diff --git a/CHANGELOG.md b/CHANGELOG.md index e763405473..4c29a4c8b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* breaking: Store constants in Hint Data [#2191](https://github.com/lambdaclass/cairo-vm/pull/2191) + #### [3.0.0-rc.3] - 2025-26-08 * chore: Bump types-rs to 0.2.0 [#2183](https://github.com/lambdaclass/cairo-vm/pull/2183) diff --git a/hint_accountant/src/main.rs b/hint_accountant/src/main.rs index 83800a423d..c694245a43 100644 --- a/hint_accountant/src/main.rs +++ b/hint_accountant/src/main.rs @@ -51,19 +51,11 @@ fn run() { } let mut vm = VirtualMachine::new(false, false); let mut hint_executor = BuiltinHintProcessor::new_empty(); - let ( - ap_tracking_data, - reference_ids, - references, - mut exec_scopes, - constants, - accessible_scopes, - ) = ( + let (ap_tracking_data, reference_ids, references, mut exec_scopes, accessible_scopes) = ( ApTracking::default(), HashMap::new(), Vec::new(), ExecutionScopes::new(), - HashMap::new(), Vec::new(), ); let missing_hints: HashSet<_> = whitelists @@ -78,10 +70,11 @@ fn run() { &reference_ids, &references, &accessible_scopes, + Default::default(), ) .expect("this implementation is infallible"); matches!( - hint_executor.execute_hint(&mut vm, &mut exec_scopes, &hint_data, &constants,), + hint_executor.execute_hint(&mut vm, &mut exec_scopes, &hint_data), Err(HintError::UnknownHint(_)), ) }) diff --git a/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index def35751ef..029b9dfa3e 100644 --- a/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/vm/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -133,6 +133,7 @@ pub struct HintProcessorData { pub ap_tracking: ApTracking, pub ids_data: HashMap, pub accessible_scopes: Vec, + pub constants: Rc>, } impl HintProcessorData { @@ -142,6 +143,7 @@ impl HintProcessorData { ap_tracking: ApTracking::default(), ids_data, accessible_scopes: vec![], + constants: Default::default(), } } } @@ -189,11 +191,11 @@ impl HintProcessorLogic for BuiltinHintProcessor { vm: &mut VirtualMachine, exec_scopes: &mut ExecutionScopes, hint_data: &Box, - constants: &HashMap, ) -> Result<(), HintError> { let hint_data = hint_data .downcast_ref::() .ok_or(HintError::WrongHintData)?; + let constants = hint_data.constants.as_ref(); if let Some(hint_func) = self.extra_hints.get(&hint_data.code) { return hint_func.0( @@ -1466,24 +1468,14 @@ mod tests { let hint_data = HintProcessorData::new_default(String::from("enter_scope_custom_a"), HashMap::new()); assert_matches!( - hint_processor.execute_hint( - &mut vm, - exec_scopes, - &any_box!(hint_data), - &HashMap::new(), - ), + hint_processor.execute_hint(&mut vm, exec_scopes, &any_box!(hint_data)), Ok(()) ); assert_eq!(exec_scopes.data.len(), 2); let hint_data = HintProcessorData::new_default(String::from("enter_scope_custom_a"), HashMap::new()); assert_matches!( - hint_processor.execute_hint( - &mut vm, - exec_scopes, - &any_box!(hint_data), - &HashMap::new(), - ), + hint_processor.execute_hint(&mut vm, exec_scopes, &any_box!(hint_data)), Ok(()) ); assert_eq!(exec_scopes.data.len(), 3); diff --git a/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs b/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs index e79fcdbfab..4f5c99faec 100644 --- a/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs +++ b/vm/src/hint_processor/cairo_1_hint_processor/hint_processor.rs @@ -9,6 +9,7 @@ use super::hint_processor_utils::*; use crate::any_box; use crate::hint_processor::cairo_1_hint_processor::dict_manager::DictSquashExecScope; use crate::hint_processor::hint_processor_definition::HintReference; +use crate::stdlib::rc::Rc; use crate::stdlib::{boxed::Box, collections::HashMap, prelude::*}; use crate::types::relocatable::{MaybeRelocatable, Relocatable}; use crate::vm::runners::cairo_runner::ResourceTracker; @@ -1265,6 +1266,8 @@ impl HintProcessorLogic for Cairo1HintProcessor { _references: &[HintReference], // List of accessible scopes in the hint _accessible_scopes: &[String], + // Identifiers stored in the hint's program. + _constants: Rc>, ) -> Result, VirtualMachineError> { let data = hint_code.parse().ok().and_then(|x: usize| self.hints.get(&x).cloned()) .ok_or_else(|| VirtualMachineError::CompileHintFail( @@ -1284,8 +1287,6 @@ impl HintProcessorLogic for Cairo1HintProcessor { exec_scopes: &mut ExecutionScopes, //Data structure that can be downcasted to the structure generated by compile_hint hint_data: &Box, - //Constant values extracted from the program specification. - _constants: &HashMap, ) -> Result<(), HintError> { let hints: &Vec = hint_data.downcast_ref().ok_or(HintError::WrongHintData)?; for hint in hints { diff --git a/vm/src/hint_processor/hint_processor_definition.rs b/vm/src/hint_processor/hint_processor_definition.rs index dbd4a8389c..293642b0b0 100644 --- a/vm/src/hint_processor/hint_processor_definition.rs +++ b/vm/src/hint_processor/hint_processor_definition.rs @@ -1,4 +1,4 @@ -use crate::stdlib::{any::Any, boxed::Box, collections::HashMap, prelude::*}; +use crate::stdlib::{any::Any, boxed::Box, collections::HashMap, prelude::*, rc::Rc}; use crate::any_box; use crate::serde::deserialize_program::ApTracking; @@ -27,8 +27,6 @@ pub trait HintProcessorLogic { exec_scopes: &mut ExecutionScopes, //Data structure that can be downcasted to the structure generated by compile_hint hint_data: &Box, - //Constant values extracted from the program specification. - constants: &HashMap, ) -> Result<(), HintError>; //Transforms hint data outputed by the VM into whichever format will be later used by execute_hint @@ -45,12 +43,15 @@ pub trait HintProcessorLogic { references: &[HintReference], // List of accessible scopes in the hint accessible_scopes: &[String], + // Identifiers stored in the hint's program. + constants: Rc>, ) -> Result, VirtualMachineError> { Ok(any_box!(HintProcessorData { code: hint_code.to_string(), ap_tracking: ap_tracking_data.clone(), ids_data: get_ids_data(reference_ids, references)?, accessible_scopes: accessible_scopes.to_vec(), + constants, })) } @@ -65,10 +66,8 @@ pub trait HintProcessorLogic { exec_scopes: &mut ExecutionScopes, //Data structure that can be downcasted to the structure generated by compile_hint hint_data: &Box, - //Constant values extracted from the program specification. - constants: &HashMap, ) -> Result { - self.execute_hint(vm, exec_scopes, hint_data, constants)?; + self.execute_hint(vm, exec_scopes, hint_data)?; Ok(HintExtension::default()) } } diff --git a/vm/src/tests/run_deprecated_contract_class_simplified.rs b/vm/src/tests/run_deprecated_contract_class_simplified.rs index d3c07b02a2..888e9f35bd 100644 --- a/vm/src/tests/run_deprecated_contract_class_simplified.rs +++ b/vm/src/tests/run_deprecated_contract_class_simplified.rs @@ -80,8 +80,6 @@ impl HintProcessorLogic for SimplifiedOsHintProcessor { _exec_scopes: &mut crate::types::exec_scope::ExecutionScopes, //Data structure that can be downcasted to the structure generated by compile_hint _hint_data: &Box, - //Constant values extracted from the program specification. - _constants: &HashMap, ) -> Result<(), crate::vm::errors::hint_errors::HintError> { // Empty impl as we are using `execute_hint_extensive` instead for this case Ok(()) @@ -93,19 +91,15 @@ impl HintProcessorLogic for SimplifiedOsHintProcessor { exec_scopes: &mut crate::types::exec_scope::ExecutionScopes, //Data structure that can be downcasted to the structure generated by compile_hint hint_data: &Box, - //Constant values extracted from the program specification. - constants: &HashMap, ) -> Result< crate::hint_processor::hint_processor_definition::HintExtension, crate::vm::errors::hint_errors::HintError, > { // First attempt to execute with builtin hint processor - match self.builtin_hint_processor.execute_hint_extensive( - vm, - exec_scopes, - hint_data, - constants, - ) { + match self + .builtin_hint_processor + .execute_hint_extensive(vm, exec_scopes, hint_data) + { Err(HintError::UnknownHint(_)) => {} res => return res, } @@ -307,6 +301,7 @@ pub fn vm_load_program( &reference_ids, &references, &accessible_scopes, + Default::default(), )?; // Create the hint extension // As the hint from the compiled constract has offset 0, the hint pc will be equal to the loaded contract's program base: diff --git a/vm/src/utils.rs b/vm/src/utils.rs index 6a6a284ee6..6824252fe2 100644 --- a/vm/src/utils.rs +++ b/vm/src/utils.rs @@ -474,9 +474,11 @@ pub mod test_utils { macro_rules! run_hint { ($vm:expr, $ids_data:expr, $hint_code:expr, $exec_scopes:expr, $constants:expr) => {{ - let hint_data = HintProcessorData::new_default($hint_code.to_string(), $ids_data); + let mut hint_data = HintProcessorData::new_default($hint_code.to_string(), $ids_data); + let constants: &HashMap = $constants; + hint_data.constants = crate::stdlib::rc::Rc::new(constants.clone()); let mut hint_processor = BuiltinHintProcessor::new_empty(); - hint_processor.execute_hint(&mut $vm, $exec_scopes, &any_box!(hint_data), $constants) + hint_processor.execute_hint(&mut $vm, $exec_scopes, &any_box!(hint_data)) }}; ($vm:expr, $ids_data:expr, $hint_code:expr, $exec_scopes:expr) => {{ let hint_data = HintProcessorData::new_default( @@ -484,12 +486,7 @@ pub mod test_utils { $ids_data, ); let mut hint_processor = BuiltinHintProcessor::new_empty(); - hint_processor.execute_hint( - &mut $vm, - $exec_scopes, - &any_box!(hint_data), - &crate::stdlib::collections::HashMap::new(), - ) + hint_processor.execute_hint(&mut $vm, $exec_scopes, &any_box!(hint_data)) }}; ($vm:expr, $ids_data:expr, $hint_code:expr) => {{ let hint_data = HintProcessorData::new_default( @@ -497,12 +494,7 @@ pub mod test_utils { $ids_data, ); let mut hint_processor = BuiltinHintProcessor::new_empty(); - hint_processor.execute_hint( - &mut $vm, - exec_scopes_ref!(), - &any_box!(hint_data), - &crate::stdlib::collections::HashMap::new(), - ) + hint_processor.execute_hint(&mut $vm, exec_scopes_ref!(), &any_box!(hint_data)) }}; } pub(crate) use run_hint; diff --git a/vm/src/vm/runners/cairo_runner.rs b/vm/src/vm/runners/cairo_runner.rs index 435671c05e..439e3596f5 100644 --- a/vm/src/vm/runners/cairo_runner.rs +++ b/vm/src/vm/runners/cairo_runner.rs @@ -1,4 +1,5 @@ use crate::vm::trace::trace_entry::TraceEntry; + use crate::{ air_private_input::AirPrivateInput, air_public_input::{PublicInput, PublicInputError}, @@ -8,6 +9,7 @@ use crate::{ collections::{BTreeMap, HashMap, HashSet}, ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign}, prelude::*, + rc::Rc, }, types::{builtin_name::BuiltinName, layout::CairoLayoutParams, layout_name::LayoutName}, vm::{ @@ -646,6 +648,8 @@ impl CairoRunner { references: &[HintReference], hint_executor: &mut dyn HintProcessor, ) -> Result>, VirtualMachineError> { + let constants = Rc::new(self.program.constants.clone()); + self.program .shared_program_data .hints_collection @@ -658,6 +662,7 @@ impl CairoRunner { &hint.flow_tracking_data.reference_ids, references, &hint.accessible_scopes, + constants.clone(), ) .map_err(|_| VirtualMachineError::CompileHintFail(hint.code.clone().into())) }) @@ -708,6 +713,7 @@ impl CairoRunner { .unwrap_or(&[]), #[cfg(feature = "extensive_hints")] &mut hint_ranges, + #[cfg(feature = "test_utils")] &self.program.constants, )?; @@ -764,6 +770,7 @@ impl CairoRunner { hint_data, #[cfg(feature = "extensive_hints")] &mut hint_ranges, + #[cfg(feature = "test_utils")] &self.program.constants, )?; } diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index c073b5a73a..8afc9628be 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -536,11 +536,10 @@ impl VirtualMachine { hint_processor: &mut dyn HintProcessor, exec_scopes: &mut ExecutionScopes, hint_datas: &[Box], - constants: &HashMap, ) -> Result<(), VirtualMachineError> { for (hint_index, hint_data) in hint_datas.iter().enumerate() { hint_processor - .execute_hint(self, exec_scopes, hint_data, constants) + .execute_hint(self, exec_scopes, hint_data) .map_err(|err| VirtualMachineError::Hint(Box::new((hint_index, err))))? } Ok(()) @@ -553,7 +552,6 @@ impl VirtualMachine { exec_scopes: &mut ExecutionScopes, hint_datas: &mut Vec>, hint_ranges: &mut HashMap, - constants: &HashMap, ) -> Result<(), VirtualMachineError> { // Check if there is a hint range for the current pc if let Some((s, l)) = hint_ranges.get(&self.run_context.pc) { @@ -566,7 +564,6 @@ impl VirtualMachine { self, exec_scopes, hint_datas.get(idx).ok_or(VirtualMachineError::Unexpected)?, - constants, ) .map_err(|err| VirtualMachineError::Hint(Box::new((idx - s, err))))?; // Update the hint_ranges & hint_datas with the hints added by the executed hint @@ -627,7 +624,7 @@ impl VirtualMachine { #[cfg(feature = "extensive_hints")] hint_datas: &mut Vec>, #[cfg(not(feature = "extensive_hints"))] hint_datas: &[Box], #[cfg(feature = "extensive_hints")] hint_ranges: &mut HashMap, - constants: &HashMap, + #[cfg(feature = "test_utils")] constants: &HashMap, ) -> Result<(), VirtualMachineError> { self.step_hint( hint_processor, @@ -635,7 +632,6 @@ impl VirtualMachine { hint_datas, #[cfg(feature = "extensive_hints")] hint_ranges, - constants, )?; #[cfg(feature = "test_utils")] @@ -3338,6 +3334,7 @@ mod tests { &mut Vec::new(), #[cfg(feature = "extensive_hints")] &mut HashMap::new(), + #[cfg(feature = "test_utils")] &HashMap::new(), ), Ok(()) @@ -3575,6 +3572,7 @@ mod tests { &mut Vec::new(), #[cfg(feature = "extensive_hints")] &mut HashMap::new(), + #[cfg(feature = "test_utils")] &HashMap::new(), ), Ok(()) @@ -3659,6 +3657,7 @@ mod tests { &mut Vec::new(), #[cfg(feature = "extensive_hints")] &mut HashMap::new(), + #[cfg(feature = "test_utils")] &HashMap::new() ), Ok(()) @@ -3763,6 +3762,7 @@ mod tests { &mut Vec::new(), #[cfg(feature = "extensive_hints")] &mut HashMap::new(), + #[cfg(feature = "test_utils")] &HashMap::new() ), Ok(()) @@ -3786,6 +3786,7 @@ mod tests { &mut Vec::new(), #[cfg(feature = "extensive_hints")] &mut HashMap::new(), + #[cfg(feature = "test_utils")] &HashMap::new() ), Ok(()) @@ -3810,6 +3811,7 @@ mod tests { &mut Vec::new(), #[cfg(feature = "extensive_hints")] &mut HashMap::new(), + #[cfg(feature = "test_utils")] &HashMap::new() ), Ok(()) @@ -4387,6 +4389,7 @@ mod tests { Relocatable::from((0, 0)), (0_usize, NonZeroUsize::new(1).unwrap()) )]), + #[cfg(feature = "test_utils")] &HashMap::new(), ), Ok(()) @@ -5332,6 +5335,7 @@ mod tests { &mut Vec::new(), #[cfg(feature = "extensive_hints")] &mut HashMap::new(), + #[cfg(feature = "test_utils")] &HashMap::new() ), Ok(()) @@ -5419,6 +5423,7 @@ mod tests { &mut Vec::new(), #[cfg(feature = "extensive_hints")] &mut HashMap::new(), + #[cfg(feature = "test_utils")] &HashMap::new() ), Ok(())