diff --git a/CHANGELOG.md b/CHANGELOG.md index def45d3522..3f72e8b0d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,8 @@ Both branches support Stwo prover opcodes (Blake2s, QM31) since v2.0.0. * fix: correct duplicate tuple index in InvalidTrackingGroup error message [#2276](https://github.com/lambdaclass/cairo-vm/pull/2276) +* fix: preserve verified offset flags in `HashBuiltinRunner::extend_additional_data` [#2269](https://github.com/lambdaclass/cairo-vm/pull/2269) + #### [3.0.1] - 2025-12-22 *Patch release with bug fixes backported to 3.0.x. See [3.1.0] for the consolidated changes.* diff --git a/vm/src/vm/runners/builtin_runner/hash.rs b/vm/src/vm/runners/builtin_runner/hash.rs index ad241e154b..0bc295f00b 100644 --- a/vm/src/vm/runners/builtin_runner/hash.rs +++ b/vm/src/vm/runners/builtin_runner/hash.rs @@ -61,11 +61,7 @@ impl HashBuiltinRunner { memory: &Memory, ) -> Result, RunnerError> { if address.offset.mod_floor(&(CELLS_PER_HASH as usize)) != 2 - || *self - .verified_addresses - .borrow() - .get(address.offset) - .unwrap_or(&false) + || *self.verified_addresses.borrow().get(address.offset).unwrap_or(&false) { return Ok(None); }; @@ -78,14 +74,11 @@ impl HashBuiltinRunner { segment_index: address.segment_index, offset: address.offset - 2, })); - if let (Some(MaybeRelocatable::Int(num_a)), Some(MaybeRelocatable::Int(num_b))) = ( - num_a.as_ref().map(|x| x.as_ref()), - num_b.as_ref().map(|x| x.as_ref()), - ) { + if let (Some(MaybeRelocatable::Int(num_a)), Some(MaybeRelocatable::Int(num_b))) = + (num_a.as_ref().map(|x| x.as_ref()), num_b.as_ref().map(|x| x.as_ref())) + { if self.verified_addresses.borrow().len() <= address.offset { - self.verified_addresses - .borrow_mut() - .resize(address.offset + 1, false); + self.verified_addresses.borrow_mut().resize(address.offset + 1, false); } self.verified_addresses.borrow_mut()[address.offset] = true; //Compute pedersen Hash @@ -96,9 +89,7 @@ impl HashBuiltinRunner { } pub fn get_used_cells(&self, segments: &MemorySegmentManager) -> Result { - segments - .get_segment_used_size(self.base()) - .ok_or(MemoryError::MissingSegmentUsedSizes) + segments.get_segment_used_size(self.base()).ok_or(MemoryError::MissingSegmentUsedSizes) } pub fn get_used_instances( @@ -134,10 +125,10 @@ impl HashBuiltinRunner { return Err(RunnerError::InvalidAdditionalData(BuiltinName::pedersen)); } // Mark offset as verified - if addr.offset > verified_addresses.len() { - verified_addresses.resize(addr.offset, false); + if addr.offset >= verified_addresses.len() { + verified_addresses.resize(addr.offset + 1, false); } - verified_addresses.insert(addr.offset, true) + verified_addresses[addr.offset] = true; } Ok(()) } @@ -146,10 +137,7 @@ impl HashBuiltinRunner { let mut private_inputs = vec![]; if let Some(segment) = memory.data.get(self.base) { let segment_len = segment.len(); - for (index, off) in (0..segment_len) - .step_by(CELLS_PER_HASH as usize) - .enumerate() - { + for (index, off) in (0..segment_len).step_by(CELLS_PER_HASH as usize).enumerate() { // Add the input cells of each hash instance to the private inputs if let (Ok(x), Ok(y)) = ( memory.get_integer((self.base as isize, off).into()), @@ -199,21 +187,14 @@ mod tests { let mut vm = vm!(); - vm.segments = segments![ - ((0, 0), (0, 0)), - ((0, 1), (0, 1)), - ((2, 0), (0, 0)), - ((2, 1), (0, 0)) - ]; + vm.segments = + segments![((0, 0), (0, 0)), ((0, 1), (0, 1)), ((2, 0), (0, 0)), ((2, 1), (0, 0))]; vm.segments.segment_used_sizes = Some(vec![0]); let pointer = Relocatable::from((2, 2)); - assert_eq!( - builtin.final_stack(&vm.segments, pointer).unwrap(), - Relocatable::from((2, 1)) - ); + assert_eq!(builtin.final_stack(&vm.segments, pointer).unwrap(), Relocatable::from((2, 1))); } #[test] @@ -223,12 +204,8 @@ mod tests { let mut vm = vm!(); - vm.segments = segments![ - ((0, 0), (0, 0)), - ((0, 1), (0, 1)), - ((2, 0), (0, 0)), - ((2, 1), (0, 0)) - ]; + vm.segments = + segments![((0, 0), (0, 0)), ((0, 1), (0, 1)), ((2, 0), (0, 0)), ((2, 1), (0, 0))]; vm.segments.segment_used_sizes = Some(vec![999]); @@ -251,21 +228,14 @@ mod tests { let mut vm = vm!(); - vm.segments = segments![ - ((0, 0), (0, 0)), - ((0, 1), (0, 1)), - ((2, 0), (0, 0)), - ((2, 1), (0, 0)) - ]; + vm.segments = + segments![((0, 0), (0, 0)), ((0, 1), (0, 1)), ((2, 0), (0, 0)), ((2, 1), (0, 0))]; vm.segments.segment_used_sizes = Some(vec![0]); let pointer = Relocatable::from((2, 2)); - assert_eq!( - builtin.final_stack(&vm.segments, pointer).unwrap(), - Relocatable::from((2, 2)) - ); + assert_eq!(builtin.final_stack(&vm.segments, pointer).unwrap(), Relocatable::from((2, 2))); } #[test] @@ -275,12 +245,7 @@ mod tests { let mut vm = vm!(); - vm.segments = segments![ - ((0, 0), (0, 0)), - ((0, 1), (0, 1)), - ((2, 0), (0, 0)), - ((2, 1), 2) - ]; + vm.segments = segments![((0, 0), (0, 0)), ((0, 1), (0, 1)), ((2, 0), (0, 0)), ((2, 1), 2)]; vm.segments.segment_used_sizes = Some(vec![0]); @@ -329,14 +294,9 @@ mod tests { let address = cairo_runner.initialize(false).unwrap(); - cairo_runner - .run_until_pc(address, &mut hint_processor) - .unwrap(); + cairo_runner.run_until_pc(address, &mut hint_processor).unwrap(); - assert_eq!( - builtin.get_used_cells_and_allocated_size(&cairo_runner.vm), - Ok((0, 3)) - ); + assert_eq!(builtin.get_used_cells_and_allocated_size(&cairo_runner.vm), Ok((0, 3))); } #[test] @@ -374,9 +334,7 @@ mod tests { let address = cairo_runner.initialize(false).unwrap(); - cairo_runner - .run_until_pc(address, &mut hint_processor) - .unwrap(); + cairo_runner.run_until_pc(address, &mut hint_processor).unwrap(); assert_eq!(builtin.get_allocated_memory_units(&cairo_runner.vm), Ok(3)); } @@ -434,10 +392,7 @@ mod tests { let builtin = BuiltinRunner::Hash(HashBuiltinRunner::new(Some(256), true)); let vm = vm!(); - assert_eq!( - builtin.get_used_cells(&vm.segments), - Err(MemoryError::MissingSegmentUsedSizes) - ); + assert_eq!(builtin.get_used_cells(&vm.segments), Err(MemoryError::MissingSegmentUsedSizes)); } #[test] @@ -466,10 +421,7 @@ mod tests { let verified_addresses = vec![Relocatable::from((0, 3)), Relocatable::from((0, 6))]; builtin.verified_addresses = RefCell::new(vec![false, false, false, true, false, false, true]); - assert_eq!( - builtin.get_additional_data(), - BuiltinAdditionalData::Hash(verified_addresses) - ) + assert_eq!(builtin.get_additional_data(), BuiltinAdditionalData::Hash(verified_addresses)) } #[test] @@ -483,6 +435,22 @@ mod tests { assert_eq!(builtin_a.verified_addresses, builtin_b.verified_addresses); } + #[test] + fn extend_additional_data_preserves_existing_verified_flags() { + let mut builtin = HashBuiltinRunner::new(Some(1), true); + builtin.verified_addresses = RefCell::new(vec![false, false, true, false, false, true]); + + let additional_data = + BuiltinAdditionalData::Hash(vec![Relocatable::from((0, 0)), Relocatable::from((0, 4))]); + + builtin.extend_additional_data(&additional_data).unwrap(); + + assert_eq!( + *builtin.verified_addresses.borrow(), + vec![true, false, true, false, true, true] + ); + } + #[test] #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] fn get_air_private_input() { @@ -503,21 +471,9 @@ mod tests { assert_eq!( builtin.air_private_input(&segments), (vec![ - PrivateInput::Pair(PrivateInputPair { - index: 0, - x: 0.into(), - y: 1.into() - }), - PrivateInput::Pair(PrivateInputPair { - index: 1, - x: 3.into(), - y: 4.into() - }), - PrivateInput::Pair(PrivateInputPair { - index: 2, - x: 6.into(), - y: 7.into() - }), + PrivateInput::Pair(PrivateInputPair { index: 0, x: 0.into(), y: 1.into() }), + PrivateInput::Pair(PrivateInputPair { index: 1, x: 3.into(), y: 4.into() }), + PrivateInput::Pair(PrivateInputPair { index: 2, x: 6.into(), y: 7.into() }), ]), ); }