diff --git a/CHANGELOG.md b/CHANGELOG.md index 61c63f365a..beab9703e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* feat: implement VirtualMachine::is_accessed [#2024](https://github.com/lambdaclass/cairo-vm/pull/2024) + * fix: Keep None values in memory segments for the prover input info [#2021](https://github.com/lambdaclass/cairo-vm/pull/2021) * refactor: Clap attribute macros from #[clap(...)] to #[arg(...)] and #[command(...)] in v4.x [#2003] (https://github.com/lambdaclass/cairo-vm/pull/2003) diff --git a/vm/src/vm/vm_core.rs b/vm/src/vm/vm_core.rs index 1c0a59682e..a38440f1dd 100644 --- a/vm/src/vm/vm_core.rs +++ b/vm/src/vm/vm_core.rs @@ -971,6 +971,10 @@ impl VirtualMachine { self.segments.memory.mem_eq(lhs, rhs, len) } + pub fn is_accessed(&self, addr: &Relocatable) -> Result { + self.segments.is_accessed(addr) + } + ///Gets `n_ret` return values from memory pub fn get_return_values(&self, n_ret: usize) -> Result, MemoryError> { let addr = (self.run_context.get_ap() - n_ret) diff --git a/vm/src/vm/vm_memory/memory.rs b/vm/src/vm/vm_memory/memory.rs index c92e132043..9808ab3f1b 100644 --- a/vm/src/vm/vm_memory/memory.rs +++ b/vm/src/vm/vm_memory/memory.rs @@ -244,13 +244,7 @@ impl Memory { { let relocatable: Relocatable = key.try_into().ok()?; - let data = if relocatable.segment_index.is_negative() { - &self.temp_data - } else { - &self.data - }; - let (i, j) = from_relocatable_to_indexes(relocatable); - let value = data.get(i)?.get(j)?.get_value()?; + let value = self.get_cell(relocatable)?.get_value()?; Some(Cow::Owned(self.relocate_value(&value).ok()?.into_owned())) } @@ -648,6 +642,23 @@ impl Memory { Ok(values) } + fn get_cell(&self, addr: Relocatable) -> Option<&MemoryCell> { + let (i, j) = from_relocatable_to_indexes(addr); + let data = if addr.segment_index < 0 { + &self.temp_data + } else { + &self.data + }; + data.get(i)?.get(j) + } + + pub fn is_accessed(&self, addr: &Relocatable) -> Result { + Ok(self + .get_cell(*addr) + .ok_or(MemoryError::UnknownMemoryCell(Box::new(*addr)))? + .is_accessed()) + } + pub fn mark_as_accessed(&mut self, addr: Relocatable) { let (i, j) = from_relocatable_to_indexes(addr); let data = if addr.segment_index < 0 { diff --git a/vm/src/vm/vm_memory/memory_segments.rs b/vm/src/vm/vm_memory/memory_segments.rs index 82bc51cbc2..e18e739346 100644 --- a/vm/src/vm/vm_memory/memory_segments.rs +++ b/vm/src/vm/vm_memory/memory_segments.rs @@ -200,6 +200,10 @@ impl MemorySegmentManager { } } + pub fn is_accessed(&self, addr: &Relocatable) -> Result { + self.memory.is_accessed(addr) + } + /// Counts the memory holes (aka unaccessed memory cells) in memory /// # Parameters /// - `builtin_segment_indexes`: Set representing the segments indexes of the builtins initialized in the VM, except for the output builtin.