diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 390d212339..cf9379854f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -323,7 +323,7 @@ jobs: strategy: fail-fast: false matrix: - special_features: ["", "extensive_hints", "mod_builtin"] + special_features: ["", "mod_builtin"] target: [ test#1, test#2, test#3, test#4, test-no_std#1, test-no_std#2, test-no_std#3, test-no_std#4, test-wasm ] name: Run tests runs-on: ubuntu-22.04 @@ -569,36 +569,6 @@ jobs: path: lcov-test-no_std-.info key: codecov-cache-test-no_std--${{ github.sha }} fail-on-cache-miss: true - - name: Fetch results for tests with stdlib (w/extensive_hints; part. 1) - uses: actions/cache/restore@v3 - with: - path: lcov-test#1-extensive_hints.info - key: codecov-cache-test#1-extensive_hints-${{ github.sha }} - fail-on-cache-miss: true - - name: Fetch results for tests with stdlib (w/extensive_hints; part. 2) - uses: actions/cache/restore@v3 - with: - path: lcov-test#2-extensive_hints.info - key: codecov-cache-test#2-extensive_hints-${{ github.sha }} - fail-on-cache-miss: true - - name: Fetch results for tests with stdlib (w/extensive_hints; part. 3) - uses: actions/cache/restore@v3 - with: - path: lcov-test#3-extensive_hints.info - key: codecov-cache-test#3-extensive_hints-${{ github.sha }} - fail-on-cache-miss: true - - name: Fetch results for tests with stdlib (w/extensive_hints; part. 4) - uses: actions/cache/restore@v3 - with: - path: lcov-test#4-extensive_hints.info - key: codecov-cache-test#4-extensive_hints-${{ github.sha }} - fail-on-cache-miss: true - - name: Fetch results for tests without stdlib (w/extensive_hints) - uses: actions/cache/restore@v3 - with: - path: lcov-no_std-extensive_hints.info - key: codecov-cache-test-no_std-extensive_hints-${{ github.sha }} - fail-on-cache-miss: true - name: Upload coverage to codecov.io diff --git a/Cargo.lock b/Cargo.lock index 37d463148d..cccaa891f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,11 +41,12 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.9" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d713b3834d76b85304d4d525563c1276e2e30dc97cc67bfb4585a4a29fc2c89f" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -904,6 +905,7 @@ dependencies = [ name = "cairo-vm" version = "1.0.0-rc2" dependencies = [ + "ahash 0.8.11", "anyhow", "arbitrary", "ark-ff", @@ -1602,7 +1604,7 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ - "ahash 0.8.9", + "ahash 0.8.11", "allocator-api2", "serde", ] diff --git a/vm/Cargo.toml b/vm/Cargo.toml index 5f6bc49c16..5e2222ade4 100644 --- a/vm/Cargo.toml +++ b/vm/Cargo.toml @@ -32,11 +32,9 @@ mod_builtin = [] # Note that these features are not retro-compatible with the cairo Python VM. test_utils = ["std", "dep:arbitrary", "starknet-types-core/arbitrary", "starknet-types-core/std"] # This feature will reference every test-oriented feature -# Allows extending the set of hints for the current vm run from within a hint. -# For a usage example checkout vm/src/tests/run_deprecated_contract_class_simplified.rs -extensive_hints = [] [dependencies] +ahash = { version = "0.8.11", default-features = false, features = ["runtime-rng"] } zip = {version = "0.6.6", optional = true } num-bigint = { workspace = true } rand = { workspace = true } diff --git a/vm/src/hint_processor/hint_processor_definition.rs b/vm/src/hint_processor/hint_processor_definition.rs index 496e8b1428..309d78fc39 100644 --- a/vm/src/hint_processor/hint_processor_definition.rs +++ b/vm/src/hint_processor/hint_processor_definition.rs @@ -20,7 +20,7 @@ use arbitrary::Arbitrary; pub trait HintProcessorLogic { // Executes the hint which's data is provided by a dynamic structure previously created by compile_hint - // Note: if the `extensive_hints` feature is activated the method used by the vm to execute hints is `execute_hint_extensive`, which's default implementation calls this method. + // Note: the method used by the vm to execute hints is `execute_hint_extensive`, which's default implementation calls this method. fn execute_hint( &mut self, vm: &mut VirtualMachine, @@ -51,7 +51,6 @@ pub trait HintProcessorLogic { })) } - #[cfg(feature = "extensive_hints")] // Executes the hint which's data is provided by a dynamic structure previously created by compile_hint // Also returns a map of hints to be loaded after the current hint is executed // Note: This is the method used by the vm to execute hints, diff --git a/vm/src/tests/run_deprecated_contract_class_simplified.rs b/vm/src/tests/run_deprecated_contract_class_simplified.rs index 6a46e46cb4..1508334f8d 100644 --- a/vm/src/tests/run_deprecated_contract_class_simplified.rs +++ b/vm/src/tests/run_deprecated_contract_class_simplified.rs @@ -1,4 +1,3 @@ -#![cfg(feature = "extensive_hints")] /* This file contains a test that runs the program: cairo_programs/starknet_os_deprecated_cc.cairo For testsing purposes, the contract ran by this program is hardcoded, with values taken from compiling: diff --git a/vm/src/types/program.rs b/vm/src/types/program.rs index 0fc8c6dc83..030f09ff16 100644 --- a/vm/src/types/program.rs +++ b/vm/src/types/program.rs @@ -33,7 +33,6 @@ use core::num::NonZeroUsize; use std::path::Path; use super::builtin_name::BuiltinName; -#[cfg(feature = "extensive_hints")] use super::relocatable::Relocatable; #[cfg(feature = "test_utils")] use arbitrary::{Arbitrary, Unstructured}; @@ -110,10 +109,7 @@ impl<'a> Arbitrary<'a> for SharedProgramData { pub(crate) struct HintsCollection { hints: Vec, /// This maps a PC to the range of hints in `hints` that correspond to it. - #[cfg(not(feature = "extensive_hints"))] - pub(crate) hints_ranges: Vec, - #[cfg(feature = "extensive_hints")] - pub(crate) hints_ranges: HashMap, + pub(crate) hints_ranges: HashMap, } impl HintsCollection { @@ -138,20 +134,13 @@ impl HintsCollection { } let mut hints_values = Vec::with_capacity(full_len); - #[cfg(not(feature = "extensive_hints"))] - let mut hints_ranges = vec![None; max_hint_pc + 1]; - #[cfg(feature = "extensive_hints")] let mut hints_ranges = HashMap::default(); + for (pc, hs) in hints.iter().filter(|(_, hs)| !hs.is_empty()) { let range = ( hints_values.len(), NonZeroUsize::new(hs.len()).expect("empty vecs already filtered"), ); - #[cfg(not(feature = "extensive_hints"))] - { - hints_ranges[*pc] = Some(range); - } - #[cfg(feature = "extensive_hints")] hints_ranges.insert(Relocatable::from((0_isize, *pc)), range); hints_values.extend_from_slice(&hs[..]); } @@ -165,24 +154,11 @@ impl HintsCollection { pub fn iter_hints(&self) -> impl Iterator { self.hints.iter() } - - #[cfg(not(feature = "extensive_hints"))] - pub fn get_hint_range_for_pc(&self, pc: usize) -> Option { - self.hints_ranges.get(pc).cloned() - } } impl From<&HintsCollection> for BTreeMap> { fn from(hc: &HintsCollection) -> Self { let mut hint_map = BTreeMap::new(); - #[cfg(not(feature = "extensive_hints"))] - for (i, r) in hc.hints_ranges.iter().enumerate() { - let Some(r) = r else { - continue; - }; - hint_map.insert(i, hc.hints[r.0..r.0 + r.1.get()].to_owned()); - } - #[cfg(feature = "extensive_hints")] for (pc, r) in hc.hints_ranges.iter() { hint_map.insert(pc.offset, hc.hints[r.0..r.0 + r.1.get()].to_owned()); } @@ -191,10 +167,6 @@ impl From<&HintsCollection> for BTreeMap> { } /// Represents a range of hints corresponding to a PC as a tuple `(start, length)`. -#[cfg(not(feature = "extensive_hints"))] -/// Is [`None`] if the range is empty, and it is [`Some`] tuple `(start, length)` otherwise. -type HintRange = Option<(usize, NonZeroUsize)>; -#[cfg(feature = "extensive_hints")] pub type HintRange = (usize, NonZeroUsize); #[cfg_attr(feature = "test_utils", derive(Arbitrary))] @@ -475,22 +447,6 @@ impl TryFrom for Program { #[cfg(test)] impl HintsCollection { pub fn iter(&self) -> impl Iterator { - #[cfg(not(feature = "extensive_hints"))] - let iter = self - .hints_ranges - .iter() - .enumerate() - .filter_map(|(pc, range)| { - range.and_then(|(start, len)| { - let end = start + len.get(); - if end <= self.hints.len() { - Some((pc, &self.hints[start..end])) - } else { - None - } - }) - }); - #[cfg(feature = "extensive_hints")] let iter = self.hints_ranges.iter().filter_map(|(pc, (start, len))| { let end = start + len.get(); if end <= self.hints.len() { @@ -554,11 +510,10 @@ mod tests { program.shared_program_data.hints_collection.hints, Vec::new() ); - assert!(program - .shared_program_data - .hints_collection - .hints_ranges - .is_empty()); + assert_eq!( + program.shared_program_data.hints_collection.hints_ranges, + HashMap::default() + ); } #[test] @@ -601,11 +556,10 @@ mod tests { program.shared_program_data.hints_collection.hints, Vec::new() ); - assert!(program - .shared_program_data - .hints_collection - .hints_ranges - .is_empty()); + assert_eq!( + program.shared_program_data.hints_collection.hints_ranges, + HashMap::default() + ); } #[test] @@ -660,22 +614,6 @@ mod tests { assert_eq!(program.shared_program_data.main, None); assert_eq!(program.shared_program_data.identifiers, HashMap::new()); - #[cfg(not(feature = "extensive_hints"))] - let program_hints: HashMap<_, _> = program - .shared_program_data - .hints_collection - .hints_ranges - .iter() - .enumerate() - .filter_map(|(pc, r)| r.map(|(s, l)| (pc, (s, s + l.get())))) - .map(|(pc, (s, e))| { - ( - pc, - program.shared_program_data.hints_collection.hints[s..e].to_vec(), - ) - }) - .collect(); - #[cfg(feature = "extensive_hints")] let program_hints: HashMap<_, _> = program .shared_program_data .hints_collection diff --git a/vm/src/types/relocatable.rs b/vm/src/types/relocatable.rs index 4631a79b4b..bf01c05e7e 100644 --- a/vm/src/types/relocatable.rs +++ b/vm/src/types/relocatable.rs @@ -1,5 +1,6 @@ use crate::stdlib::{ fmt::{self, Display}, + hash::{Hash, Hasher}, ops::{Add, AddAssign, Sub}, prelude::*, }; @@ -15,14 +16,18 @@ use serde::{Deserialize, Serialize}; use arbitrary::Arbitrary; #[cfg_attr(feature = "test_utils", derive(Arbitrary))] -#[derive( - Eq, Ord, Hash, PartialEq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize, Default, -)] +#[derive(Eq, Ord, PartialEq, PartialOrd, Clone, Copy, Debug, Serialize, Deserialize, Default)] pub struct Relocatable { pub segment_index: isize, pub offset: usize, } +impl Hash for Relocatable { + fn hash(&self, state: &mut H) { + (((self.segment_index as i64) << 48) | (self.offset as i64)).hash(state); + } +} + #[cfg_attr(feature = "test_utils", derive(Arbitrary))] #[derive(Eq, Ord, Hash, PartialEq, PartialOrd, Clone, Serialize, Deserialize)] pub enum MaybeRelocatable { diff --git a/vm/src/vm/runners/cairo_runner.rs b/vm/src/vm/runners/cairo_runner.rs index 9592d77f2a..2d6bbc80dc 100644 --- a/vm/src/vm/runners/cairo_runner.rs +++ b/vm/src/vm/runners/cairo_runner.rs @@ -661,11 +661,7 @@ impl CairoRunner { hint_processor: &mut dyn HintProcessor, ) -> Result<(), VirtualMachineError> { let references = &self.program.shared_program_data.reference_manager; - #[cfg(not(feature = "extensive_hints"))] - let hint_data = self.get_hint_data(references, hint_processor)?; - #[cfg(feature = "extensive_hints")] let mut hint_data = self.get_hint_data(references, hint_processor)?; - #[cfg(feature = "extensive_hints")] let mut hint_ranges = self .program .shared_program_data @@ -678,18 +674,7 @@ impl CairoRunner { vm.step( hint_processor, &mut self.exec_scopes, - #[cfg(feature = "extensive_hints")] &mut hint_data, - #[cfg(not(feature = "extensive_hints"))] - self.program - .shared_program_data - .hints_collection - .get_hint_range_for_pc(vm.run_context.pc.offset) - .and_then(|range| { - range.and_then(|(start, length)| hint_data.get(start..start + length.get())) - }) - .unwrap_or(&[]), - #[cfg(feature = "extensive_hints")] &mut hint_ranges, &self.program.constants, )?; @@ -712,27 +697,13 @@ impl CairoRunner { hint_processor: &mut dyn HintProcessor, ) -> Result<(), VirtualMachineError> { let references = &self.program.shared_program_data.reference_manager; - #[cfg(not(feature = "extensive_hints"))] - let hint_data = self.get_hint_data(references, hint_processor)?; - #[cfg(feature = "extensive_hints")] let mut hint_data = self.get_hint_data(references, hint_processor)?; - #[cfg(feature = "extensive_hints")] let mut hint_ranges = self .program .shared_program_data .hints_collection .hints_ranges .clone(); - #[cfg(not(feature = "extensive_hints"))] - let hint_data = &self - .program - .shared_program_data - .hints_collection - .get_hint_range_for_pc(vm.run_context.pc.offset) - .and_then(|range| { - range.and_then(|(start, length)| hint_data.get(start..start + length.get())) - }) - .unwrap_or(&[]); for remaining_steps in (1..=steps).rev() { if self.final_pc.as_ref() == Some(&vm.run_context.pc) { @@ -742,11 +713,7 @@ impl CairoRunner { vm.step( hint_processor, &mut self.exec_scopes, - #[cfg(feature = "extensive_hints")] &mut hint_data, - #[cfg(not(feature = "extensive_hints"))] - hint_data, - #[cfg(feature = "extensive_hints")] &mut hint_ranges, &self.program.constants, )?; diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 34cccf7438..a89ce82651 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -1,7 +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::{ hint_processor::hint_processor_definition::HintProcessor, @@ -30,7 +29,6 @@ use crate::{ use crate::Felt252; use core::cmp::Ordering; -#[cfg(feature = "extensive_hints")] use core::num::NonZeroUsize; use num_traits::{ToPrimitive, Zero}; @@ -454,29 +452,12 @@ impl VirtualMachine { decode_instruction(instruction) } - #[cfg(not(feature = "extensive_hints"))] - pub fn step_hint( - &mut self, - 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) - .map_err(|err| VirtualMachineError::Hint(Box::new((hint_index, err))))? - } - Ok(()) - } - - #[cfg(feature = "extensive_hints")] pub fn step_hint( &mut self, hint_processor: &mut dyn HintProcessor, exec_scopes: &mut ExecutionScopes, hint_datas: &mut Vec>, - hint_ranges: &mut HashMap, + hint_ranges: &mut HashMap, constants: &HashMap, ) -> Result<(), VirtualMachineError> { // Check if there is a hint range for the current pc @@ -548,16 +529,14 @@ impl VirtualMachine { &mut self, hint_processor: &mut dyn HintProcessor, exec_scopes: &mut ExecutionScopes, - #[cfg(feature = "extensive_hints")] hint_datas: &mut Vec>, - #[cfg(not(feature = "extensive_hints"))] hint_datas: &[Box], - #[cfg(feature = "extensive_hints")] hint_ranges: &mut HashMap, + hint_datas: &mut Vec>, + hint_ranges: &mut HashMap, constants: &HashMap, ) -> Result<(), VirtualMachineError> { self.step_hint( hint_processor, exec_scopes, hint_datas, - #[cfg(feature = "extensive_hints")] hint_ranges, constants, )?; @@ -2792,8 +2771,7 @@ mod tests { &mut hint_processor, exec_scopes_ref!(), &mut Vec::new(), - #[cfg(feature = "extensive_hints")] - &mut HashMap::new(), + &mut HashMap::default(), &HashMap::new(), ), Ok(()) @@ -3023,8 +3001,7 @@ mod tests { &mut hint_processor, exec_scopes_ref!(), &mut Vec::new(), - #[cfg(feature = "extensive_hints")] - &mut HashMap::new(), + &mut HashMap::default(), &HashMap::new(), ), Ok(()) @@ -3107,8 +3084,7 @@ mod tests { &mut hint_processor, exec_scopes_ref!(), &mut Vec::new(), - #[cfg(feature = "extensive_hints")] - &mut HashMap::new(), + &mut HashMap::default(), &HashMap::new() ), Ok(()) @@ -3211,8 +3187,7 @@ mod tests { &mut hint_processor, exec_scopes_ref!(), &mut Vec::new(), - #[cfg(feature = "extensive_hints")] - &mut HashMap::new(), + &mut HashMap::default(), &HashMap::new() ), Ok(()) @@ -3234,8 +3209,7 @@ mod tests { &mut hint_processor, exec_scopes_ref!(), &mut Vec::new(), - #[cfg(feature = "extensive_hints")] - &mut HashMap::new(), + &mut HashMap::default(), &HashMap::new() ), Ok(()) @@ -3258,8 +3232,7 @@ mod tests { &mut hint_processor, exec_scopes_ref!(), &mut Vec::new(), - #[cfg(feature = "extensive_hints")] - &mut HashMap::new(), + &mut HashMap::default(), &HashMap::new() ), Ok(()) @@ -3814,23 +3787,15 @@ mod tests { ((1, 1), (3, 0)) ]; - #[cfg(feature = "extensive_hints")] let mut hint_data = hint_data; //Run Steps for _ in 0..6 { - #[cfg(not(feature = "extensive_hints"))] - let mut hint_data = if vm.run_context.pc == (0, 0).into() { - &hint_data[0..] - } else { - &hint_data[0..0] - }; assert_matches!( vm.step( &mut hint_processor, exec_scopes_ref!(), &mut hint_data, - #[cfg(feature = "extensive_hints")] &mut HashMap::from([( Relocatable::from((0, 0)), (0_usize, NonZeroUsize::new(1).unwrap()) @@ -4483,8 +4448,7 @@ mod tests { &mut hint_processor, exec_scopes_ref!(), &mut Vec::new(), - #[cfg(feature = "extensive_hints")] - &mut HashMap::new(), + &mut HashMap::default(), &HashMap::new() ), Ok(()) @@ -4570,8 +4534,7 @@ mod tests { &mut hint_processor, exec_scopes_ref!(), &mut Vec::new(), - #[cfg(feature = "extensive_hints")] - &mut HashMap::new(), + &mut HashMap::default(), &HashMap::new() ), Ok(())