Skip to content

Commit d220115

Browse files
add the functions get_u32_range and get_u32_from_felt252 to impl VirtualMachine
1 parent 6dbac44 commit d220115

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#### Upcoming Changes
44

5+
* feat: add the functions `get_u32_range` and `get_u32_from_felt252` to `impl VirtualMachine` [#1936](https://github.com/lambdaclass/cairo-vm/pull/1936)
6+
57
* feat: add the field `opcode_extension` to the structure of `Instruction` [#1933](https://github.com/lambdaclass/cairo-vm/pull/1933)
68

79
* fix(BREAKING): Fix no trace padding flow in proof mode [#1909](https://github.com/lambdaclass/cairo-vm/pull/1909)

vm/src/vm/errors/memory_errors.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ pub enum MemoryError {
101101
UnrelocatedMemory,
102102
#[error("Malformed public memory")]
103103
MalformedPublicMemory,
104+
#[error("Expected u32 valued Felt252, found {0}")]
105+
ExpectedU32(Box<Felt252>),
104106
}
105107

106108
#[derive(Debug, PartialEq, Eq, Error)]

vm/src/vm/vm_core.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
instruction::{
1212
is_call_instruction, ApUpdate, FpUpdate, Instruction, Opcode, PcUpdate, Res,
1313
},
14-
relocatable::{MaybeRelocatable, Relocatable},
14+
relocatable::{MaybeRelocatable, MaybeRelocatable::RelocatableValue, Relocatable},
1515
},
1616
vm::{
1717
context::run_context::RunContext,
@@ -929,6 +929,33 @@ impl VirtualMachine {
929929
self.segments.memory.get_integer_range(addr, size)
930930
}
931931

932+
/// Gets n u32 values from memory starting from addr (n being size),
933+
/// Verifies that addr is &RelocatableValue and that the values are u32.
934+
pub fn get_u32_range(
935+
&self,
936+
addr: &MaybeRelocatable,
937+
size: usize,
938+
) -> Result<Vec<u32>, MemoryError> {
939+
let addr_relocatable: Relocatable = match addr {
940+
&RelocatableValue(relocatable) => relocatable,
941+
_ => return Err(MemoryError::AddressNotRelocatable),
942+
};
943+
let res_cow = self.get_integer_range(addr_relocatable, size)?;
944+
res_cow
945+
.iter()
946+
.map(|x| VirtualMachine::get_u32_from_felt252(x.clone().into_owned()))
947+
.collect()
948+
}
949+
950+
fn get_u32_from_felt252(felt: Felt252) -> Result<u32, MemoryError> {
951+
let le_digits = felt.to_le_digits();
952+
if le_digits[0] >= (1 << 32) || le_digits[1] != 0 || le_digits[2] != 0 || le_digits[3] != 0
953+
{
954+
return Err(MemoryError::ExpectedU32(Box::new(felt)));
955+
}
956+
Ok(le_digits[0] as u32)
957+
}
958+
932959
pub fn get_range_check_builtin(
933960
&self,
934961
) -> Result<&RangeCheckBuiltinRunner<RC_N_PARTS_STANDARD>, VirtualMachineError> {
@@ -4373,6 +4400,26 @@ mod tests {
43734400
);
43744401
}
43754402

4403+
#[test]
4404+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
4405+
fn get_u32_range_not_relocatable() {
4406+
let vm = vm!();
4407+
assert_matches!(
4408+
vm.get_u32_range(&MaybeRelocatable::Int(Felt252::from(1)), 1),
4409+
Err(MemoryError::AddressNotRelocatable)
4410+
);
4411+
}
4412+
4413+
#[test]
4414+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
4415+
fn get_u32_from_felt252_not_u32() {
4416+
let x = Felt252::from(1 << 32);
4417+
assert_matches!(
4418+
VirtualMachine::get_u32_from_felt252(x),
4419+
Err(MemoryError::ExpectedU32(bx)) if *bx == x.into()
4420+
);
4421+
}
4422+
43764423
#[test]
43774424
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
43784425
fn get_traceback_entries_bad_usort() {

0 commit comments

Comments
 (0)