diff --git a/.gitignore b/.gitignore index c2c0ebea83..2e1f8ff93e 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ **/*.memory **/*.air_public_input **/*.air_private_input +**/*.pie.zip **/*.swp bench/results .python-version diff --git a/CHANGELOG.md b/CHANGELOG.md index cfa56b1389..be9dd49bb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* feat: Add zero segment [#1668](https://github.com/lambdaclass/cairo-vm/pull/1668) + * feat: Bump cairo_lang to 0.13.1 in testing env [#1687](https://github.com/lambdaclass/cairo-vm/pull/1687) * feat(BREAKING): Use return type info from sierra when serializing return values in cairo1-run crate [#1665](https://github.com/lambdaclass/cairo-vm/pull/1665) diff --git a/vm/src/hint_processor/builtin_hint_processor/bigint.rs b/vm/src/hint_processor/builtin_hint_processor/bigint.rs index 2069446fb7..ff5326bd58 100644 --- a/vm/src/hint_processor/builtin_hint_processor/bigint.rs +++ b/vm/src/hint_processor/builtin_hint_processor/bigint.rs @@ -103,7 +103,6 @@ mod test { use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; use crate::hint_processor::builtin_hint_processor::hint_code; use crate::hint_processor::hint_processor_definition::{HintProcessorLogic, HintReference}; - use crate::stdlib::collections::HashMap; use crate::types::exec_scope::ExecutionScopes; use crate::utils::test_utils::*; use crate::vm::vm_core::VirtualMachine; diff --git a/vm/src/hint_processor/builtin_hint_processor/poseidon_utils.rs b/vm/src/hint_processor/builtin_hint_processor/poseidon_utils.rs index e33f35af61..02a6dd7f25 100644 --- a/vm/src/hint_processor/builtin_hint_processor/poseidon_utils.rs +++ b/vm/src/hint_processor/builtin_hint_processor/poseidon_utils.rs @@ -57,7 +57,6 @@ mod tests { use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::HintProcessorData; use crate::hint_processor::hint_processor_definition::HintProcessorLogic; use crate::hint_processor::hint_processor_definition::HintReference; - use crate::stdlib::collections::HashMap; use crate::types::exec_scope::ExecutionScopes; use crate::vm::vm_core::VirtualMachine; diff --git a/vm/src/hint_processor/hint_processor_utils.rs b/vm/src/hint_processor/hint_processor_utils.rs index b78c7c9a79..69944d8669 100644 --- a/vm/src/hint_processor/hint_processor_utils.rs +++ b/vm/src/hint_processor/hint_processor_utils.rs @@ -179,7 +179,6 @@ fn get_offset_value_reference( #[cfg(test)] mod tests { use super::*; - use crate::stdlib::collections::HashMap; use crate::{ relocatable, diff --git a/vm/src/utils.rs b/vm/src/utils.rs index eeeec33894..8432a5cd79 100644 --- a/vm/src/utils.rs +++ b/vm/src/utils.rs @@ -121,14 +121,9 @@ pub mod test_utils { macro_rules! segments { ($( (($si:expr, $off:expr), $val:tt) ),* $(,)? ) => { { - let memory = memory!($( (($si, $off), $val) ),*); - $crate::vm::vm_memory::memory_segments::MemorySegmentManager { - memory, - segment_sizes: HashMap::new(), - segment_used_sizes: None, - public_memory_offsets: HashMap::new(), - } - + let mut segments = $crate::vm::vm_memory::memory_segments::MemorySegmentManager::new(); + segments.memory = memory!($( (($si, $off), $val) ),*); + segments } }; diff --git a/vm/src/vm/runners/builtin_runner/bitwise.rs b/vm/src/vm/runners/builtin_runner/bitwise.rs index ca9e1e01cc..1c4bdb889c 100644 --- a/vm/src/vm/runners/builtin_runner/bitwise.rs +++ b/vm/src/vm/runners/builtin_runner/bitwise.rs @@ -224,7 +224,6 @@ mod tests { use super::*; use crate::relocatable; use crate::serde::deserialize_program::BuiltinName; - use crate::stdlib::collections::HashMap; use crate::vm::errors::memory_errors::MemoryError; use crate::vm::runners::builtin_runner::BuiltinRunner; use crate::vm::vm_core::VirtualMachine; diff --git a/vm/src/vm/runners/builtin_runner/ec_op.rs b/vm/src/vm/runners/builtin_runner/ec_op.rs index 37ec430e12..af1951f543 100644 --- a/vm/src/vm/runners/builtin_runner/ec_op.rs +++ b/vm/src/vm/runners/builtin_runner/ec_op.rs @@ -298,7 +298,6 @@ mod tests { use super::*; use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; use crate::serde::deserialize_program::BuiltinName; - use crate::stdlib::collections::HashMap; use crate::types::program::Program; use crate::utils::test_utils::*; use crate::vm::errors::cairo_run_errors::CairoRunError; diff --git a/vm/src/vm/runners/builtin_runner/hash.rs b/vm/src/vm/runners/builtin_runner/hash.rs index 3ec2aabf27..788c224644 100644 --- a/vm/src/vm/runners/builtin_runner/hash.rs +++ b/vm/src/vm/runners/builtin_runner/hash.rs @@ -219,7 +219,6 @@ mod tests { use super::*; use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; use crate::serde::deserialize_program::BuiltinName; - use crate::stdlib::collections::HashMap; use crate::types::program::Program; use crate::utils::test_utils::*; use crate::vm::runners::cairo_runner::CairoRunner; diff --git a/vm/src/vm/runners/builtin_runner/keccak.rs b/vm/src/vm/runners/builtin_runner/keccak.rs index 17e6e3d638..a4f2346b27 100644 --- a/vm/src/vm/runners/builtin_runner/keccak.rs +++ b/vm/src/vm/runners/builtin_runner/keccak.rs @@ -272,7 +272,6 @@ impl KeccakBuiltinRunner { mod tests { use super::*; use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; - use crate::stdlib::collections::HashMap; use crate::types::program::Program; use crate::utils::test_utils::*; use crate::vm::runners::cairo_runner::CairoRunner; diff --git a/vm/src/vm/runners/builtin_runner/range_check.rs b/vm/src/vm/runners/builtin_runner/range_check.rs index 68809b8752..d70e74b9da 100644 --- a/vm/src/vm/runners/builtin_runner/range_check.rs +++ b/vm/src/vm/runners/builtin_runner/range_check.rs @@ -214,7 +214,6 @@ mod tests { use super::*; use crate::relocatable; use crate::serde::deserialize_program::BuiltinName; - use crate::stdlib::collections::HashMap; use crate::vm::vm_memory::memory::Memory; use crate::{ hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor, diff --git a/vm/src/vm/runners/builtin_runner/segment_arena.rs b/vm/src/vm/runners/builtin_runner/segment_arena.rs index 82c9e72aea..7f45f0e8f3 100644 --- a/vm/src/vm/runners/builtin_runner/segment_arena.rs +++ b/vm/src/vm/runners/builtin_runner/segment_arena.rs @@ -142,7 +142,6 @@ fn gen_arg(segments: &mut MemorySegmentManager, data: &[MaybeRelocatable; 3]) -> #[cfg(test)] mod tests { use super::*; - use crate::stdlib::collections::HashMap; use crate::vm::vm_core::VirtualMachine; use crate::{relocatable, utils::test_utils::*, vm::runners::builtin_runner::BuiltinRunner}; #[cfg(target_arch = "wasm32")] diff --git a/vm/src/vm/security.rs b/vm/src/vm/security.rs index 2749fcf154..45440cfd76 100644 --- a/vm/src/vm/security.rs +++ b/vm/src/vm/security.rs @@ -87,7 +87,6 @@ mod test { use super::*; use crate::hint_processor::builtin_hint_processor::builtin_hint_processor_definition::BuiltinHintProcessor; use crate::serde::deserialize_program::BuiltinName; - use crate::stdlib::collections::HashMap; use crate::types::relocatable::Relocatable; diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 947ba263b4..8bd47ea1df 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -1221,7 +1221,6 @@ mod tests { use crate::vm::runners::builtin_runner::{ BITWISE_BUILTIN_NAME, EC_OP_BUILTIN_NAME, HASH_BUILTIN_NAME, }; - use crate::vm::vm_memory::memory::Memory; use crate::{ any_box, hint_processor::builtin_hint_processor::builtin_hint_processor_definition::{ @@ -4321,11 +4320,10 @@ mod tests { ap: 18, fp: 0, }) - .segments(MemorySegmentManager { - segment_sizes: HashMap::new(), - segment_used_sizes: Some(vec![1]), - public_memory_offsets: HashMap::new(), - memory: Memory::new(), + .segments({ + let mut segments = MemorySegmentManager::new(); + segments.segment_used_sizes = Some(vec![1]); + segments }) .skip_instruction_execution(true) .trace(Some(vec![TraceEntry { diff --git a/vm/src/vm/vm_memory/memory_segments.rs b/vm/src/vm/vm_memory/memory_segments.rs index cabba6266b..aa8709419b 100644 --- a/vm/src/vm/vm_memory/memory_segments.rs +++ b/vm/src/vm/vm_memory/memory_segments.rs @@ -1,5 +1,9 @@ +use core::cmp::max; use core::fmt; +use crate::Felt252; +use num_traits::Zero; + use crate::stdlib::prelude::*; use crate::stdlib::{any::Any, collections::HashMap}; use crate::vm::runners::cairo_runner::CairoArg; @@ -12,6 +16,8 @@ use crate::{ }, }; +use super::memory::MemoryCell; + pub struct MemorySegmentManager { pub segment_sizes: HashMap, pub segment_used_sizes: Option>, @@ -19,6 +25,11 @@ pub struct MemorySegmentManager { // A map from segment index to a list of pairs (offset, page_id) that constitute the // public memory. Note that the offset is absolute (not based on the page_id). pub public_memory_offsets: HashMap>, + // Segment index of the zero segment index, a memory segment filled with zeroes, used exclusively by builtin runners + // This segment will never have index 0 so we use 0 to represent uninitialized value + zero_segment_index: usize, + // Segment size of the zero segment index + zero_segment_size: usize, } impl MemorySegmentManager { @@ -71,6 +82,8 @@ impl MemorySegmentManager { segment_used_sizes: None, public_memory_offsets: HashMap::new(), memory: Memory::new(), + zero_segment_index: 0, + zero_segment_size: 0, } } @@ -206,11 +219,16 @@ impl MemorySegmentManager { if i > builtin_segments_start && i <= builtin_segments_end { continue; } - let accessed_amount = match self.memory.get_amount_of_accessed_addresses_for_segment(i) - { - Some(accessed_amount) if accessed_amount > 0 => accessed_amount, - _ => continue, - }; + let accessed_amount = + // Instead of marking the values in the zero segment until zero_segment_size as accessed we use zero_segment_size as accessed_amount + if !self.zero_segment_index.is_zero() && i == self.zero_segment_index { + self.zero_segment_size + } else { + match self.memory.get_amount_of_accessed_addresses_for_segment(i) { + Some(accessed_amount) if accessed_amount > 0 => accessed_amount, + _ => continue, + } + }; let segment_size = self .get_segment_size(i) .ok_or(MemoryError::MissingSegmentUsedSizes)?; @@ -263,6 +281,37 @@ impl MemorySegmentManager { self.public_memory_offsets .insert(segment_index, public_memory.cloned().unwrap_or_default()); } + + // TODO: remove allow + #[allow(unused)] + // Creates the zero segment if it wasn't previously created + // Fills the segment with the value 0 until size is reached + // Returns the index of the zero segment + pub(crate) fn add_zero_segment(&mut self, size: usize) -> usize { + if self.zero_segment_index.is_zero() { + self.zero_segment_index = self.add().segment_index as usize; + } + // Fil zero segment with zero values until size is reached + for _ in 0..self.zero_segment_size.saturating_sub(size) { + // As zero_segment_index is only accessible to the segment manager + // we can asume that it is always valid and index direcly into it + self.memory.data[self.zero_segment_index] + .push(Some(MemoryCell::new(Felt252::ZERO.into()))) + } + self.zero_segment_size = max(self.zero_segment_size, size); + self.zero_segment_index + } + + // TODO: remove allow + #[allow(unused)] + // Finalizes the zero segment and clears it's tracking data from the manager + pub(crate) fn finalize_zero_segment(&mut self) { + if !self.zero_segment_index.is_zero() { + self.finalize(Some(self.zero_segment_size), self.zero_segment_index, None); + self.zero_segment_index = 0; + self.zero_segment_size = 0; + } + } } impl Default for MemorySegmentManager {