diff --git a/CHANGELOG.md b/CHANGELOG.md index d21298bab8..ebe9ac6470 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,25 @@ #### Upcoming Changes +* refactor(BREAKING): Use `BuiltinName` enum instead of string representation [#1722](https://github.com/lambdaclass/cairo-vm/pull/1722) + * `BuiltinName` moved from `crate::serde::deserialize_program` module to `crate::types::builtin_name`. + * Implement `BuiltinName` methods `to_str`, `to_str_with_suffix`, `from_str` & `from_str_with_suffix`. + * Remove `BuiltinName` method `name`. + * All builtin-related error variants now store `BuiltinName` instead of `&'static str` or `String`. + * Remove constants: `OUTPUT_BUILTIN_NAME`, `HASH_BUILTIN_NAME`, `RANGE_CHECK_BUILTIN_NAME`,`RANGE_CHECK_96_BUILTIN_NAME`, `SIGNATURE_BUILTIN_NAME`, `BITWISE_BUILTIN_NAME`, `EC_OP_BUILTIN_NAME`, `KECCAK_BUILTIN_NAME`, `POSEIDON_BUILTIN_NAME`, `SEGMENT_ARENA_BUILTIN_NAME`, `ADD_MOD_BUILTIN_NAME` & +`MUL_MOD_BUILTIN_NAME`. + * Remove `BuiltinRunner` & `ModBuiltinRunner` method `identifier` + * Structs containing string representation of builtin names now use `BuiltinName` instead: + * `AirPrivateInput(pub HashMap<&'static str, Vec>)` -> `AirPrivateInput(pub HashMap>)`. + * `CairoPieMetadata` field `additional_data`: `HashMap,` -> `CairoPieAdditionalData` with `CairoPieAdditionalData(pub HashMap)` + * `CairoPieMetadata` field `builtin_segments`: `HashMap` -> `HashMap`. + * `ExecutiobResources` field `builtin_instance_counter`: `HashMap` -> `HashMap` + * Methods returning string representation of builtin names now use `BuiltinName` instead: + * `BuiltinRunner`, `ModBuiltinRunner` & `RangeCheckBuiltinRunner` method `name`: `&'static str` -> `BuiltinName`. + * `CairoRunner` method `get_builtin_segment_info_for_pie`: `Result, RunnerError>` -> `Result, RunnerError>` + + Notes: Serialization of vm outputs that now contain `BuiltinName` & `Display` implementation of `BuiltinName` have not been affected by this PR + * feat: Add `recursive_with_poseidon` layout[#1724](https://github.com/lambdaclass/cairo-vm/pull/1724) * refactor(BREAKING): Use an enum to represent layout name[#1715](https://github.com/lambdaclass/cairo-vm/pull/1715) diff --git a/cairo1-run/src/cairo_run.rs b/cairo1-run/src/cairo_run.rs index 09a9034eda..3cbb4076b4 100644 --- a/cairo1-run/src/cairo_run.rs +++ b/cairo1-run/src/cairo_run.rs @@ -29,19 +29,14 @@ use cairo_lang_utils::{casts::IntoOrPanic, unordered_hash_map::UnorderedHashMap} use cairo_vm::{ hint_processor::cairo_1_hint_processor::hint_processor::Cairo1HintProcessor, math_utils::signed_felt, - serde::deserialize_program::{ - ApTracking, BuiltinName, FlowTrackingData, HintParams, ReferenceManager, + serde::deserialize_program::{ApTracking, FlowTrackingData, HintParams, ReferenceManager}, + types::{ + builtin_name::BuiltinName, layout_name::LayoutName, program::Program, + relocatable::MaybeRelocatable, }, - types::{layout_name::LayoutName, program::Program, relocatable::MaybeRelocatable}, vm::{ errors::{runner_errors::RunnerError, vm_errors::VirtualMachineError}, - 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, - }, - cairo_runner::{CairoRunner, RunResources, RunnerMode}, - }, + runners::cairo_runner::{CairoRunner, RunResources, RunnerMode}, vm_core::VirtualMachine, }, Felt252, @@ -236,10 +231,7 @@ pub fn cairo_run_program( .iter() .enumerate() .map(|(i, builtin)| { - ( - builtin.name(), - (vm.get_ap() - (builtins.len() - 1 - i)).unwrap(), - ) + (*builtin, (vm.get_ap() - (builtins.len() - 1 - i)).unwrap()) }) .collect(), false, @@ -723,14 +715,14 @@ fn finalize_builtins( 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 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, + let builtin_name = match name.as_str() { + "RangeCheck" => BuiltinName::range_check, + "Poseidon" => BuiltinName::poseidon, + "EcOp" => BuiltinName::ec_op, + "Bitwise" => BuiltinName::bitwise, + "Pedersen" => BuiltinName::pedersen, + "Output" => BuiltinName::output, + "Ecdsa" => BuiltinName::ecdsa, _ => { stack_pointer.offset += size as usize; continue; diff --git a/vm/src/air_private_input.rs b/vm/src/air_private_input.rs index 1dbb96bb8f..be3bceedab 100644 --- a/vm/src/air_private_input.rs +++ b/vm/src/air_private_input.rs @@ -3,11 +3,7 @@ use crate::{ collections::{BTreeMap, HashMap}, prelude::{String, Vec}, }, - vm::runners::builtin_runner::{ - ADD_MOD_BUILTIN_NAME, BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, - KECCAK_BUILTIN_NAME, MUL_MOD_BUILTIN_NAME, POSEIDON_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, - SIGNATURE_BUILTIN_NAME, - }, + types::builtin_name::BuiltinName, }; use serde::{Deserialize, Serialize}; @@ -40,7 +36,7 @@ pub struct AirPrivateInputSerializable { // Contains only builtin public inputs, useful for library users #[derive(Clone, Debug, PartialEq, Eq)] -pub struct AirPrivateInput(pub HashMap<&'static str, Vec>); +pub struct AirPrivateInput(pub HashMap>); #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[serde(untagged)] @@ -159,21 +155,21 @@ impl AirPrivateInput { AirPrivateInputSerializable { trace_path, memory_path, - pedersen: self.0.get(HASH_BUILTIN_NAME).cloned(), - range_check: self.0.get(RANGE_CHECK_BUILTIN_NAME).cloned(), - ecdsa: self.0.get(SIGNATURE_BUILTIN_NAME).cloned(), - bitwise: self.0.get(BITWISE_BUILTIN_NAME).cloned(), - ec_op: self.0.get(EC_OP_BUILTIN_NAME).cloned(), - keccak: self.0.get(KECCAK_BUILTIN_NAME).cloned(), - poseidon: self.0.get(POSEIDON_BUILTIN_NAME).cloned(), + pedersen: self.0.get(&BuiltinName::pedersen).cloned(), + range_check: self.0.get(&BuiltinName::range_check).cloned(), + ecdsa: self.0.get(&BuiltinName::ecdsa).cloned(), + bitwise: self.0.get(&BuiltinName::bitwise).cloned(), + ec_op: self.0.get(&BuiltinName::ec_op).cloned(), + keccak: self.0.get(&BuiltinName::keccak).cloned(), + poseidon: self.0.get(&BuiltinName::poseidon).cloned(), add_mod: self .0 - .get(ADD_MOD_BUILTIN_NAME) + .get(&BuiltinName::add_mod) .and_then(|pi| pi.first()) .cloned(), mul_mod: self .0 - .get(MUL_MOD_BUILTIN_NAME) + .get(&BuiltinName::mul_mod) .and_then(|pi| pi.first()) .cloned(), } @@ -188,13 +184,13 @@ impl From for AirPrivateInput { inputs.insert(input_name, input); } }; - insert_input(HASH_BUILTIN_NAME, private_input.pedersen); - insert_input(RANGE_CHECK_BUILTIN_NAME, private_input.range_check); - insert_input(SIGNATURE_BUILTIN_NAME, private_input.ecdsa); - insert_input(BITWISE_BUILTIN_NAME, private_input.bitwise); - insert_input(EC_OP_BUILTIN_NAME, private_input.ec_op); - insert_input(KECCAK_BUILTIN_NAME, private_input.keccak); - insert_input(POSEIDON_BUILTIN_NAME, private_input.poseidon); + insert_input(BuiltinName::pedersen, private_input.pedersen); + insert_input(BuiltinName::range_check, private_input.range_check); + insert_input(BuiltinName::ecdsa, private_input.ecdsa); + insert_input(BuiltinName::bitwise, private_input.bitwise); + insert_input(BuiltinName::ec_op, private_input.ec_op); + insert_input(BuiltinName::keccak, private_input.keccak); + insert_input(BuiltinName::poseidon, private_input.poseidon); Self(inputs) } @@ -213,10 +209,6 @@ mod tests { use { super::*, crate::air_private_input::{AirPrivateInput, AirPrivateInputSerializable}, - crate::vm::runners::builtin_runner::{ - BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, KECCAK_BUILTIN_NAME, - POSEIDON_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME, - }, assert_matches::assert_matches, }; @@ -285,13 +277,13 @@ mod tests { let private_input = AirPrivateInput::from(serializable_private_input.clone()); - assert_matches!(private_input.0.get(HASH_BUILTIN_NAME), data if data == serializable_private_input.pedersen.as_ref()); - assert_matches!(private_input.0.get(RANGE_CHECK_BUILTIN_NAME), data if data == serializable_private_input.range_check.as_ref()); - assert_matches!(private_input.0.get(SIGNATURE_BUILTIN_NAME), data if data == serializable_private_input.ecdsa.as_ref()); - assert_matches!(private_input.0.get(BITWISE_BUILTIN_NAME), data if data == serializable_private_input.bitwise.as_ref()); - assert_matches!(private_input.0.get(EC_OP_BUILTIN_NAME), data if data == serializable_private_input.ec_op.as_ref()); - assert_matches!(private_input.0.get(KECCAK_BUILTIN_NAME), data if data == serializable_private_input.keccak.as_ref()); - assert_matches!(private_input.0.get(POSEIDON_BUILTIN_NAME), data if data == serializable_private_input.poseidon.as_ref()); + assert_matches!(private_input.0.get(&BuiltinName::pedersen), data if data == serializable_private_input.pedersen.as_ref()); + assert_matches!(private_input.0.get(&BuiltinName::range_check), data if data == serializable_private_input.range_check.as_ref()); + assert_matches!(private_input.0.get(&BuiltinName::ecdsa), data if data == serializable_private_input.ecdsa.as_ref()); + assert_matches!(private_input.0.get(&BuiltinName::bitwise), data if data == serializable_private_input.bitwise.as_ref()); + assert_matches!(private_input.0.get(&BuiltinName::ec_op), data if data == serializable_private_input.ec_op.as_ref()); + assert_matches!(private_input.0.get(&BuiltinName::keccak), data if data == serializable_private_input.keccak.as_ref()); + assert_matches!(private_input.0.get(&BuiltinName::poseidon), data if data == serializable_private_input.poseidon.as_ref()); } #[test] diff --git a/vm/src/program_hash.rs b/vm/src/program_hash.rs index 3ff1fa798c..48ed006e91 100644 --- a/vm/src/program_hash.rs +++ b/vm/src/program_hash.rs @@ -2,8 +2,8 @@ use starknet_crypto::{pedersen_hash, FieldElement}; use crate::Felt252; -use crate::serde::deserialize_program::BuiltinName; use crate::stdlib::vec::Vec; +use crate::types::builtin_name::BuiltinName; use crate::types::relocatable::MaybeRelocatable; use crate::vm::runners::cairo_pie::StrippedProgram; @@ -58,15 +58,12 @@ where /// /// Converts the builtin name to bytes then attempts to create a field element from /// these bytes. This function will fail if the builtin name is over 31 characters. -fn builtin_to_field_element(builtin: &BuiltinName) -> Result { +fn builtin_name_to_field_element( + builtin_name: &BuiltinName, +) -> Result { // The Python implementation uses the builtin name without suffix - let builtin_name = builtin - .name() - .strip_suffix("_builtin") - .unwrap_or(builtin.name()); - - FieldElement::from_byte_slice_be(builtin_name.as_bytes()) - .map_err(|_| ProgramHashError::InvalidProgramBuiltin(builtin.name())) + FieldElement::from_byte_slice_be(builtin_name.to_str().as_bytes()) + .map_err(|_| ProgramHashError::InvalidProgramBuiltin(builtin_name.to_str())) } /// The `value: FieldElement` is `pub(crate)` and there is no accessor. @@ -111,7 +108,7 @@ pub fn compute_program_hash_chain( let builtin_list: Result, _> = program .builtins .iter() - .map(builtin_to_field_element) + .map(builtin_name_to_field_element) .collect(); let builtin_list = builtin_list?; diff --git a/vm/src/serde/deserialize_program.rs b/vm/src/serde/deserialize_program.rs index 401a9b7b6b..6eea8b84c5 100644 --- a/vm/src/serde/deserialize_program.rs +++ b/vm/src/serde/deserialize_program.rs @@ -1,7 +1,7 @@ //! # Program deserialization //! //! This module contains the logic for [`Program`] deserialization. -//! Users shouldn't need to use it directly (except for [`BuiltinName`]). +//! Users shouldn't need to use it directly //! //! To generate a [`Program`] from a JSON string, see [`Program::from_bytes()`]. //! To do the same from a JSON file, see [`Program::from_file()`]. @@ -13,13 +13,11 @@ use crate::{ prelude::*, sync::Arc, }, + types::builtin_name::BuiltinName, utils::CAIRO_PRIME, - vm::runners::builtin_runner::RANGE_CHECK_96_BUILTIN_NAME, }; use crate::utils::PRIME_STR; -use crate::vm::runners::builtin_runner::SEGMENT_ARENA_BUILTIN_NAME; -use crate::vm::runners::builtin_runner::{ADD_MOD_BUILTIN_NAME, MUL_MOD_BUILTIN_NAME}; use crate::Felt252; use crate::{ serde::deserialize_utils, @@ -29,11 +27,6 @@ use crate::{ program::{HintsCollection, Program, SharedProgramData}, relocatable::MaybeRelocatable, }, - vm::runners::builtin_runner::{ - BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, KECCAK_BUILTIN_NAME, - OUTPUT_BUILTIN_NAME, POSEIDON_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, - SIGNATURE_BUILTIN_NAME, - }, }; use num_bigint::BigUint; use num_traits::{float::FloatCore, Num}; @@ -43,44 +36,6 @@ use serde_json::Number; #[cfg(all(feature = "arbitrary", feature = "std"))] use arbitrary::{self, Arbitrary, Unstructured}; -// This enum is used to deserialize program builtins into &str and catch non-valid names -#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))] -#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone, Eq, Hash)] -#[allow(non_camel_case_types)] -pub enum BuiltinName { - output, - range_check, - pedersen, - ecdsa, - keccak, - bitwise, - ec_op, - poseidon, - segment_arena, - range_check96, - add_mod, - mul_mod, -} - -impl BuiltinName { - pub fn name(&self) -> &'static str { - match self { - BuiltinName::output => OUTPUT_BUILTIN_NAME, - BuiltinName::range_check => RANGE_CHECK_BUILTIN_NAME, - BuiltinName::pedersen => HASH_BUILTIN_NAME, - BuiltinName::ecdsa => SIGNATURE_BUILTIN_NAME, - BuiltinName::keccak => KECCAK_BUILTIN_NAME, - BuiltinName::bitwise => BITWISE_BUILTIN_NAME, - BuiltinName::ec_op => EC_OP_BUILTIN_NAME, - BuiltinName::poseidon => POSEIDON_BUILTIN_NAME, - BuiltinName::segment_arena => SEGMENT_ARENA_BUILTIN_NAME, - BuiltinName::range_check96 => RANGE_CHECK_96_BUILTIN_NAME, - BuiltinName::add_mod => ADD_MOD_BUILTIN_NAME, - BuiltinName::mul_mod => MUL_MOD_BUILTIN_NAME, - } - } -} - #[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary, Clone))] #[derive(Deserialize, Debug)] pub struct ProgramJson { diff --git a/vm/src/serde/serialize_program.rs b/vm/src/serde/serialize_program.rs index 922769732a..f8bd0d076a 100644 --- a/vm/src/serde/serialize_program.rs +++ b/vm/src/serde/serialize_program.rs @@ -1,13 +1,16 @@ -use crate::stdlib::{ - collections::{BTreeMap, HashMap}, - prelude::*, +use crate::{ + stdlib::{ + collections::{BTreeMap, HashMap}, + prelude::*, + }, + types::builtin_name::BuiltinName, }; use serde::{Deserialize, Serialize}; use super::deserialize_program::{ - ApTracking, Attribute, BuiltinName, DebugInfo, FlowTrackingData, HintParams, Identifier, - Member, ProgramJson, Reference, ReferenceManager, ValueAddress, + ApTracking, Attribute, DebugInfo, FlowTrackingData, HintParams, Identifier, Member, + ProgramJson, Reference, ReferenceManager, ValueAddress, }; use crate::types::program::Program; use crate::types::relocatable::MaybeRelocatable; diff --git a/vm/src/tests/cairo_pie_test.rs b/vm/src/tests/cairo_pie_test.rs index ad791af277..487cbb8341 100644 --- a/vm/src/tests/cairo_pie_test.rs +++ b/vm/src/tests/cairo_pie_test.rs @@ -1,4 +1,7 @@ -use crate::{felt_str, types::layout_name::LayoutName}; +use crate::{ + felt_str, + types::{builtin_name::BuiltinName, layout_name::LayoutName}, +}; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::*; @@ -12,13 +15,9 @@ use alloc::{ use crate::{ cairo_run::{cairo_run, CairoRunConfig}, hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor, - stdlib::{collections::HashMap, prelude::*}, + stdlib::collections::HashMap, types::relocatable::Relocatable, vm::runners::{ - builtin_runner::{ - HASH_BUILTIN_NAME, OUTPUT_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, - SIGNATURE_BUILTIN_NAME, - }, cairo_pie::{ BuiltinAdditionalData, CairoPieMemory, OutputBuiltinAdditionalData, SegmentInfo, }, @@ -59,9 +58,9 @@ fn pedersen_test() { assert_eq!(pie_metadata.ret_pc_segment, SegmentInfo::from((6, 0))); // builtin_segments let expected_builtin_segments = HashMap::from([ - (String::from("output"), SegmentInfo::from((2, 1))), - (String::from("pedersen"), SegmentInfo::from((3, 3))), - (String::from("range_check"), SegmentInfo::from((4, 0))), + (BuiltinName::output, SegmentInfo::from((2, 1))), + (BuiltinName::pedersen, SegmentInfo::from((3, 3))), + (BuiltinName::range_check, SegmentInfo::from((4, 0))), ]); assert_eq!(pie_metadata.builtin_segments, expected_builtin_segments); // program_segment @@ -85,31 +84,28 @@ fn pedersen_test() { n_steps: 14, n_memory_holes: 0, builtin_instance_counter: HashMap::from([ - (RANGE_CHECK_BUILTIN_NAME.to_string(), 0), - (OUTPUT_BUILTIN_NAME.to_string(), 1), - (HASH_BUILTIN_NAME.to_string(), 1), + (BuiltinName::range_check, 0), + (BuiltinName::output, 1), + (BuiltinName::pedersen, 1), ]), }; assert_eq!(cairo_pie.execution_resources, expected_execution_resources); // additional_data let expected_additional_data = HashMap::from([ ( - OUTPUT_BUILTIN_NAME.to_string(), + BuiltinName::output, BuiltinAdditionalData::Output(OutputBuiltinAdditionalData { pages: HashMap::new(), attributes: HashMap::new(), }), ), ( - HASH_BUILTIN_NAME.to_string(), + BuiltinName::pedersen, BuiltinAdditionalData::Hash(vec![Relocatable::from((3, 2))]), ), - ( - RANGE_CHECK_BUILTIN_NAME.to_string(), - BuiltinAdditionalData::None, - ), + (BuiltinName::range_check, BuiltinAdditionalData::None), ]); - assert_eq!(cairo_pie.additional_data, expected_additional_data); + assert_eq!(cairo_pie.additional_data.0, expected_additional_data); // memory assert_eq!( cairo_pie.memory, @@ -144,7 +140,7 @@ fn common_signature() { assert_eq!(pie_metadata.ret_pc_segment, SegmentInfo::from((4, 0))); // builtin_segments let expected_builtin_segments = - HashMap::from([(String::from("ecdsa"), SegmentInfo::from((2, 2)))]); + HashMap::from([(BuiltinName::ecdsa, SegmentInfo::from((2, 2)))]); assert_eq!(pie_metadata.builtin_segments, expected_builtin_segments); // program_segment assert_eq!(pie_metadata.program_segment, SegmentInfo::from((0, 21))); @@ -166,12 +162,12 @@ fn common_signature() { let expected_execution_resources = ExecutionResources { n_steps: 11, n_memory_holes: 0, - builtin_instance_counter: HashMap::from([(SIGNATURE_BUILTIN_NAME.to_string(), 1)]), + builtin_instance_counter: HashMap::from([(BuiltinName::ecdsa, 1)]), }; assert_eq!(cairo_pie.execution_resources, expected_execution_resources); // additional_data let expected_additional_data = HashMap::from([( - SIGNATURE_BUILTIN_NAME.to_string(), + BuiltinName::ecdsa, BuiltinAdditionalData::Signature(HashMap::from([( Relocatable::from((2, 0)), ( @@ -184,7 +180,7 @@ fn common_signature() { ), )])), )]); - assert_eq!(cairo_pie.additional_data, expected_additional_data); + assert_eq!(cairo_pie.additional_data.0, expected_additional_data); // memory assert_eq!( cairo_pie.memory, @@ -243,7 +239,7 @@ fn relocate_segments() { }; assert_eq!(cairo_pie.execution_resources, expected_execution_resources); // additional_data - assert!(cairo_pie.additional_data.is_empty()); + assert!(cairo_pie.additional_data.0.is_empty()); // memory assert_eq!( cairo_pie.memory, diff --git a/vm/src/tests/mod.rs b/vm/src/tests/mod.rs index 3a3d5b2e05..b2d95c3df6 100644 --- a/vm/src/tests/mod.rs +++ b/vm/src/tests/mod.rs @@ -9,8 +9,7 @@ use crate::Felt252; #[cfg(feature = "cairo-1-hints")] use crate::{ hint_processor::cairo_1_hint_processor::hint_processor::Cairo1HintProcessor, - serde::deserialize_program::BuiltinName, - types::relocatable::MaybeRelocatable, + types::{builtin_name::BuiltinName, relocatable::MaybeRelocatable}, vm::{ runners::cairo_runner::{CairoArg, CairoRunner}, vm_core::VirtualMachine, @@ -130,11 +129,7 @@ fn run_cairo_1_entrypoint( // Implicit Args let syscall_segment = MaybeRelocatable::from(vm.add_memory_segment()); - let builtins: Vec<&'static str> = runner - .get_program_builtins() - .iter() - .map(|b| b.name()) - .collect(); + let builtins = runner.get_program_builtins(); let builtin_segment: Vec = vm .get_builtin_runners() @@ -232,11 +227,7 @@ fn run_cairo_1_entrypoint_with_run_resources( // Implicit Args let syscall_segment = MaybeRelocatable::from(vm.add_memory_segment()); - let builtins: Vec<&'static str> = runner - .get_program_builtins() - .iter() - .map(|b| b.name()) - .collect(); + let builtins = runner.get_program_builtins(); let builtin_segment: Vec = vm .get_builtin_runners() @@ -320,22 +311,6 @@ fn get_casm_contract_builtins( .unwrap() .builtins .iter() - .map(|n| format!("{}_builtin", n)) - .map(|s| match &*s { - crate::vm::runners::builtin_runner::OUTPUT_BUILTIN_NAME => BuiltinName::output, - crate::vm::runners::builtin_runner::RANGE_CHECK_BUILTIN_NAME => { - BuiltinName::range_check - } - crate::vm::runners::builtin_runner::HASH_BUILTIN_NAME => BuiltinName::pedersen, - crate::vm::runners::builtin_runner::SIGNATURE_BUILTIN_NAME => BuiltinName::ecdsa, - crate::vm::runners::builtin_runner::KECCAK_BUILTIN_NAME => BuiltinName::keccak, - crate::vm::runners::builtin_runner::BITWISE_BUILTIN_NAME => BuiltinName::bitwise, - crate::vm::runners::builtin_runner::EC_OP_BUILTIN_NAME => BuiltinName::ec_op, - crate::vm::runners::builtin_runner::POSEIDON_BUILTIN_NAME => BuiltinName::poseidon, - crate::vm::runners::builtin_runner::SEGMENT_ARENA_BUILTIN_NAME => { - BuiltinName::segment_arena - } - _ => panic!("Invalid builtin {}", s), - }) + .map(|s| BuiltinName::from_str(s).expect("Invalid builtin name")) .collect() } diff --git a/vm/src/types/builtin_name.rs b/vm/src/types/builtin_name.rs new file mode 100644 index 0000000000..e904a1f335 --- /dev/null +++ b/vm/src/types/builtin_name.rs @@ -0,0 +1,211 @@ +use serde::{Deserialize, Serialize}; + +#[cfg(all(feature = "arbitrary", feature = "std"))] +use arbitrary::{self, Arbitrary}; + +// Internal constants +const OUTPUT_BUILTIN_NAME: &str = "output"; +const HASH_BUILTIN_NAME: &str = "pedersen"; +const RANGE_CHECK_BUILTIN_NAME: &str = "range_check"; +const RANGE_CHECK_96_BUILTIN_NAME: &str = "range_check_96"; +const SIGNATURE_BUILTIN_NAME: &str = "ecdsa"; +const BITWISE_BUILTIN_NAME: &str = "bitwise"; +const EC_OP_BUILTIN_NAME: &str = "ec_op"; +const KECCAK_BUILTIN_NAME: &str = "keccak"; +const POSEIDON_BUILTIN_NAME: &str = "poseidon"; +const SEGMENT_ARENA_BUILTIN_NAME: &str = "segment_arena"; +const ADD_MOD_BUILTIN_NAME: &str = "add_mod"; +const MUL_MOD_BUILTIN_NAME: &str = "mul_mod"; + +const OUTPUT_BUILTIN_NAME_WITH_SUFFIX: &str = "output_builtin"; +const HASH_BUILTIN_NAME_WITH_SUFFIX: &str = "pedersen_builtin"; +const RANGE_CHECK_BUILTIN_NAME_WITH_SUFFIX: &str = "range_check_builtin"; +const RANGE_CHECK_96_BUILTIN_NAME_WITH_SUFFIX: &str = "range_check_96_builtin"; +const SIGNATURE_BUILTIN_NAME_WITH_SUFFIX: &str = "ecdsa_builtin"; +const BITWISE_BUILTIN_NAME_WITH_SUFFIX: &str = "bitwise_builtin"; +const EC_OP_BUILTIN_NAME_WITH_SUFFIX: &str = "ec_op_builtin"; +const KECCAK_BUILTIN_NAME_WITH_SUFFIX: &str = "keccak_builtin"; +const POSEIDON_BUILTIN_NAME_WITH_SUFFIX: &str = "poseidon_builtin"; +const SEGMENT_ARENA_BUILTIN_NAME_WITH_SUFFIX: &str = "segment_arena_builtin"; +const ADD_MOD_BUILTIN_NAME_WITH_SUFFIX: &str = "add_mod_builtin"; +const MUL_MOD_BUILTIN_NAME_WITH_SUFFIX: &str = "mul_mod_builtin"; + +/// Enum representing the name of a cairo builtin +#[cfg_attr(all(feature = "arbitrary", feature = "std"), derive(Arbitrary))] +#[derive(Serialize, Deserialize, Debug, PartialEq, Copy, Clone, Eq, Hash)] +#[allow(non_camel_case_types)] +pub enum BuiltinName { + output, + range_check, + pedersen, + ecdsa, + keccak, + bitwise, + ec_op, + poseidon, + segment_arena, + range_check96, + add_mod, + mul_mod, +} + +impl BuiltinName { + /// Converts a [`BuiltinName`] to its string representation adding the "_builtin" suffix + /// + /// ## Example + /// + /// ``` + /// # use cairo_vm::types::builtin_name::BuiltinName; + /// + /// let builtin_name = BuiltinName::poseidon; + /// assert_eq!(builtin_name.to_str_with_suffix(), "poseidon_builtin"); + /// + /// ``` + pub fn to_str_with_suffix(self) -> &'static str { + match self { + BuiltinName::output => OUTPUT_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::range_check => RANGE_CHECK_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::pedersen => HASH_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::ecdsa => SIGNATURE_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::keccak => KECCAK_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::bitwise => BITWISE_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::ec_op => EC_OP_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::poseidon => POSEIDON_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::segment_arena => SEGMENT_ARENA_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::range_check96 => RANGE_CHECK_96_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::add_mod => ADD_MOD_BUILTIN_NAME_WITH_SUFFIX, + BuiltinName::mul_mod => MUL_MOD_BUILTIN_NAME_WITH_SUFFIX, + } + } + + /// Converts a [`BuiltinName`] to its string representation + /// + /// ## Example + /// + /// ``` + /// # use cairo_vm::types::builtin_name::BuiltinName; + /// + /// let builtin_name = BuiltinName::poseidon; + /// assert_eq!(builtin_name.to_str(), "poseidon"); + /// + /// ``` + pub fn to_str(self) -> &'static str { + match self { + BuiltinName::output => OUTPUT_BUILTIN_NAME, + BuiltinName::range_check => RANGE_CHECK_BUILTIN_NAME, + BuiltinName::pedersen => HASH_BUILTIN_NAME, + BuiltinName::ecdsa => SIGNATURE_BUILTIN_NAME, + BuiltinName::keccak => KECCAK_BUILTIN_NAME, + BuiltinName::bitwise => BITWISE_BUILTIN_NAME, + BuiltinName::ec_op => EC_OP_BUILTIN_NAME, + BuiltinName::poseidon => POSEIDON_BUILTIN_NAME, + BuiltinName::segment_arena => SEGMENT_ARENA_BUILTIN_NAME, + BuiltinName::range_check96 => RANGE_CHECK_96_BUILTIN_NAME, + BuiltinName::add_mod => ADD_MOD_BUILTIN_NAME, + BuiltinName::mul_mod => MUL_MOD_BUILTIN_NAME, + } + } + + /// Converts a [`BuiltinName`] from its string representation removing the "_builtin" suffix + /// + /// ## Example + /// + /// ``` + /// # use cairo_vm::types::builtin_name::BuiltinName; + /// + /// assert_eq!(BuiltinName::from_str_with_suffix("poseidon_builtin"), Some(BuiltinName::poseidon)); + /// + /// assert_eq!(BuiltinName::from_str_with_suffix("unknown"), None); + /// + /// ``` + pub fn from_str_with_suffix(suffixed_str: &str) -> Option { + match suffixed_str { + OUTPUT_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::output), + RANGE_CHECK_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::range_check), + HASH_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::pedersen), + SIGNATURE_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::ecdsa), + KECCAK_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::keccak), + BITWISE_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::bitwise), + EC_OP_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::ec_op), + POSEIDON_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::poseidon), + SEGMENT_ARENA_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::segment_arena), + RANGE_CHECK_96_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::range_check96), + ADD_MOD_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::add_mod), + MUL_MOD_BUILTIN_NAME_WITH_SUFFIX => Some(BuiltinName::mul_mod), + _ => None, + } + } + + // Implementing this as a trait would generate confusion as `Display` impl uses suffixed version + #[allow(clippy::should_implement_trait)] + /// Converts a [`BuiltinName`] from its string representation + /// + /// ## Example + /// + /// ``` + /// # use cairo_vm::types::builtin_name::BuiltinName; + /// + /// assert_eq!(BuiltinName::from_str("poseidon"), Some(BuiltinName::poseidon)); + /// + /// assert_eq!(BuiltinName::from_str("unknown"), None); + /// + /// ``` + pub fn from_str(str: &str) -> Option { + match str { + OUTPUT_BUILTIN_NAME => Some(BuiltinName::output), + RANGE_CHECK_BUILTIN_NAME => Some(BuiltinName::range_check), + HASH_BUILTIN_NAME => Some(BuiltinName::pedersen), + SIGNATURE_BUILTIN_NAME => Some(BuiltinName::ecdsa), + KECCAK_BUILTIN_NAME => Some(BuiltinName::keccak), + BITWISE_BUILTIN_NAME => Some(BuiltinName::bitwise), + EC_OP_BUILTIN_NAME => Some(BuiltinName::ec_op), + POSEIDON_BUILTIN_NAME => Some(BuiltinName::poseidon), + SEGMENT_ARENA_BUILTIN_NAME => Some(BuiltinName::segment_arena), + RANGE_CHECK_96_BUILTIN_NAME => Some(BuiltinName::range_check96), + ADD_MOD_BUILTIN_NAME => Some(BuiltinName::add_mod), + MUL_MOD_BUILTIN_NAME => Some(BuiltinName::mul_mod), + _ => None, + } + } +} + +/// NOTE: Adds "_builtin" suffix +impl core::fmt::Display for BuiltinName { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + self.to_str_with_suffix().fmt(f) + } +} + +// Implementation of custom serialization & deserialization for maps using builtin names with suffixes as keys +pub(crate) mod serde_generic_map_impl { + use super::BuiltinName; + use crate::stdlib::{collections::HashMap, string::String}; + use serde::{de::Error, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; + + pub fn serialize( + values: &HashMap, + serializer: S, + ) -> Result + where + S: Serializer, + V: Serialize, + { + let mut map_serializer = serializer.serialize_map(Some(values.len()))?; + for (key, val) in values { + map_serializer.serialize_entry(key.to_str_with_suffix(), val)? + } + map_serializer.end() + } + + pub fn deserialize<'de, D: Deserializer<'de>, V: Deserialize<'de>>( + d: D, + ) -> Result, D::Error> { + // First deserialize keys into String + let map = HashMap::::deserialize(d)?; + // Then match keys to BuiltinName and handle invalid names + map.into_iter() + .map(|(k, v)| BuiltinName::from_str_with_suffix(&k).map(|k| (k, v))) + .collect::>>() + .ok_or(D::Error::custom("Invalid builtin name")) + } +} diff --git a/vm/src/types/mod.rs b/vm/src/types/mod.rs index c40e417c22..b52ca522bb 100644 --- a/vm/src/types/mod.rs +++ b/vm/src/types/mod.rs @@ -1,3 +1,4 @@ +pub mod builtin_name; pub mod errors; pub mod exec_scope; pub mod instance_definitions; diff --git a/vm/src/types/program.rs b/vm/src/types/program.rs index a56558395b..956847cd5c 100644 --- a/vm/src/types/program.rs +++ b/vm/src/types/program.rs @@ -18,8 +18,8 @@ use crate::Felt252; use crate::{ hint_processor::hint_processor_definition::HintReference, serde::deserialize_program::{ - deserialize_and_parse_program, Attribute, BuiltinName, HintParams, Identifier, - InstructionLocation, OffsetValue, ReferenceManager, + deserialize_and_parse_program, Attribute, HintParams, Identifier, InstructionLocation, + OffsetValue, ReferenceManager, }, types::{ errors::program_errors::ProgramError, instruction::Register, relocatable::MaybeRelocatable, @@ -32,6 +32,7 @@ use core::num::NonZeroUsize; #[cfg(feature = "std")] use std::path::Path; +use super::builtin_name::BuiltinName; #[cfg(feature = "extensive_hints")] use super::relocatable::Relocatable; #[cfg(all(feature = "arbitrary", feature = "std"))] diff --git a/vm/src/utils.rs b/vm/src/utils.rs index 2aae236af3..78b7148955 100644 --- a/vm/src/utils.rs +++ b/vm/src/utils.rs @@ -337,7 +337,7 @@ pub mod test_utils { >, pub(crate) constants: crate::stdlib::collections::HashMap, - pub(crate) builtins: crate::utils::Vec, + pub(crate) builtins: crate::utils::Vec, pub(crate) reference_manager: crate::serde::deserialize_program::ReferenceManager, } @@ -626,6 +626,7 @@ pub mod test_utils { mod test { use crate::hint_processor::hint_processor_definition::HintProcessorLogic; use crate::stdlib::{cell::RefCell, collections::HashMap, rc::Rc, string::String, vec::Vec}; + use crate::types::builtin_name::BuiltinName; use crate::types::program::HintsCollection; use crate::{ hint_processor::{ @@ -635,7 +636,7 @@ mod test { }, hint_processor_definition::HintReference, }, - serde::deserialize_program::{BuiltinName, ReferenceManager}, + serde::deserialize_program::ReferenceManager, types::{exec_scope::ExecutionScopes, program::Program, relocatable::MaybeRelocatable}, utils::test_utils::*, vm::{trace::trace_entry::TraceEntry, vm_core::VirtualMachine, vm_memory::memory::Memory}, diff --git a/vm/src/vm/errors/memory_errors.rs b/vm/src/vm/errors/memory_errors.rs index 6f28ef1d37..b6f02b0a85 100644 --- a/vm/src/vm/errors/memory_errors.rs +++ b/vm/src/vm/errors/memory_errors.rs @@ -2,6 +2,7 @@ #![allow(clippy::explicit_auto_deref)] use crate::stdlib::prelude::*; +use crate::types::builtin_name::BuiltinName; use thiserror_no_std::Error; @@ -48,10 +49,10 @@ pub enum MemoryError { GetRangeMemoryGap(Box<(Relocatable, usize)>), #[error("Error calculating builtin memory units")] ErrorCalculatingMemoryUnits, - #[error("Missing memory cells for builtin {0}")] - MissingMemoryCells(Box<&'static str>), - #[error("Missing memory cells for builtin {}: {:?}", (*.0).0, (*.0).1)] - MissingMemoryCellsWithOffsets(Box<(&'static str, Vec)>), + #[error("Missing memory cells for {0}")] + MissingMemoryCells(Box), + #[error("Missing memory cells for {}: {:?}", (*.0).0, (*.0).1)] + MissingMemoryCellsWithOffsets(Box<(BuiltinName, Vec)>), #[error("ErrorInitializing Verifying Key from public key: {0:?}")] InitializingVerifyingKey(Box>), #[error( @@ -104,10 +105,10 @@ pub enum MemoryError { #[derive(Debug, PartialEq, Eq, Error)] pub enum InsufficientAllocatedCellsError { - #[error("Number of steps must be at least {} for the {} builtin.", (*.0).0, (*.0).1)] - MinStepNotReached(Box<(usize, &'static str)>), - #[error("The {} builtin used {} cells but the capacity is {}.", (*.0).0, (*.0).1, (*.0).2)] - BuiltinCells(Box<(&'static str, usize, usize)>), + #[error("Number of steps must be at least {} for the {}.", (*.0).0, (*.0).1)] + MinStepNotReached(Box<(usize, BuiltinName)>), + #[error("The {} used {} cells but the capacity is {}.", (*.0).0, (*.0).1, (*.0).2)] + BuiltinCells(Box<(BuiltinName, usize, usize)>), #[error("There are only {} cells to fill the range checks holes, but potentially {} are required.", (*.0).0, (*.0).1)] RangeCheckUnits(Box<(usize, usize)>), #[error("There are only {} cells to fill the diluted check holes, but potentially {} are required.", (*.0).0, (*.0).1)] diff --git a/vm/src/vm/errors/runner_errors.rs b/vm/src/vm/errors/runner_errors.rs index 37380903bd..a1ad55bcc4 100644 --- a/vm/src/vm/errors/runner_errors.rs +++ b/vm/src/vm/errors/runner_errors.rs @@ -2,6 +2,7 @@ #![allow(clippy::explicit_auto_deref)] use crate::stdlib::{collections::HashSet, prelude::*}; +use crate::types::builtin_name::BuiltinName; use crate::types::layout_name::LayoutName; use thiserror_no_std::Error; @@ -40,7 +41,7 @@ pub enum RunnerError { #[error("EcOpBuiltin: point {0:?} is not on the curve")] PointNotOnCurve(Box<(Felt252, Felt252)>), #[error("Builtin(s) {:?} not present in layout {}", (*.0).0, (*.0).1)] - NoBuiltinForInstance(Box<(HashSet<&'static str>, LayoutName)>), + NoBuiltinForInstance(Box<(HashSet, LayoutName)>), #[error("end_run called twice.")] EndRunCalledTwice, #[error("end_run must be called before finalize_segments.")] @@ -52,11 +53,11 @@ pub enum RunnerError { #[error("finalize_segments called but proof_mode is not enabled")] FinalizeSegmentsNoProofMode, #[error("Invalid stop pointer for {}: Stop pointer has value {} but builtin segment is {}", (*.0).0, (*.0).1, (*.0).2)] - InvalidStopPointerIndex(Box<(&'static str, Relocatable, usize)>), + InvalidStopPointerIndex(Box<(BuiltinName, Relocatable, usize)>), #[error("Invalid stop pointer for {}. Expected: {}, found: {}", (*.0).0, (*.0).1, (*.0).2)] - InvalidStopPointer(Box<(&'static str, Relocatable, Relocatable)>), + InvalidStopPointer(Box<(BuiltinName, Relocatable, Relocatable)>), #[error("No stop pointer found for builtin {0}")] - NoStopPointer(Box<&'static str>), + NoStopPointer(Box), #[error("Running in proof-mode but no __start__ label found, try compiling with proof-mode")] NoProgramStart, #[error("Running in proof-mode but no __end__ label found, try compiling with proof-mode")] @@ -80,7 +81,7 @@ pub enum RunnerError { #[error("keccak_builtin: Failed to get first input address")] KeccakNoFirstInput, #[error("{}: Expected integer at address {}", (*.0).0, (*.0).1)] - BuiltinExpectedInteger(Box<(&'static str, Relocatable)>), + BuiltinExpectedInteger(Box<(BuiltinName, Relocatable)>), #[error("keccak_builtin: Failed to convert input cells to u64 values")] KeccakInputCellsNotU64, #[error("Unexpected ret_fp_segment size")] @@ -106,13 +107,13 @@ pub enum RunnerError { #[error("Expected integer at address {} to be smaller than 2^{}. Got: {}.", (*.0).0, (*.0).1, (*.0).2)] WordExceedsModBuiltinWordBitLen(Box<(Relocatable, u32, Felt252)>), #[error("{}: Expected n >= 1. Got: {}.", (*.0).0, (*.0).1)] - ModBuiltinNLessThanOne(Box<(&'static str, usize)>), + ModBuiltinNLessThanOne(Box<(BuiltinName, usize)>), #[error("{}: Missing value at address {}.", (*.0).0, (*.0).1)] - ModBuiltinMissingValue(Box<(&'static str, Relocatable)>), + ModBuiltinMissingValue(Box<(BuiltinName, Relocatable)>), #[error("{}: n must be <= {}", (*.0).0, (*.0).1)] - FillMemoryMaxExceeded(Box<(&'static str, usize)>), + FillMemoryMaxExceeded(Box<(BuiltinName, usize)>), #[error("{0}: write_n_words value must be 0 after loop")] - WriteNWordsValueNotZero(&'static str), + WriteNWordsValueNotZero(BuiltinName), #[error("add_mod and mul_mod builtins must have the same n_words and word_bit_len.")] ModBuiltinsMismatchedInstanceDef, #[error("At least one of add_mod and mul_mod must be given.")] @@ -120,11 +121,11 @@ pub enum RunnerError { #[error("Could not fill the values table, add_mod_index={0}, mul_mod_index={1}")] FillMemoryCoudNotFillTable(usize, usize), #[error("{}: {}", (*.0).0, (*.0).1)] - ModBuiltinSecurityCheck(Box<(&'static str, String)>), + ModBuiltinSecurityCheck(Box<(BuiltinName, String)>), #[error("{0} is missing")] - MissingBuiltin(&'static str), + MissingBuiltin(BuiltinName), #[error("The stop pointer of the missing builtin {0} must be 0")] - MissingBuiltinStopPtrNotZero(&'static str), + MissingBuiltinStopPtrNotZero(BuiltinName), } #[cfg(test)] diff --git a/vm/src/vm/errors/vm_errors.rs b/vm/src/vm/errors/vm_errors.rs index 68b8ceed45..c3698eda02 100644 --- a/vm/src/vm/errors/vm_errors.rs +++ b/vm/src/vm/errors/vm_errors.rs @@ -2,6 +2,7 @@ #![allow(clippy::explicit_auto_deref)] use crate::stdlib::prelude::*; +use crate::types::builtin_name::BuiltinName; use thiserror_no_std::Error; @@ -77,8 +78,8 @@ pub enum VirtualMachineError { InvalidOpcode(u64), #[error("This is not implemented")] NotImplemented, - #[error("Inconsistent auto-deduction for builtin {}, expected {}, got {:?}", (*.0).0, (*.0).1, (*.0).2)] - InconsistentAutoDeduction(Box<(&'static str, MaybeRelocatable, Option)>), + #[error("Inconsistent auto-deduction for {}, expected {}, got {:?}", (*.0).0, (*.0).1, (*.0).2)] + InconsistentAutoDeduction(Box<(BuiltinName, MaybeRelocatable, Option)>), #[error("Invalid hint encoding at pc: {0}")] InvalidHintEncoding(Box), #[error("Expected output builtin to be present")] @@ -88,7 +89,7 @@ pub enum VirtualMachineError { #[error("Expected ecdsa builtin to be present")] NoSignatureBuiltin, #[error("Expected {0} to be present")] - NoModBuiltin(&'static str), + NoModBuiltin(BuiltinName), #[error("Div out of range: 0 < {} <= {}", (*.0).0, (*.0).1)] OutOfValidRange(Box<(Felt252, Felt252)>), #[error("Failed to compare {} and {}, cant compare a relocatable to an integer value", (*.0).0, (*.0).1)] @@ -134,7 +135,7 @@ pub enum VirtualMachineError { #[error("Failed to find index {0} in the vm's relocation table")] RelocationNotFound(usize), #[error("{} batch size is not {}", (*.0).0, (*.0).1)] - ModBuiltinBatchSize(Box<(&'static str, usize)>), + ModBuiltinBatchSize(Box<(BuiltinName, usize)>), } #[cfg(test)] diff --git a/vm/src/vm/runners/builtin_runner/bitwise.rs b/vm/src/vm/runners/builtin_runner/bitwise.rs index e5901194db..a37c6e5cd2 100644 --- a/vm/src/vm/runners/builtin_runner/bitwise.rs +++ b/vm/src/vm/runners/builtin_runner/bitwise.rs @@ -168,9 +168,9 @@ impl BitwiseBuiltinRunner { mod tests { use super::*; use crate::relocatable; - use crate::serde::deserialize_program::BuiltinName; + use crate::types::builtin_name::BuiltinName; use crate::vm::errors::memory_errors::MemoryError; - use crate::vm::runners::builtin_runner::{BuiltinRunner, BITWISE_BUILTIN_NAME}; + use crate::vm::runners::builtin_runner::BuiltinRunner; use crate::vm::vm_core::VirtualMachine; use crate::Felt252; use crate::{ @@ -245,7 +245,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::InvalidStopPointer(Box::new(( - BITWISE_BUILTIN_NAME, + BuiltinName::bitwise, relocatable!(0, 995), relocatable!(0, 0) )))) @@ -296,7 +296,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), - Err(RunnerError::NoStopPointer(Box::new(BITWISE_BUILTIN_NAME))) + Err(RunnerError::NoStopPointer(Box::new(BuiltinName::bitwise))) ); } diff --git a/vm/src/vm/runners/builtin_runner/ec_op.rs b/vm/src/vm/runners/builtin_runner/ec_op.rs index a72166e7bb..05f88fad45 100644 --- a/vm/src/vm/runners/builtin_runner/ec_op.rs +++ b/vm/src/vm/runners/builtin_runner/ec_op.rs @@ -242,13 +242,12 @@ impl EcOpBuiltinRunner { mod tests { use super::*; use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; - use crate::serde::deserialize_program::BuiltinName; + use crate::types::builtin_name::BuiltinName; use crate::types::layout_name::LayoutName; use crate::types::program::Program; use crate::utils::test_utils::*; use crate::vm::errors::cairo_run_errors::CairoRunError; use crate::vm::errors::vm_errors::VirtualMachineError; - use crate::vm::runners::builtin_runner::EC_OP_BUILTIN_NAME; use crate::vm::runners::cairo_runner::CairoRunner; use crate::{felt_hex, felt_str, relocatable}; @@ -318,7 +317,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::InvalidStopPointer(Box::new(( - EC_OP_BUILTIN_NAME, + BuiltinName::ec_op, relocatable!(0, 994), relocatable!(0, 0) )))) @@ -369,7 +368,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), - Err(RunnerError::NoStopPointer(Box::new(EC_OP_BUILTIN_NAME))) + Err(RunnerError::NoStopPointer(Box::new(BuiltinName::ec_op))) ); } diff --git a/vm/src/vm/runners/builtin_runner/hash.rs b/vm/src/vm/runners/builtin_runner/hash.rs index bd641f2690..225b779d82 100644 --- a/vm/src/vm/runners/builtin_runner/hash.rs +++ b/vm/src/vm/runners/builtin_runner/hash.rs @@ -147,10 +147,9 @@ impl HashBuiltinRunner { mod tests { use super::*; use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; - use crate::serde::deserialize_program::BuiltinName; + use crate::types::builtin_name::BuiltinName; use crate::types::program::Program; use crate::utils::test_utils::*; - use crate::vm::runners::builtin_runner::HASH_BUILTIN_NAME; use crate::vm::runners::cairo_runner::CairoRunner; use crate::{felt_hex, relocatable}; @@ -218,7 +217,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::InvalidStopPointer(Box::new(( - HASH_BUILTIN_NAME, + BuiltinName::pedersen, relocatable!(0, 999), relocatable!(0, 0) )))) @@ -269,7 +268,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), - Err(RunnerError::NoStopPointer(Box::new(HASH_BUILTIN_NAME))) + Err(RunnerError::NoStopPointer(Box::new(BuiltinName::pedersen))) ); } diff --git a/vm/src/vm/runners/builtin_runner/keccak.rs b/vm/src/vm/runners/builtin_runner/keccak.rs index 93daf92f82..b80bb9061f 100644 --- a/vm/src/vm/runners/builtin_runner/keccak.rs +++ b/vm/src/vm/runners/builtin_runner/keccak.rs @@ -1,6 +1,7 @@ use crate::air_private_input::{PrivateInput, PrivateInputKeccakState}; use crate::math_utils::safe_div_usize; use crate::stdlib::{cell::RefCell, collections::HashMap, prelude::*}; +use crate::types::builtin_name::BuiltinName; use crate::types::instance_definitions::keccak_instance_def::{ CELLS_PER_KECCAK, INPUT_CELLS_PER_KECCAK, }; @@ -14,8 +15,6 @@ use lazy_static::lazy_static; use num_bigint::BigUint; use num_integer::div_ceil; -use super::KECCAK_BUILTIN_NAME; - const KECCAK_FELT_BYTE_SIZE: usize = 25; // 200 / 8 const BITS: u32 = 200; lazy_static! { @@ -86,7 +85,7 @@ impl KeccakBuiltinRunner { let num = value .get_int_ref() .ok_or(RunnerError::BuiltinExpectedInteger(Box::new(( - KECCAK_BUILTIN_NAME, + BuiltinName::keccak, (first_input_addr + i)?, ))))?; if num >= &KECCAK_INPUT_MAX { @@ -282,7 +281,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::InvalidStopPointer(Box::new(( - KECCAK_BUILTIN_NAME, + BuiltinName::keccak, relocatable!(0, 992), relocatable!(0, 0) )))) @@ -333,7 +332,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), - Err(RunnerError::NoStopPointer(Box::new(KECCAK_BUILTIN_NAME))) + Err(RunnerError::NoStopPointer(Box::new(BuiltinName::keccak))) ); } @@ -499,7 +498,7 @@ mod tests { assert_eq!( result, Err(RunnerError::BuiltinExpectedInteger(Box::new(( - KECCAK_BUILTIN_NAME, + BuiltinName::keccak, (0, 0).into() )))) ); diff --git a/vm/src/vm/runners/builtin_runner/mod.rs b/vm/src/vm/runners/builtin_runner/mod.rs index e034ed46e4..1d1f21c07e 100644 --- a/vm/src/vm/runners/builtin_runner/mod.rs +++ b/vm/src/vm/runners/builtin_runner/mod.rs @@ -1,7 +1,7 @@ use crate::air_private_input::PrivateInput; use crate::math_utils::safe_div_usize; -use crate::serde::deserialize_program::BuiltinName; use crate::stdlib::prelude::*; +use crate::types::builtin_name::BuiltinName; use crate::types::instance_definitions::bitwise_instance_def::{ CELLS_PER_BITWISE, INPUT_CELLS_PER_BITWISE, }; @@ -56,19 +56,6 @@ pub use signature::SignatureBuiltinRunner; use super::cairo_pie::BuiltinAdditionalData; -pub const OUTPUT_BUILTIN_NAME: &str = "output_builtin"; -pub const HASH_BUILTIN_NAME: &str = "pedersen_builtin"; -pub const RANGE_CHECK_BUILTIN_NAME: &str = "range_check_builtin"; -pub const RANGE_CHECK_96_BUILTIN_NAME: &str = "range_check_96_builtin"; -pub const SIGNATURE_BUILTIN_NAME: &str = "ecdsa_builtin"; -pub const BITWISE_BUILTIN_NAME: &str = "bitwise_builtin"; -pub const EC_OP_BUILTIN_NAME: &str = "ec_op_builtin"; -pub const KECCAK_BUILTIN_NAME: &str = "keccak_builtin"; -pub const POSEIDON_BUILTIN_NAME: &str = "poseidon_builtin"; -pub const SEGMENT_ARENA_BUILTIN_NAME: &str = "segment_arena_builtin"; -pub const ADD_MOD_BUILTIN_NAME: &str = "add_mod_builtin"; -pub const MUL_MOD_BUILTIN_NAME: &str = "mul_mod_builtin"; - /* NB: this enum is no accident: we may need (and cairo-vm-py *does* need) * structs containing this to be `Send`. The only two ways to achieve that * are either storing a `dyn Trait` inside an `Arc>` or @@ -406,23 +393,7 @@ impl BuiltinRunner { } } - pub fn name(&self) -> &'static str { - match self { - BuiltinRunner::Bitwise(_) => BITWISE_BUILTIN_NAME, - BuiltinRunner::EcOp(_) => EC_OP_BUILTIN_NAME, - BuiltinRunner::Hash(_) => HASH_BUILTIN_NAME, - BuiltinRunner::RangeCheck(_) => RANGE_CHECK_BUILTIN_NAME, - BuiltinRunner::RangeCheck96(_) => RANGE_CHECK_96_BUILTIN_NAME, - BuiltinRunner::Output(_) => OUTPUT_BUILTIN_NAME, - BuiltinRunner::Keccak(_) => KECCAK_BUILTIN_NAME, - BuiltinRunner::Signature(_) => SIGNATURE_BUILTIN_NAME, - BuiltinRunner::Poseidon(_) => POSEIDON_BUILTIN_NAME, - BuiltinRunner::SegmentArena(_) => SEGMENT_ARENA_BUILTIN_NAME, - BuiltinRunner::Mod(b) => b.name(), - } - } - - pub fn identifier(&self) -> BuiltinName { + pub fn name(&self) -> BuiltinName { match self { BuiltinRunner::Bitwise(_) => BuiltinName::bitwise, BuiltinRunner::EcOp(_) => BuiltinName::ec_op, @@ -434,7 +405,7 @@ impl BuiltinRunner { BuiltinRunner::Signature(_) => BuiltinName::ecdsa, BuiltinRunner::Poseidon(_) => BuiltinName::poseidon, BuiltinRunner::SegmentArena(_) => BuiltinName::segment_arena, - BuiltinRunner::Mod(b) => b.identifier(), + BuiltinRunner::Mod(b) => b.name(), } } @@ -661,7 +632,7 @@ mod tests { use super::*; use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; use crate::relocatable; - use crate::serde::deserialize_program::BuiltinName; + use crate::types::builtin_name::BuiltinName; use crate::types::program::Program; use crate::vm::errors::memory_errors::InsufficientAllocatedCellsError; use crate::vm::runners::cairo_runner::CairoRunner; @@ -756,7 +727,7 @@ mod tests { fn get_name_bitwise() { let bitwise = BitwiseBuiltinRunner::new(Some(10), true); let builtin: BuiltinRunner = bitwise.into(); - assert_eq!(BITWISE_BUILTIN_NAME, builtin.name()) + assert_eq!(BuiltinName::bitwise, builtin.name()) } #[test] @@ -764,7 +735,7 @@ mod tests { fn get_name_hash() { let hash = HashBuiltinRunner::new(Some(10), true); let builtin: BuiltinRunner = hash.into(); - assert_eq!(HASH_BUILTIN_NAME, builtin.name()) + assert_eq!(BuiltinName::pedersen, builtin.name()) } #[test] @@ -772,7 +743,7 @@ mod tests { fn get_name_range_check() { let range_check = RangeCheckBuiltinRunner::::new(Some(10), true); let builtin: BuiltinRunner = range_check.into(); - assert_eq!(RANGE_CHECK_BUILTIN_NAME, builtin.name()) + assert_eq!(BuiltinName::range_check, builtin.name()) } #[test] @@ -780,7 +751,7 @@ mod tests { fn get_name_ec_op() { let ec_op = EcOpBuiltinRunner::new(Some(256), true); let builtin: BuiltinRunner = ec_op.into(); - assert_eq!(EC_OP_BUILTIN_NAME, builtin.name()) + assert_eq!(BuiltinName::ec_op, builtin.name()) } #[test] @@ -788,7 +759,7 @@ mod tests { fn get_name_ecdsa() { let signature = SignatureBuiltinRunner::new(Some(10), true); let builtin: BuiltinRunner = signature.into(); - assert_eq!(SIGNATURE_BUILTIN_NAME, builtin.name()) + assert_eq!(BuiltinName::ecdsa, builtin.name()) } #[test] @@ -796,7 +767,7 @@ mod tests { fn get_name_output() { let output = OutputBuiltinRunner::new(true); let builtin: BuiltinRunner = output.into(); - assert_eq!(OUTPUT_BUILTIN_NAME, builtin.name()) + assert_eq!(BuiltinName::output, builtin.name()) } #[test] @@ -998,7 +969,7 @@ mod tests { Err(MemoryError::InsufficientAllocatedCells( InsufficientAllocatedCellsError::MinStepNotReached(Box::new(( 160, - KECCAK_BUILTIN_NAME + BuiltinName::keccak ))) )) ); @@ -1219,7 +1190,7 @@ mod tests { builtin.run_security_checks(&vm), Err(VirtualMachineError::Memory( MemoryError::MissingMemoryCellsWithOffsets(bx) - )) if *bx == (BITWISE_BUILTIN_NAME, vec![0]) + )) if *bx == (BuiltinName::bitwise, vec![0]) ); } @@ -1238,7 +1209,7 @@ mod tests { builtin.run_security_checks(&vm), Err(VirtualMachineError::Memory( MemoryError::MissingMemoryCells(bx) - )) if *bx == BITWISE_BUILTIN_NAME + )) if *bx == BuiltinName::bitwise ); } @@ -1259,7 +1230,7 @@ mod tests { builtin.run_security_checks(&vm), Err(VirtualMachineError::Memory( MemoryError::MissingMemoryCellsWithOffsets(bx) - )) if *bx == (HASH_BUILTIN_NAME, vec![0]) + )) if *bx == (BuiltinName::pedersen, vec![0]) ); } @@ -1278,7 +1249,7 @@ mod tests { builtin.run_security_checks(&vm), Err(VirtualMachineError::Memory( MemoryError::MissingMemoryCells(bx) - )) if *bx == HASH_BUILTIN_NAME + )) if *bx == BuiltinName::pedersen ); } @@ -1303,7 +1274,7 @@ mod tests { builtin.run_security_checks(&vm), Err(VirtualMachineError::Memory( MemoryError::MissingMemoryCells(bx) - )) if *bx == RANGE_CHECK_BUILTIN_NAME + )) if *bx == BuiltinName::range_check ); } @@ -1321,7 +1292,7 @@ mod tests { builtin.run_security_checks(&vm), Err(VirtualMachineError::Memory( MemoryError::MissingMemoryCells(bx) - )) if *bx == RANGE_CHECK_BUILTIN_NAME + )) if *bx == BuiltinName::range_check ); } @@ -1390,7 +1361,7 @@ mod tests { builtin.run_security_checks(&vm), Err(VirtualMachineError::Memory( MemoryError::MissingMemoryCells(bx) - )) if *bx == EC_OP_BUILTIN_NAME + )) if *bx == BuiltinName::ec_op ); } @@ -1409,7 +1380,7 @@ mod tests { builtin.run_security_checks(&vm), Err(VirtualMachineError::Memory( MemoryError::MissingMemoryCells(bx) - )) if *bx == EC_OP_BUILTIN_NAME + )) if *bx == BuiltinName::ec_op ); } @@ -1431,7 +1402,7 @@ mod tests { builtin.run_security_checks(&vm), Err(VirtualMachineError::Memory( MemoryError::MissingMemoryCellsWithOffsets(bx) - )) if *bx == (EC_OP_BUILTIN_NAME, vec![0]) + )) if *bx == (BuiltinName::ec_op, vec![0]) ); } @@ -1462,7 +1433,7 @@ mod tests { builtin.run_security_checks(&vm), Err(VirtualMachineError::Memory( MemoryError::MissingMemoryCellsWithOffsets(bx) - )) if *bx == (EC_OP_BUILTIN_NAME, vec![7]) + )) if *bx == (BuiltinName::ec_op, vec![7]) ); } diff --git a/vm/src/vm/runners/builtin_runner/modulo.rs b/vm/src/vm/runners/builtin_runner/modulo.rs index 4cbfd56328..6183c2b88a 100644 --- a/vm/src/vm/runners/builtin_runner/modulo.rs +++ b/vm/src/vm/runners/builtin_runner/modulo.rs @@ -1,13 +1,13 @@ use crate::{ air_private_input::{ModInput, ModInputInstance, ModInputMemoryVars, PrivateInput}, math_utils::{div_mod_unsigned, safe_div_usize}, - serde::deserialize_program::BuiltinName, stdlib::{ borrow::Cow, collections::BTreeMap, prelude::{Box, Vec}, }, types::{ + builtin_name::BuiltinName, errors::math_errors::MathError, instance_definitions::mod_instance_def::{ModInstanceDef, CELLS_PER_MOD, N_WORDS}, relocatable::{relocate_address, MaybeRelocatable, Relocatable}, @@ -109,14 +109,7 @@ impl ModBuiltinRunner { } } - pub fn name(&self) -> &'static str { - match self.builtin_type { - ModBuiltinType::Mul => super::MUL_MOD_BUILTIN_NAME, - ModBuiltinType::Add => super::ADD_MOD_BUILTIN_NAME, - } - } - - pub fn identifier(&self) -> BuiltinName { + pub fn name(&self) -> BuiltinName { match self.builtin_type { ModBuiltinType::Mul => BuiltinName::mul_mod, ModBuiltinType::Add => BuiltinName::add_mod, @@ -694,10 +687,7 @@ mod tests { hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor, types::layout_name::LayoutName, utils::test_utils::Program, - vm::runners::{ - builtin_runner::{BuiltinRunner, ADD_MOD_BUILTIN_NAME, MUL_MOD_BUILTIN_NAME}, - cairo_runner::CairoRunner, - }, + vm::runners::{builtin_runner::BuiltinRunner, cairo_runner::CairoRunner}, Felt252, }; @@ -732,7 +722,7 @@ mod tests { let air_private_input = runner.get_air_private_input(&vm); assert_eq!( - air_private_input.0.get(ADD_MOD_BUILTIN_NAME).unwrap()[0], + air_private_input.0.get(&BuiltinName::add_mod).unwrap()[0], PrivateInput::Mod(ModInput { instances: vec![ ModInputInstance { @@ -800,7 +790,7 @@ mod tests { }) ); assert_eq!( - air_private_input.0.get(MUL_MOD_BUILTIN_NAME).unwrap()[0], + air_private_input.0.get(&BuiltinName::mul_mod).unwrap()[0], PrivateInput::Mod(ModInput { instances: vec![ ModInputInstance { diff --git a/vm/src/vm/runners/builtin_runner/output.rs b/vm/src/vm/runners/builtin_runner/output.rs index c6283d3756..f0015761f6 100644 --- a/vm/src/vm/runners/builtin_runner/output.rs +++ b/vm/src/vm/runners/builtin_runner/output.rs @@ -1,4 +1,5 @@ use crate::stdlib::{collections::HashMap, prelude::*}; +use crate::types::builtin_name::BuiltinName; use crate::types::relocatable::{MaybeRelocatable, Relocatable}; use crate::vm::errors::memory_errors::MemoryError; use crate::vm::errors::runner_errors::RunnerError; @@ -8,8 +9,6 @@ use crate::vm::runners::cairo_pie::{ use crate::vm::vm_core::VirtualMachine; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; -use super::OUTPUT_BUILTIN_NAME; - #[derive(Debug, Clone, PartialEq)] pub struct OutputBuiltinState { pub base: usize, @@ -85,14 +84,14 @@ impl OutputBuiltinRunner { ) -> Result { if self.included { let stop_pointer_addr = (pointer - 1) - .map_err(|_| RunnerError::NoStopPointer(Box::new(OUTPUT_BUILTIN_NAME)))?; + .map_err(|_| RunnerError::NoStopPointer(Box::new(BuiltinName::output)))?; let stop_pointer = segments .memory .get_relocatable(stop_pointer_addr) - .map_err(|_| RunnerError::NoStopPointer(Box::new(OUTPUT_BUILTIN_NAME)))?; + .map_err(|_| RunnerError::NoStopPointer(Box::new(BuiltinName::output)))?; if self.base as isize != stop_pointer.segment_index { return Err(RunnerError::InvalidStopPointerIndex(Box::new(( - OUTPUT_BUILTIN_NAME, + BuiltinName::output, stop_pointer, self.base, )))); @@ -101,7 +100,7 @@ impl OutputBuiltinRunner { let used = self.get_used_cells(segments).map_err(RunnerError::Memory)?; if stop_ptr != used { return Err(RunnerError::InvalidStopPointer(Box::new(( - OUTPUT_BUILTIN_NAME, + BuiltinName::output, Relocatable::from((self.base as isize, used)), Relocatable::from((self.base as isize, stop_ptr)), )))); @@ -260,7 +259,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::InvalidStopPointer(Box::new(( - OUTPUT_BUILTIN_NAME, + BuiltinName::output, relocatable!(0, 998), relocatable!(0, 0) )))) @@ -311,7 +310,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), - Err(RunnerError::NoStopPointer(Box::new(OUTPUT_BUILTIN_NAME))) + Err(RunnerError::NoStopPointer(Box::new(BuiltinName::output))) ); } diff --git a/vm/src/vm/runners/builtin_runner/poseidon.rs b/vm/src/vm/runners/builtin_runner/poseidon.rs index 51b12cc73b..7886d98e84 100644 --- a/vm/src/vm/runners/builtin_runner/poseidon.rs +++ b/vm/src/vm/runners/builtin_runner/poseidon.rs @@ -1,5 +1,6 @@ use crate::air_private_input::{PrivateInput, PrivateInputPoseidonState}; use crate::stdlib::{cell::RefCell, collections::HashMap, prelude::*}; +use crate::types::builtin_name::BuiltinName; use crate::types::errors::math_errors::MathError; use crate::types::instance_definitions::poseidon_instance_def::{ CELLS_PER_POSEIDON, INPUT_CELLS_PER_POSEIDON, @@ -13,8 +14,6 @@ use crate::Felt252; use num_integer::div_ceil; use starknet_crypto::{poseidon_permute_comp, FieldElement}; -use super::POSEIDON_BUILTIN_NAME; - #[derive(Debug, Clone)] pub struct PoseidonBuiltinRunner { pub base: usize, @@ -81,7 +80,7 @@ impl PoseidonBuiltinRunner { let num = value .get_int_ref() .ok_or(RunnerError::BuiltinExpectedInteger(Box::new(( - POSEIDON_BUILTIN_NAME, + BuiltinName::poseidon, (first_input_addr + i)?, ))))?; FieldElement::from_bytes_be(&num.to_bytes_be()) @@ -150,7 +149,7 @@ mod tests { use super::*; use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; use crate::relocatable; - use crate::serde::deserialize_program::BuiltinName; + use crate::types::builtin_name::BuiltinName; use crate::types::program::Program; use crate::utils::test_utils::*; use crate::vm::runners::cairo_runner::CairoRunner; @@ -226,7 +225,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::InvalidStopPointer(Box::new(( - POSEIDON_BUILTIN_NAME, + BuiltinName::poseidon, relocatable!(0, 1002), relocatable!(0, 0) )))) @@ -277,7 +276,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), - Err(RunnerError::NoStopPointer(Box::new(POSEIDON_BUILTIN_NAME))) + Err(RunnerError::NoStopPointer(Box::new(BuiltinName::poseidon))) ); } diff --git a/vm/src/vm/runners/builtin_runner/range_check.rs b/vm/src/vm/runners/builtin_runner/range_check.rs index b9b49992ce..f5c4991a74 100644 --- a/vm/src/vm/runners/builtin_runner/range_check.rs +++ b/vm/src/vm/runners/builtin_runner/range_check.rs @@ -4,6 +4,7 @@ use crate::{ cmp::{max, min}, prelude::*, }, + types::builtin_name::BuiltinName, }; use crate::Felt252; @@ -20,8 +21,6 @@ use crate::{ use lazy_static::lazy_static; -use super::{RANGE_CHECK_96_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME}; - const INNER_RC_BOUND_SHIFT: u64 = 16; const INNER_RC_BOUND_MASK: u64 = u16::MAX as u64; @@ -72,10 +71,10 @@ impl RangeCheckBuiltinRunner { self.ratio } - pub fn name(&self) -> &'static str { + pub fn name(&self) -> BuiltinName { match N_PARTS { - RC_N_PARTS_96 => RANGE_CHECK_96_BUILTIN_NAME, - _ => RANGE_CHECK_BUILTIN_NAME, + RC_N_PARTS_96 => BuiltinName::range_check96, + _ => BuiltinName::range_check, } } @@ -166,9 +165,8 @@ impl RangeCheckBuiltinRunner { mod tests { use super::*; use crate::relocatable; - use crate::serde::deserialize_program::BuiltinName; + use crate::types::builtin_name::BuiltinName; use crate::vm::errors::runner_errors::RunnerError; - use crate::vm::runners::builtin_runner::RANGE_CHECK_BUILTIN_NAME; use crate::vm::vm_memory::memory::Memory; use crate::{ hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor, @@ -241,7 +239,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::InvalidStopPointer(Box::new(( - RANGE_CHECK_BUILTIN_NAME, + BuiltinName::range_check, relocatable!(0, 998), relocatable!(0, 0) )))) @@ -295,7 +293,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::NoStopPointer(Box::new( - RANGE_CHECK_BUILTIN_NAME + BuiltinName::range_check ))) ); } diff --git a/vm/src/vm/runners/builtin_runner/segment_arena.rs b/vm/src/vm/runners/builtin_runner/segment_arena.rs index 5cc61fb706..95d849f541 100644 --- a/vm/src/vm/runners/builtin_runner/segment_arena.rs +++ b/vm/src/vm/runners/builtin_runner/segment_arena.rs @@ -88,8 +88,8 @@ fn gen_arg(segments: &mut MemorySegmentManager, data: &[MaybeRelocatable; 3]) -> #[cfg(test)] mod tests { use super::*; + use crate::types::builtin_name::BuiltinName; use crate::vm::errors::runner_errors::RunnerError; - use crate::vm::runners::builtin_runner::SEGMENT_ARENA_BUILTIN_NAME; use crate::vm::vm_core::VirtualMachine; use crate::{relocatable, utils::test_utils::*, vm::runners::builtin_runner::BuiltinRunner}; #[cfg(not(feature = "std"))] @@ -153,7 +153,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::InvalidStopPointer(Box::new(( - SEGMENT_ARENA_BUILTIN_NAME, + BuiltinName::segment_arena, relocatable!(0, 3), relocatable!(0, 0) )))) @@ -229,7 +229,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::NoStopPointer(Box::new( - SEGMENT_ARENA_BUILTIN_NAME + BuiltinName::segment_arena ))) ); } diff --git a/vm/src/vm/runners/builtin_runner/signature.rs b/vm/src/vm/runners/builtin_runner/signature.rs index f72f62a5af..a95ad508a4 100644 --- a/vm/src/vm/runners/builtin_runner/signature.rs +++ b/vm/src/vm/runners/builtin_runner/signature.rs @@ -220,13 +220,14 @@ mod tests { use super::*; use crate::{ relocatable, + types::builtin_name::BuiltinName, utils::test_utils::*, vm::{ errors::{ memory_errors::{InsufficientAllocatedCellsError, MemoryError}, runner_errors::RunnerError, }, - runners::builtin_runner::{BuiltinRunner, SIGNATURE_BUILTIN_NAME}, + runners::builtin_runner::BuiltinRunner, vm_core::VirtualMachine, vm_memory::{memory::Memory, memory_segments::MemorySegmentManager}, }, @@ -310,7 +311,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), Err(RunnerError::InvalidStopPointer(Box::new(( - SIGNATURE_BUILTIN_NAME, + BuiltinName::ecdsa, relocatable!(0, 998), relocatable!(0, 0) )))) @@ -337,7 +338,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, pointer), - Err(RunnerError::NoStopPointer(Box::new(SIGNATURE_BUILTIN_NAME))) + Err(RunnerError::NoStopPointer(Box::new(BuiltinName::ecdsa))) ); } @@ -427,7 +428,7 @@ mod tests { Err(MemoryError::InsufficientAllocatedCells( InsufficientAllocatedCellsError::MinStepNotReached(Box::new(( 512, - SIGNATURE_BUILTIN_NAME + BuiltinName::ecdsa ))) )) ) @@ -444,7 +445,7 @@ mod tests { builtin.get_used_cells_and_allocated_size(&vm), Err(MemoryError::InsufficientAllocatedCells( InsufficientAllocatedCellsError::BuiltinCells(Box::new(( - SIGNATURE_BUILTIN_NAME, + BuiltinName::ecdsa, 50, 2 ))) @@ -461,7 +462,7 @@ mod tests { assert_eq!( builtin.final_stack(&vm.segments, (0, 1).into()), Err(RunnerError::InvalidStopPointerIndex(Box::new(( - SIGNATURE_BUILTIN_NAME, + BuiltinName::ecdsa, relocatable!(1, 0), 0 )))) diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs index 16bcb80d41..c66dce1f2b 100644 --- a/vm/src/vm/runners/cairo_pie.rs +++ b/vm/src/vm/runners/cairo_pie.rs @@ -1,7 +1,7 @@ use super::cairo_runner::ExecutionResources; use crate::stdlib::prelude::{String, Vec}; +use crate::types::builtin_name::BuiltinName; use crate::{ - serde::deserialize_program::BuiltinName, stdlib::{collections::HashMap, prelude::*}, types::relocatable::{MaybeRelocatable, Relocatable}, Felt252, @@ -68,12 +68,18 @@ pub enum BuiltinAdditionalData { None, } +#[derive(Serialize, Clone, Debug, PartialEq, Eq)] +pub struct CairoPieAdditionalData( + #[serde(with = "crate::types::builtin_name::serde_generic_map_impl")] + pub HashMap, +); + #[derive(Serialize, Clone, Debug, PartialEq, Eq)] pub struct CairoPie { pub metadata: CairoPieMetadata, pub memory: CairoPieMemory, pub execution_resources: ExecutionResources, - pub additional_data: HashMap, + pub additional_data: CairoPieAdditionalData, pub version: CairoPieVersion, } @@ -85,7 +91,7 @@ pub struct CairoPieMetadata { pub ret_fp_segment: SegmentInfo, pub ret_pc_segment: SegmentInfo, #[serde(serialize_with = "serde_impl::serialize_builtin_segments")] - pub builtin_segments: HashMap, + pub builtin_segments: HashMap, pub extra_segments: Vec, } @@ -132,6 +138,7 @@ impl CairoPie { mod serde_impl { use crate::stdlib::collections::HashMap; + use crate::types::builtin_name::BuiltinName; use num_traits::Num; use serde::ser::SerializeMap; @@ -323,26 +330,26 @@ mod serde_impl { } pub fn serialize_builtin_segments( - values: &HashMap, + values: &HashMap, serializer: S, ) -> Result where S: Serializer, { let mut map_serializer = serializer.serialize_map(Some(values.len()))?; - const BUILTIN_ORDERED_LIST: &[&str] = &[ - "output", - "pedersen", - "range_check", - "ecdsa", - "bitwise", - "ec_op", - "keccak", - "poseidon", + const BUILTIN_ORDERED_LIST: &[BuiltinName] = &[ + BuiltinName::output, + BuiltinName::pedersen, + BuiltinName::range_check, + BuiltinName::ecdsa, + BuiltinName::bitwise, + BuiltinName::ec_op, + BuiltinName::keccak, + BuiltinName::poseidon, ]; for name in BUILTIN_ORDERED_LIST { - if let Some(info) = values.get(*name) { + if let Some(info) = values.get(name) { map_serializer.serialize_entry(name, info)? } } diff --git a/vm/src/vm/runners/cairo_runner.rs b/vm/src/vm/runners/cairo_runner.rs index 1040e1f52a..fdda4030f2 100644 --- a/vm/src/vm/runners/cairo_runner.rs +++ b/vm/src/vm/runners/cairo_runner.rs @@ -7,7 +7,7 @@ use crate::{ ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}, prelude::*, }, - types::{layout::MEMORY_UNITS_PER_STEP, layout_name::LayoutName}, + types::{builtin_name::BuiltinName, layout::MEMORY_UNITS_PER_STEP, layout_name::LayoutName}, vm::{ runners::builtin_runner::SegmentArenaBuiltinRunner, trace::trace_entry::{relocate_trace_register, RelocatedTraceEntry}, @@ -18,7 +18,6 @@ use crate::{ use crate::{ hint_processor::hint_processor_definition::{HintProcessor, HintReference}, math_utils::safe_div_usize, - serde::deserialize_program::BuiltinName, types::{ errors::{math_errors::MathError, program_errors::ProgramError}, exec_scope::ExecutionScopes, @@ -50,7 +49,7 @@ use num_integer::div_rem; use num_traits::{ToPrimitive, Zero}; use serde::{Deserialize, Serialize}; -use super::builtin_runner::ModBuiltinRunner; +use super::{builtin_runner::ModBuiltinRunner, cairo_pie::CairoPieAdditionalData}; use super::{ builtin_runner::{ KeccakBuiltinRunner, PoseidonBuiltinRunner, RC_N_PARTS_96, RC_N_PARTS_STANDARD, @@ -353,7 +352,7 @@ impl CairoRunner { } if !program_builtins.is_empty() && !allow_missing_builtins { return Err(RunnerError::NoBuiltinForInstance(Box::new(( - program_builtins.iter().map(|n| n.name()).collect(), + program_builtins.iter().map(|n| **n).collect(), self.layout.name, )))); } @@ -522,10 +521,10 @@ impl CairoRunner { let builtin_runners = vm .builtin_runners .iter() - .map(|b| (b.identifier(), b)) + .map(|b| (b.name(), b)) .collect::>(); - for builtin_id in &self.program.builtins { - if let Some(builtin_runner) = builtin_runners.get(builtin_id) { + for builtin_name in &self.program.builtins { + if let Some(builtin_runner) = builtin_runners.get(builtin_name) { stack.append(&mut builtin_runner.initial_stack()); } else { stack.push(Felt252::ZERO.into()) @@ -1019,18 +1018,14 @@ impl CairoRunner { pub fn get_builtin_segment_info_for_pie( &self, vm: &VirtualMachine, - ) -> Result, RunnerError> { + ) -> Result, RunnerError> { let mut builtin_segment_info = HashMap::new(); for builtin in &vm.builtin_runners { let (index, stop_ptr) = builtin.get_memory_segment_addresses(); builtin_segment_info.insert( - builtin - .name() - .strip_suffix("_builtin") - .unwrap_or_default() - .to_string(), + builtin.name(), ( index as isize, stop_ptr.ok_or_else(|| RunnerError::NoStopPointer(Box::new(builtin.name())))?, @@ -1059,7 +1054,7 @@ impl CairoRunner { let mut builtin_instance_counter = HashMap::new(); for builtin_runner in &vm.builtin_runners { builtin_instance_counter.insert( - builtin_runner.name().to_string(), + builtin_runner.name(), builtin_runner.get_used_instances(&vm.segments)?, ); } @@ -1273,22 +1268,22 @@ impl CairoRunner { return Err(RunnerError::ReadReturnValuesNoEndRun); } let mut pointer = vm.get_ap(); - for builtin_id in self.program.builtins.iter().rev() { + for builtin_name in self.program.builtins.iter().rev() { if let Some(builtin_runner) = vm .builtin_runners .iter_mut() - .find(|b| b.identifier() == *builtin_id) + .find(|b| b.name() == *builtin_name) { let new_pointer = builtin_runner.final_stack(&vm.segments, pointer)?; pointer = new_pointer; } else { if !allow_missing_builtins { - return Err(RunnerError::MissingBuiltin(builtin_id.name())); + return Err(RunnerError::MissingBuiltin(*builtin_name)); } pointer.offset = pointer.offset.saturating_sub(1); if !vm.get_integer(pointer)?.is_zero() { - return Err(RunnerError::MissingBuiltinStopPtrNotZero(builtin_id.name())); + return Err(RunnerError::MissingBuiltinStopPtrNotZero(*builtin_name)); } } } @@ -1326,7 +1321,7 @@ impl CairoRunner { .filter(|builtin_runner| { self.get_program_builtins() .iter() - .any(|bn| bn.name() == builtin_runner.name()) + .any(|bn| *bn == builtin_runner.name()) }) { stack_ptr = runner.final_stack(&vm.segments, stack_ptr)? @@ -1427,11 +1422,12 @@ impl CairoRunner { metadata, memory: (&vm.segments.memory).into(), execution_resources: self.get_execution_resources(vm)?, - additional_data: vm - .builtin_runners - .iter() - .map(|b| (b.name().to_string(), b.get_additional_data())) - .collect(), + additional_data: CairoPieAdditionalData( + vm.builtin_runners + .iter() + .map(|b| (b.name(), b.get_additional_data())) + .collect(), + ), version: CairoPieVersion { cairo_pie: () }, }) } @@ -1493,16 +1489,13 @@ impl CairoRunner { .iter() .map(|builtin| -> Result<_, VirtualMachineError> { let (base, stop_ptr) = builtin.get_memory_segment_addresses(); - let stop_ptr = if self.program.builtins.contains(&builtin.identifier()) { + let stop_ptr = if self.program.builtins.contains(&builtin.name()) { stop_ptr.ok_or_else(|| RunnerError::NoStopPointer(Box::new(builtin.name())))? } else { stop_ptr.unwrap_or_default() }; - Ok(( - builtin.name().strip_suffix("_builtin").unwrap_or_default(), - relocate((base, stop_ptr))?, - )) + Ok((builtin.name().to_str(), relocate((base, stop_ptr))?)) }) .collect() } @@ -1522,7 +1515,8 @@ pub struct SegmentInfo { pub struct ExecutionResources { pub n_steps: usize, pub n_memory_holes: usize, - pub builtin_instance_counter: HashMap, + #[serde(with = "crate::types::builtin_name::serde_generic_map_impl")] + pub builtin_instance_counter: HashMap, } /// Returns a copy of the execution resources where all the builtins with a usage counter @@ -1558,7 +1552,7 @@ impl AddAssign<&ExecutionResources> for ExecutionResources { self.n_memory_holes += rhs.n_memory_holes; for (k, v) in rhs.builtin_instance_counter.iter() { // FIXME: remove k's clone, use &'static str - *self.builtin_instance_counter.entry(k.clone()).or_insert(0) += v; + *self.builtin_instance_counter.entry(*k).or_insert(0) += v; } } } @@ -1579,7 +1573,7 @@ impl SubAssign<&ExecutionResources> for ExecutionResources { self.n_memory_holes -= rhs.n_memory_holes; for (k, v) in rhs.builtin_instance_counter.iter() { // FIXME: remove k's clone, use &'static str - let entry = self.builtin_instance_counter.entry(k.clone()).or_insert(0); + let entry = self.builtin_instance_counter.entry(*k).or_insert(0); *entry = (*entry).saturating_sub(*v); } } @@ -1611,11 +1605,6 @@ mod tests { use crate::air_private_input::{PrivateInput, PrivateInputSignature, SignatureInput}; use crate::cairo_run::{cairo_run, CairoRunConfig}; use crate::stdlib::collections::{HashMap, HashSet}; - use crate::vm::runners::builtin_runner::{ - BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, KECCAK_BUILTIN_NAME, - OUTPUT_BUILTIN_NAME, POSEIDON_BUILTIN_NAME, RANGE_CHECK_BUILTIN_NAME, - SEGMENT_ARENA_BUILTIN_NAME, SIGNATURE_BUILTIN_NAME, - }; use crate::vm::vm_memory::memory::MemoryCell; use crate::felt_hex; @@ -1723,7 +1712,7 @@ mod tests { offset: 0, }) ); - assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].name(), BuiltinName::output); assert_eq!(vm.builtin_runners[0].base(), 7); assert_eq!(vm.segments.num_segments(), 8); @@ -1751,7 +1740,7 @@ mod tests { offset: 0 }) ); - assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].name(), BuiltinName::output); assert_eq!(vm.builtin_runners[0].base(), 2); assert_eq!(vm.segments.num_segments(), 3); @@ -1985,7 +1974,7 @@ mod tests { cairo_runner.initialize_builtins(&mut vm, false).unwrap(); cairo_runner.initialize_segments(&mut vm, None); vm.segments = segments![((2, 0), 23), ((2, 1), 233)]; - assert_eq!(vm.builtin_runners[0].name(), RANGE_CHECK_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].name(), BuiltinName::range_check); assert_eq!(vm.builtin_runners[0].base(), 2); cairo_runner.initialize_vm(&mut vm).unwrap(); assert!(vm @@ -2424,7 +2413,7 @@ mod tests { ], ); //Check the range_check builtin segment - assert_eq!(vm.builtin_runners[0].name(), RANGE_CHECK_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].name(), BuiltinName::range_check); assert_eq!(vm.builtin_runners[0].base(), 2); check_memory!( @@ -2542,7 +2531,7 @@ mod tests { ], ); //Check that the output to be printed is correct - assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].name(), BuiltinName::output); assert_eq!(vm.builtin_runners[0].base(), 2); check_memory!(vm.segments.memory, ((2, 0), 1), ((2, 1), 17)); assert!(vm @@ -2686,7 +2675,7 @@ mod tests { ], ); //Check the range_check builtin segment - assert_eq!(vm.builtin_runners[1].name(), RANGE_CHECK_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[1].name(), BuiltinName::range_check); assert_eq!(vm.builtin_runners[1].base(), 3); check_memory!( @@ -2701,7 +2690,7 @@ mod tests { .is_none()); //Check the output segment - assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].name(), BuiltinName::output); assert_eq!(vm.builtin_runners[0].base(), 2); check_memory!(vm.segments.memory, ((2, 0), 7)); @@ -3141,7 +3130,7 @@ mod tests { let mut vm = vm!(); cairo_runner.initialize_builtins(&mut vm, false).unwrap(); cairo_runner.initialize_segments(&mut vm, None); - assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].name(), BuiltinName::output); assert_eq!(vm.builtin_runners[0].base(), 2); vm.segments = segments![((2, 0), 1), ((2, 1), 2)]; @@ -3259,7 +3248,7 @@ mod tests { let mut vm = vm!(); cairo_runner.initialize_builtins(&mut vm, false).unwrap(); cairo_runner.initialize_segments(&mut vm, None); - assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].name(), BuiltinName::output); assert_eq!(vm.builtin_runners[0].base(), 2); vm.segments = segments![( (2, 0), @@ -3351,11 +3340,11 @@ mod tests { let cairo_runner = cairo_runner!(program); let mut vm = vm!(); cairo_runner.initialize_builtins(&mut vm, false).unwrap(); - assert_eq!(vm.builtin_runners[0].name(), OUTPUT_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[1].name(), HASH_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[2].name(), RANGE_CHECK_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[3].name(), BITWISE_BUILTIN_NAME); - assert_eq!(vm.builtin_runners[4].name(), EC_OP_BUILTIN_NAME); + assert_eq!(vm.builtin_runners[0].name(), BuiltinName::output); + assert_eq!(vm.builtin_runners[1].name(), BuiltinName::pedersen); + assert_eq!(vm.builtin_runners[2].name(), BuiltinName::range_check); + assert_eq!(vm.builtin_runners[3].name(), BuiltinName::bitwise); + assert_eq!(vm.builtin_runners[4].name(), BuiltinName::ec_op); } #[test] @@ -3863,9 +3852,7 @@ mod tests { vm.builtin_runners = vec![BuiltinRunner::Output(OutputBuiltinRunner::new(true))]; assert_eq!( cairo_runner.get_builtin_segments_info(&vm), - Err(RunnerError::NoStopPointer(Box::new( - BuiltinName::output.name() - ))), + Err(RunnerError::NoStopPointer(Box::new(BuiltinName::output))), ); } @@ -3966,10 +3953,7 @@ mod tests { Ok(ExecutionResources { n_steps: 10, n_memory_holes: 0, - builtin_instance_counter: HashMap::from([( - BuiltinName::output.name().to_string(), - 4 - )]), + builtin_instance_counter: HashMap::from([(BuiltinName::output, 4)]), }), ); } @@ -4359,14 +4343,14 @@ mod tests { let given_output = vm.get_builtin_runners(); - assert_eq!(given_output[0].name(), HASH_BUILTIN_NAME); - assert_eq!(given_output[1].name(), RANGE_CHECK_BUILTIN_NAME); - assert_eq!(given_output[2].name(), OUTPUT_BUILTIN_NAME); - assert_eq!(given_output[3].name(), SIGNATURE_BUILTIN_NAME); - assert_eq!(given_output[4].name(), BITWISE_BUILTIN_NAME); - assert_eq!(given_output[5].name(), EC_OP_BUILTIN_NAME); - assert_eq!(given_output[6].name(), KECCAK_BUILTIN_NAME); - assert_eq!(given_output[7].name(), POSEIDON_BUILTIN_NAME); + assert_eq!(given_output[0].name(), BuiltinName::pedersen); + assert_eq!(given_output[1].name(), BuiltinName::range_check); + assert_eq!(given_output[2].name(), BuiltinName::output); + assert_eq!(given_output[3].name(), BuiltinName::ecdsa); + assert_eq!(given_output[4].name(), BuiltinName::bitwise); + assert_eq!(given_output[5].name(), BuiltinName::ec_op); + assert_eq!(given_output[6].name(), BuiltinName::keccak); + assert_eq!(given_output[7].name(), BuiltinName::poseidon); } #[test] @@ -4387,14 +4371,14 @@ mod tests { let given_output = vm.get_builtin_runners(); - assert_eq!(given_output[0].name(), HASH_BUILTIN_NAME); - assert_eq!(given_output[1].name(), RANGE_CHECK_BUILTIN_NAME); - assert_eq!(given_output[2].name(), SIGNATURE_BUILTIN_NAME); - assert_eq!(given_output[3].name(), OUTPUT_BUILTIN_NAME); - assert_eq!(given_output[4].name(), BITWISE_BUILTIN_NAME); - assert_eq!(given_output[5].name(), EC_OP_BUILTIN_NAME); - assert_eq!(given_output[6].name(), KECCAK_BUILTIN_NAME); - assert_eq!(given_output[7].name(), POSEIDON_BUILTIN_NAME); + assert_eq!(given_output[0].name(), BuiltinName::pedersen); + assert_eq!(given_output[1].name(), BuiltinName::range_check); + assert_eq!(given_output[2].name(), BuiltinName::ecdsa); + assert_eq!(given_output[3].name(), BuiltinName::output); + assert_eq!(given_output[4].name(), BuiltinName::bitwise); + assert_eq!(given_output[5].name(), BuiltinName::ec_op); + assert_eq!(given_output[6].name(), BuiltinName::keccak); + assert_eq!(given_output[7].name(), BuiltinName::poseidon); } #[test] @@ -4416,14 +4400,14 @@ mod tests { let given_output = vm.get_builtin_runners(); - assert_eq!(given_output[0].name(), HASH_BUILTIN_NAME); - assert_eq!(given_output[1].name(), RANGE_CHECK_BUILTIN_NAME); - assert_eq!(given_output[2].name(), SIGNATURE_BUILTIN_NAME); - assert_eq!(given_output[3].name(), SEGMENT_ARENA_BUILTIN_NAME); - assert_eq!(given_output[4].name(), OUTPUT_BUILTIN_NAME); - assert_eq!(given_output[5].name(), BITWISE_BUILTIN_NAME); - assert_eq!(given_output[6].name(), EC_OP_BUILTIN_NAME); - assert_eq!(given_output[7].name(), KECCAK_BUILTIN_NAME); + assert_eq!(given_output[0].name(), BuiltinName::pedersen); + assert_eq!(given_output[1].name(), BuiltinName::range_check); + assert_eq!(given_output[2].name(), BuiltinName::ecdsa); + assert_eq!(given_output[3].name(), BuiltinName::segment_arena); + assert_eq!(given_output[4].name(), BuiltinName::output); + assert_eq!(given_output[5].name(), BuiltinName::bitwise); + assert_eq!(given_output[6].name(), BuiltinName::ec_op); + assert_eq!(given_output[7].name(), BuiltinName::keccak); } #[test] @@ -4440,14 +4424,14 @@ mod tests { let builtin_runners = vm.get_builtin_runners(); - assert_eq!(builtin_runners[0].name(), HASH_BUILTIN_NAME); - assert_eq!(builtin_runners[1].name(), RANGE_CHECK_BUILTIN_NAME); - assert_eq!(builtin_runners[2].name(), OUTPUT_BUILTIN_NAME); - assert_eq!(builtin_runners[3].name(), SIGNATURE_BUILTIN_NAME); - assert_eq!(builtin_runners[4].name(), BITWISE_BUILTIN_NAME); - assert_eq!(builtin_runners[5].name(), EC_OP_BUILTIN_NAME); - assert_eq!(builtin_runners[6].name(), KECCAK_BUILTIN_NAME); - assert_eq!(builtin_runners[7].name(), POSEIDON_BUILTIN_NAME); + assert_eq!(builtin_runners[0].name(), BuiltinName::pedersen); + assert_eq!(builtin_runners[1].name(), BuiltinName::range_check); + assert_eq!(builtin_runners[2].name(), BuiltinName::output); + assert_eq!(builtin_runners[3].name(), BuiltinName::ecdsa); + assert_eq!(builtin_runners[4].name(), BuiltinName::bitwise); + assert_eq!(builtin_runners[5].name(), BuiltinName::ec_op); + assert_eq!(builtin_runners[6].name(), BuiltinName::keccak); + assert_eq!(builtin_runners[7].name(), BuiltinName::poseidon); assert_eq!( cairo_runner.program_base, @@ -4480,15 +4464,15 @@ mod tests { let builtin_runners = vm.get_builtin_runners(); - assert_eq!(builtin_runners[0].name(), SEGMENT_ARENA_BUILTIN_NAME); - assert_eq!(builtin_runners[1].name(), HASH_BUILTIN_NAME); - assert_eq!(builtin_runners[2].name(), RANGE_CHECK_BUILTIN_NAME); - assert_eq!(builtin_runners[3].name(), OUTPUT_BUILTIN_NAME); - assert_eq!(builtin_runners[4].name(), SIGNATURE_BUILTIN_NAME); - assert_eq!(builtin_runners[5].name(), BITWISE_BUILTIN_NAME); - assert_eq!(builtin_runners[6].name(), EC_OP_BUILTIN_NAME); - assert_eq!(builtin_runners[7].name(), KECCAK_BUILTIN_NAME); - assert_eq!(builtin_runners[8].name(), POSEIDON_BUILTIN_NAME); + assert_eq!(builtin_runners[0].name(), BuiltinName::segment_arena); + assert_eq!(builtin_runners[1].name(), BuiltinName::pedersen); + assert_eq!(builtin_runners[2].name(), BuiltinName::range_check); + assert_eq!(builtin_runners[3].name(), BuiltinName::output); + assert_eq!(builtin_runners[4].name(), BuiltinName::ecdsa); + assert_eq!(builtin_runners[5].name(), BuiltinName::bitwise); + assert_eq!(builtin_runners[6].name(), BuiltinName::ec_op); + assert_eq!(builtin_runners[7].name(), BuiltinName::keccak); + assert_eq!(builtin_runners[8].name(), BuiltinName::poseidon); assert_eq!( cairo_runner.program_base, @@ -4516,7 +4500,7 @@ mod tests { assert_eq!( cairo_runner.initialize_builtins(&mut vm, false), Err(RunnerError::NoBuiltinForInstance(Box::new(( - HashSet::from([BuiltinName::output.name()]), + HashSet::from([BuiltinName::output]), LayoutName::plain )))) ); @@ -4531,7 +4515,7 @@ mod tests { assert_eq!( cairo_runner.initialize_builtins(&mut vm, false), Err(RunnerError::NoBuiltinForInstance(Box::new(( - HashSet::from([BuiltinName::output.name(), HASH_BUILTIN_NAME]), + HashSet::from([BuiltinName::output, BuiltinName::pedersen]), LayoutName::plain )))) ); @@ -4546,7 +4530,7 @@ mod tests { assert_eq!( cairo_runner.initialize_builtins(&mut vm, false), Err(RunnerError::NoBuiltinForInstance(Box::new(( - HashSet::from([BuiltinName::bitwise.name()]), + HashSet::from([BuiltinName::bitwise]), LayoutName::small, )))) ); @@ -4999,8 +4983,8 @@ mod tests { } fn setup_execution_resources() -> (ExecutionResources, ExecutionResources) { - let mut builtin_instance_counter: HashMap = HashMap::new(); - builtin_instance_counter.insert(BuiltinName::output.name().to_string(), 8); + let mut builtin_instance_counter: HashMap = HashMap::new(); + builtin_instance_counter.insert(BuiltinName::output, 8); let execution_resources_1 = ExecutionResources { n_steps: 100, @@ -5009,7 +4993,7 @@ mod tests { }; //Test that the combined Execution Resources only contains the shared builtins - builtin_instance_counter.insert(RANGE_CHECK_BUILTIN_NAME.to_string(), 8); + builtin_instance_counter.insert(BuiltinName::range_check, 8); let execution_resources_2 = ExecutionResources { n_steps: 100, @@ -5031,13 +5015,13 @@ mod tests { assert_eq!( combined_resources .builtin_instance_counter - .get(BuiltinName::output.name()) + .get(&BuiltinName::output) .unwrap(), &16 ); assert!(combined_resources .builtin_instance_counter - .contains_key(RANGE_CHECK_BUILTIN_NAME)); + .contains_key(&BuiltinName::range_check)); } #[test] @@ -5052,13 +5036,13 @@ mod tests { assert_eq!( combined_resources .builtin_instance_counter - .get(BuiltinName::output.name()) + .get(&BuiltinName::output) .unwrap(), &0 ); assert!(combined_resources .builtin_instance_counter - .contains_key(RANGE_CHECK_BUILTIN_NAME)); + .contains_key(&BuiltinName::range_check)); } #[test] @@ -5191,8 +5175,7 @@ mod tests { .unwrap(); vm.segments.compute_effective_sizes(); let mut exec = runner.get_execution_resources(&vm).unwrap(); - exec.builtin_instance_counter - .insert("unused_builtin".to_string(), 0); + exec.builtin_instance_counter.insert(BuiltinName::keccak, 0); assert_eq!(exec.builtin_instance_counter.len(), 5); let rsc = exec.filter_unused_builtins(); assert_eq!(rsc.builtin_instance_counter.len(), 4); @@ -5204,8 +5187,8 @@ mod tests { n_steps: 800, n_memory_holes: 0, builtin_instance_counter: HashMap::from([ - ("pedersen_builtin".to_string(), 7), - ("range_check_builtin".to_string(), 16), + (BuiltinName::pedersen, 7), + (BuiltinName::range_check, 16), ]), }; @@ -5215,8 +5198,8 @@ mod tests { n_steps: 1600, n_memory_holes: 0, builtin_instance_counter: HashMap::from([ - ("pedersen_builtin".to_string(), 14), - ("range_check_builtin".to_string(), 32) + (BuiltinName::pedersen, 14), + (BuiltinName::range_check, 32) ]) } ); @@ -5224,7 +5207,7 @@ mod tests { let execution_resources_2 = ExecutionResources { n_steps: 545, n_memory_holes: 0, - builtin_instance_counter: HashMap::from([("range_check_builtin".to_string(), 17)]), + builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 17)]), }; assert_eq!( @@ -5232,7 +5215,7 @@ mod tests { ExecutionResources { n_steps: 4360, n_memory_holes: 0, - builtin_instance_counter: HashMap::from([("range_check_builtin".to_string(), 136)]) + builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 136)]) } ); @@ -5530,14 +5513,14 @@ mod tests { ) .unwrap(); let air_private_input = runner.get_air_private_input(&vm); - assert!(air_private_input.0[HASH_BUILTIN_NAME].is_empty()); - assert!(air_private_input.0[RANGE_CHECK_BUILTIN_NAME].is_empty()); - assert!(air_private_input.0[BITWISE_BUILTIN_NAME].is_empty()); - assert!(air_private_input.0[EC_OP_BUILTIN_NAME].is_empty()); - assert!(air_private_input.0[KECCAK_BUILTIN_NAME].is_empty()); - assert!(air_private_input.0[POSEIDON_BUILTIN_NAME].is_empty()); + assert!(air_private_input.0[&BuiltinName::pedersen].is_empty()); + assert!(air_private_input.0[&BuiltinName::range_check].is_empty()); + assert!(air_private_input.0[&BuiltinName::bitwise].is_empty()); + assert!(air_private_input.0[&BuiltinName::ec_op].is_empty()); + assert!(air_private_input.0[&BuiltinName::keccak].is_empty()); + assert!(air_private_input.0[&BuiltinName::poseidon].is_empty()); assert_eq!( - air_private_input.0[SIGNATURE_BUILTIN_NAME], + air_private_input.0[&BuiltinName::ecdsa], vec![PrivateInput::Signature(PrivateInputSignature { index: 0, pubkey: felt_hex!( diff --git a/vm/src/vm/security.rs b/vm/src/vm/security.rs index 45440cfd76..b13cf33613 100644 --- a/vm/src/vm/security.rs +++ b/vm/src/vm/security.rs @@ -86,8 +86,8 @@ pub fn verify_secure_runner( mod test { use super::*; use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; - use crate::serde::deserialize_program::BuiltinName; + use crate::types::builtin_name::BuiltinName; use crate::types::relocatable::Relocatable; use crate::Felt252; diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index da21035a06..f8ba07e29c 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -1,5 +1,6 @@ use crate::math_utils::signed_felt; use crate::stdlib::{any::Any, borrow::Cow, collections::HashMap, prelude::*}; +use crate::types::builtin_name::BuiltinName; #[cfg(feature = "extensive_hints")] use crate::types::program::HintRange; use crate::{ @@ -34,10 +35,7 @@ use core::num::NonZeroUsize; use num_traits::{ToPrimitive, Zero}; use super::errors::runner_errors::RunnerError; -use super::runners::builtin_runner::{ - ModBuiltinRunner, ADD_MOD_BUILTIN_NAME, MUL_MOD_BUILTIN_NAME, OUTPUT_BUILTIN_NAME, - RC_N_PARTS_STANDARD, -}; +use super::runners::builtin_runner::{ModBuiltinRunner, RC_N_PARTS_STANDARD}; const MAX_TRACEBACK_ENTRIES: u32 = 20; @@ -1026,7 +1024,7 @@ impl VirtualMachine { let builtin = match self .builtin_runners .iter() - .find(|b| b.name() == OUTPUT_BUILTIN_NAME) + .find(|b| b.name() == BuiltinName::output) { Some(x) => x, _ => return Ok(()), @@ -1067,7 +1065,7 @@ impl VirtualMachine { #[doc(hidden)] pub fn builtins_final_stack_from_stack_pointer_dict( &mut self, - builtin_name_to_stack_pointer: &HashMap<&'static str, Relocatable>, + builtin_name_to_stack_pointer: &HashMap, skip_output: bool, ) -> Result<(), RunnerError> { for builtin in self.builtin_runners.iter_mut() { @@ -1077,7 +1075,7 @@ impl VirtualMachine { builtin.final_stack( &self.segments, builtin_name_to_stack_pointer - .get(builtin.name()) + .get(&builtin.name()) .cloned() .unwrap_or_default(), )?; @@ -1106,7 +1104,7 @@ impl VirtualMachine { batch_size: Option, ) -> Result<(), VirtualMachineError> { let fetch_builtin_params = |mod_params: Option<(Relocatable, usize)>, - mod_name: &'static str| + mod_name: BuiltinName| -> Result< Option<(Relocatable, &ModBuiltinRunner, usize)>, VirtualMachineError, @@ -1136,8 +1134,8 @@ impl VirtualMachine { ModBuiltinRunner::fill_memory( &mut self.segments.memory, - fetch_builtin_params(add_mod_ptr_n, ADD_MOD_BUILTIN_NAME)?, - fetch_builtin_params(mul_mod_ptr_n, MUL_MOD_BUILTIN_NAME)?, + fetch_builtin_params(add_mod_ptr_n, BuiltinName::add_mod)?, + fetch_builtin_params(mul_mod_ptr_n, BuiltinName::mul_mod)?, ) .map_err(VirtualMachineError::RunnerError) } @@ -1247,9 +1245,6 @@ mod tests { use crate::stdlib::collections::HashMap; use crate::types::layout_name::LayoutName; use crate::types::program::Program; - use crate::vm::runners::builtin_runner::{ - BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, - }; use crate::{ any_box, hint_processor::builtin_hint_processor::builtin_hint_processor_definition::{ @@ -3620,7 +3615,7 @@ mod tests { assert_matches!( error, Err(VirtualMachineError::InconsistentAutoDeduction(bx)) - if *bx == (EC_OP_BUILTIN_NAME, + if *bx == (BuiltinName::ec_op, MaybeRelocatable::Int(crate::felt_str!( "2739017437753868763038285897969098325279422804143820990343394856167768859289" )), @@ -3864,8 +3859,8 @@ mod tests { let builtins = vm.get_builtin_runners(); - assert_eq!(builtins[0].name(), HASH_BUILTIN_NAME); - assert_eq!(builtins[1].name(), BITWISE_BUILTIN_NAME); + assert_eq!(builtins[0].name(), BuiltinName::pedersen); + assert_eq!(builtins[1].name(), BuiltinName::bitwise); } #[test] @@ -4399,7 +4394,7 @@ mod tests { .get(0) .unwrap() .name(), - "pedersen_builtin" + BuiltinName::pedersen ); assert_eq!(virtual_machine_from_builder.run_context.ap, 18,); assert_eq!(