diff --git a/src/hint_processor/builtin_hint_processor/blake2s_utils.rs b/src/hint_processor/builtin_hint_processor/blake2s_utils.rs index a53adfa5e5..a12c20c0d8 100644 --- a/src/hint_processor/builtin_hint_processor/blake2s_utils.rs +++ b/src/hint_processor/builtin_hint_processor/blake2s_utils.rs @@ -288,9 +288,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory( - MemoryError::ExpectedRelocatable(x) - )) if x == Relocatable::from((1, 0)) + Err(HintError::IdentifierNotRelocatable(x, y) + ) if x == "output" && y == (1,0).into() ); } @@ -423,7 +422,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, HashMap::new(), hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "blake2s_ptr_end" ); } diff --git a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs index 72e6cb0935..db4dd67767 100644 --- a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs +++ b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs @@ -447,7 +447,6 @@ impl HintProcessor for BuiltinHintProcessor { #[cfg(test)] mod tests { use super::*; - use crate::types::relocatable::Relocatable; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use crate::{ any_box, @@ -555,9 +554,8 @@ mod tests { let ids_data = ids_data!["len"]; assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 1)) + Err(HintError::IdentifierNotInteger(x, y)) + if x == "len" && y == (1,1).into() ); } diff --git a/src/hint_processor/builtin_hint_processor/dict_hint_utils.rs b/src/hint_processor/builtin_hint_processor/dict_hint_utils.rs index 463b69a040..a8c576c1f6 100644 --- a/src/hint_processor/builtin_hint_processor/dict_hint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/dict_hint_utils.rs @@ -440,7 +440,7 @@ mod tests { let ids_data = ids_data!["default_value"]; assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "default_value" ); } diff --git a/src/hint_processor/builtin_hint_processor/find_element_hint.rs b/src/hint_processor/builtin_hint_processor/find_element_hint.rs index 080cbafda2..7d9021742a 100644 --- a/src/hint_processor/builtin_hint_processor/find_element_hint.rs +++ b/src/hint_processor/builtin_hint_processor/find_element_hint.rs @@ -144,9 +144,9 @@ mod tests { }, hint_processor_definition::HintProcessor, }, - types::relocatable::{MaybeRelocatable, Relocatable}, + types::relocatable::MaybeRelocatable, utils::test_utils::*, - vm::{errors::memory_errors::MemoryError, vm_core::VirtualMachine}, + vm::vm_core::VirtualMachine, }; use assert_matches::assert_matches; use num_traits::{One, Zero}; @@ -269,9 +269,8 @@ mod tests { let ids_data = ids_data!["array_ptr", "elm_size", "n_elms", "index", "key"]; assert_matches!( run_hint!(vm, ids_data, hint_code::FIND_ELEMENT), - Err(HintError::Memory(MemoryError::UnknownMemoryCell( - x - ))) if x == Relocatable::from((1, 4)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "key" && y == (1,4).into() ); } @@ -283,9 +282,8 @@ mod tests { )])); assert_matches!( run_hint!(vm, ids_data, hint_code::FIND_ELEMENT), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 1)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "elm_size" && y == (1,1).into() ); } @@ -315,16 +313,13 @@ mod tests { #[test] fn find_elm_not_int_n_elms() { - let relocatable = Relocatable::from((1, 2)); - let (mut vm, ids_data) = init_vm_ids_data(HashMap::from([( - "n_elms".to_string(), - MaybeRelocatable::from(relocatable), - )])); + let relocatable = MaybeRelocatable::from((1, 2)); + let (mut vm, ids_data) = + init_vm_ids_data(HashMap::from([("n_elms".to_string(), relocatable)])); assert_matches!( run_hint!(vm, ids_data, hint_code::FIND_ELEMENT), - Err(HintError::Memory(MemoryError::ExpectedInteger( - inner - ))) if inner == relocatable + Err(HintError::IdentifierNotInteger(x, y + )) if x == "n_elms" && y == (1,2).into() ); } @@ -363,12 +358,7 @@ mod tests { init_vm_ids_data(HashMap::from([("key".to_string(), relocatable)])); assert_matches!( run_hint!(vm, ids_data, hint_code::FIND_ELEMENT), - Err(HintError::Memory(MemoryError::ExpectedInteger( - Relocatable { - segment_index: 1, - offset: 4 - } - ))) + Err(HintError::IdentifierNotInteger(x, y)) if x == "key" && y == (1,4).into() ); } @@ -404,9 +394,8 @@ mod tests { )])); assert_matches!( run_hint!(vm, ids_data, hint_code::SEARCH_SORTED_LOWER), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 1)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "elm_size" && y == (1,1).into() ); } @@ -442,9 +431,8 @@ mod tests { )])); assert_matches!( run_hint!(vm, ids_data, hint_code::SEARCH_SORTED_LOWER), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 2)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "n_elms" && y == (1,2).into() ); } diff --git a/src/hint_processor/builtin_hint_processor/hint_utils.rs b/src/hint_processor/builtin_hint_processor/hint_utils.rs index 867742b521..eb31045b2a 100644 --- a/src/hint_processor/builtin_hint_processor/hint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/hint_utils.rs @@ -1,7 +1,9 @@ use felt::Felt; use crate::hint_processor::hint_processor_definition::HintReference; -use crate::hint_processor::hint_processor_utils::compute_addr_from_reference; +use crate::hint_processor::hint_processor_utils::{ + compute_addr_from_reference, get_ptr_from_reference, +}; use crate::hint_processor::hint_processor_utils::{ get_integer_from_reference, get_maybe_relocatable_from_reference, }; @@ -42,16 +44,14 @@ pub fn get_ptr_from_var_name( ids_data: &HashMap, ap_tracking: &ApTracking, ) -> Result { - let var_addr = get_relocatable_from_var_name(var_name, vm, ids_data, ap_tracking)?; - //Add immediate if present in reference - let hint_reference = ids_data - .get(&String::from(var_name)) - .ok_or(HintError::FailedToGetIds)?; - if hint_reference.dereference { - let value = vm.get_relocatable(var_addr)?; - Ok(value) - } else { - Ok(var_addr) + let reference = get_reference_from_var_name(var_name, ids_data)?; + match get_ptr_from_reference(vm, reference, ap_tracking) { + // Map internal errors into more descriptive variants + Ok(val) => Ok(val), + Err(HintError::WrongIdentifierTypeInternal(var_addr)) => Err( + HintError::IdentifierNotRelocatable(var_name.to_string(), var_addr), + ), + _ => Err(HintError::UnknownIdentifier(var_name.to_string())), } } @@ -62,11 +62,7 @@ pub fn get_address_from_var_name( ids_data: &HashMap, ap_tracking: &ApTracking, ) -> Result { - Ok(MaybeRelocatable::from(compute_addr_from_reference( - ids_data.get(var_name).ok_or(HintError::FailedToGetIds)?, - vm, - ap_tracking, - )?)) + get_relocatable_from_var_name(var_name, vm, ids_data, ap_tracking).map(|x| x.into()) } //Gets the address, as a Relocatable of the variable given by the ids name @@ -76,24 +72,30 @@ pub fn get_relocatable_from_var_name( ids_data: &HashMap, ap_tracking: &ApTracking, ) -> Result { - compute_addr_from_reference( - ids_data.get(var_name).ok_or(HintError::FailedToGetIds)?, - vm, - ap_tracking, - ) + ids_data + .get(var_name) + .and_then(|x| compute_addr_from_reference(x, vm, ap_tracking)) + .ok_or_else(|| HintError::UnknownIdentifier(var_name.to_string())) } //Gets the value of a variable name. //If the value is an MaybeRelocatable::Int(Bigint) return &Bigint //else raises Err pub fn get_integer_from_var_name<'a>( - var_name: &str, + var_name: &'a str, vm: &'a VirtualMachine, ids_data: &'a HashMap, ap_tracking: &ApTracking, ) -> Result, HintError> { let reference = get_reference_from_var_name(var_name, ids_data)?; - get_integer_from_reference(vm, reference, ap_tracking) + match get_integer_from_reference(vm, reference, ap_tracking) { + // Map internal errors into more descriptive variants + Ok(val) => Ok(val), + Err(HintError::WrongIdentifierTypeInternal(var_addr)) => Err( + HintError::IdentifierNotInteger(var_name.to_string(), var_addr), + ), + _ => Err(HintError::UnknownIdentifier(var_name.to_string())), + } } //Gets the value of a variable name as a MaybeRelocatable @@ -105,13 +107,16 @@ pub fn get_maybe_relocatable_from_var_name<'a>( ) -> Result { let reference = get_reference_from_var_name(var_name, ids_data)?; get_maybe_relocatable_from_reference(vm, reference, ap_tracking) + .ok_or_else(|| HintError::UnknownIdentifier(var_name.to_string())) } pub fn get_reference_from_var_name<'a>( - var_name: &str, + var_name: &'a str, ids_data: &'a HashMap, ) -> Result<&'a HintReference, HintError> { - ids_data.get(var_name).ok_or(HintError::FailedToGetIds) + ids_data + .get(var_name) + .ok_or(HintError::UnknownIdentifier(var_name.to_string())) } #[cfg(test)] @@ -165,7 +170,7 @@ mod tests { assert_matches!( get_maybe_relocatable_from_var_name("value", &vm, &ids_data, &ApTracking::new()), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == *"value" ); } @@ -191,9 +196,8 @@ mod tests { assert_matches!( get_ptr_from_var_name("value", &vm, &ids_data, &ApTracking::new()), - Err(HintError::Memory( - MemoryError::ExpectedRelocatable(x) - )) if x == Relocatable::from((1, 0)) + Err(HintError::IdentifierNotRelocatable(x,y + )) if x == "value" && y == (1,0).into() ); } @@ -219,7 +223,7 @@ mod tests { assert_matches!( get_relocatable_from_var_name("value", &vm, &ids_data, &ApTracking::new()), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "value" ); } @@ -245,9 +249,8 @@ mod tests { assert_matches!( get_integer_from_var_name("value", &vm, &ids_data, &ApTracking::new()), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 0)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "value" && y == (1,0).into() ); } } diff --git a/src/hint_processor/builtin_hint_processor/math_utils.rs b/src/hint_processor/builtin_hint_processor/math_utils.rs index 04335830fb..d51a88161e 100644 --- a/src/hint_processor/builtin_hint_processor/math_utils.rs +++ b/src/hint_processor/builtin_hint_processor/math_utils.rs @@ -2,8 +2,8 @@ use crate::{ any_box, hint_processor::{ builtin_hint_processor::hint_utils::{ - get_address_from_var_name, get_integer_from_var_name, get_ptr_from_var_name, - insert_value_from_var_name, insert_value_into_ap, + get_integer_from_var_name, get_ptr_from_var_name, insert_value_from_var_name, + insert_value_into_ap, }, hint_processor_definition::HintReference, }, @@ -26,6 +26,8 @@ use std::{ ops::{Shl, Shr}, }; +use super::hint_utils::get_maybe_relocatable_from_var_name; + //Implements hint: memory[ap] = 0 if 0 <= (ids.a % PRIME) < range_check_builtin.bound else 1 pub fn is_nn( vm: &mut VirtualMachine, @@ -191,42 +193,31 @@ pub fn assert_not_equal( ids_data: &HashMap, ap_tracking: &ApTracking, ) -> Result<(), HintError> { - let a_addr = get_address_from_var_name("a", vm, ids_data, ap_tracking)?; - let b_addr = get_address_from_var_name("b", vm, ids_data, ap_tracking)?; - //Check that the ids are in memory - match (vm.get_maybe(&a_addr), vm.get_maybe(&b_addr)) { - (Some(maybe_rel_a), Some(maybe_rel_b)) => { - let maybe_rel_a = maybe_rel_a; - let maybe_rel_b = maybe_rel_b; - match (maybe_rel_a, maybe_rel_b) { - (MaybeRelocatable::Int(a), MaybeRelocatable::Int(b)) => { - if (&a - &b).is_zero() { - return Err(HintError::AssertNotEqualFail( - MaybeRelocatable::Int(a), - MaybeRelocatable::Int(b), - )); - }; - Ok(()) - } - (MaybeRelocatable::RelocatableValue(a), MaybeRelocatable::RelocatableValue(b)) => { - if a.segment_index != b.segment_index { - Err(VirtualMachineError::DiffIndexComp(a, b))?; - }; - if a.offset == b.offset { - return Err(HintError::AssertNotEqualFail( - MaybeRelocatable::RelocatableValue(a), - MaybeRelocatable::RelocatableValue(b), - )); - }; - Ok(()) - } - (maybe_rel_a, maybe_rel_b) => Err(VirtualMachineError::DiffTypeComparison( - maybe_rel_a, - maybe_rel_b, - ))?, - } + let maybe_rel_a = get_maybe_relocatable_from_var_name("a", vm, ids_data, ap_tracking)?; + let maybe_rel_b = get_maybe_relocatable_from_var_name("b", vm, ids_data, ap_tracking)?; + match (maybe_rel_a, maybe_rel_b) { + (MaybeRelocatable::Int(a), MaybeRelocatable::Int(b)) => { + if (&a - &b).is_zero() { + return Err(HintError::AssertNotEqualFail( + MaybeRelocatable::Int(a), + MaybeRelocatable::Int(b), + )); + }; + Ok(()) + } + (MaybeRelocatable::RelocatableValue(a), MaybeRelocatable::RelocatableValue(b)) => { + if a.segment_index != b.segment_index { + Err(VirtualMachineError::DiffIndexComp(a, b))?; + }; + if a.offset == b.offset { + return Err(HintError::AssertNotEqualFail( + MaybeRelocatable::RelocatableValue(a), + MaybeRelocatable::RelocatableValue(b), + )); + }; + Ok(()) } - _ => Err(HintError::FailedToGetIds), + (a, b) => Err(VirtualMachineError::DiffTypeComparison(a, b))?, } } @@ -655,7 +646,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "a" ); } @@ -672,9 +663,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::UnknownMemoryCell( - x - ))) if x == Relocatable::from((1, 4)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "a" && y == (1,4).into() ); } @@ -691,9 +681,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 4)) + Err(HintError::IdentifierNotInteger(x,y + )) if x == "a" && y == (1,4).into() ); } @@ -776,7 +765,7 @@ mod tests { let ids_data = ids_data!["a", "c"]; assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "b" ); } @@ -824,7 +813,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "a" ); } @@ -840,9 +829,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::UnknownMemoryCell( - x - ))) if x == Relocatable::from((1, 3)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "a" && y == (1,3).into() ); } @@ -875,9 +863,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::UnknownMemoryCell( - x - ))) if x == Relocatable::from((1, 3)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "a" && y == (1,3).into() ); } @@ -930,9 +917,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code, &mut exec_scopes, &constants), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 0)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "a" && y == (1,0).into() ); } @@ -958,9 +944,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code, &mut exec_scopes, &constants), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 1)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "b" && y == (1,1).into() ); } @@ -1174,7 +1159,7 @@ mod tests { let ids_data = ids_data!["incorrect_id"]; assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "value" ); } @@ -1191,9 +1176,8 @@ mod tests { let ids_data = ids_data!["value"]; assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 4)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "value" && y == (1,4).into() ); } @@ -1500,7 +1484,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "div" ) } @@ -1610,7 +1594,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "div" ) } @@ -1700,7 +1684,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "value" ); } @@ -1789,9 +1773,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 3)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "value" && y == (1,3).into() ); } @@ -1839,7 +1822,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "b" ); } @@ -1855,9 +1838,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 1)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "a" && y == (1,1).into() ); } @@ -1873,9 +1855,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 2)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "b" && y == (1,2).into() ); } @@ -1892,9 +1873,8 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::UnknownMemoryCell( - x - ))) if x == Relocatable::from((1, 2)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "b" && y == (1,2).into() ); } } diff --git a/src/hint_processor/builtin_hint_processor/memcpy_hint_utils.rs b/src/hint_processor/builtin_hint_processor/memcpy_hint_utils.rs index 08ac141d7f..a7e8d36ad6 100644 --- a/src/hint_processor/builtin_hint_processor/memcpy_hint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/memcpy_hint_utils.rs @@ -74,7 +74,6 @@ pub fn memcpy_continue_copying( #[cfg(test)] mod tests { use super::*; - use crate::types::relocatable::Relocatable; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use crate::{ types::relocatable::MaybeRelocatable, @@ -125,9 +124,8 @@ mod tests { assert_matches!( get_integer_from_var_name(var_name, &vm, &ids_data, &ApTracking::default()), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 0)) + Err(HintError::IdentifierNotInteger(x,y + )) if x == var_name && y == (1,0).into() ); } } diff --git a/src/hint_processor/builtin_hint_processor/memset_utils.rs b/src/hint_processor/builtin_hint_processor/memset_utils.rs index ae8e453848..8d13dd38da 100644 --- a/src/hint_processor/builtin_hint_processor/memset_utils.rs +++ b/src/hint_processor/builtin_hint_processor/memset_utils.rs @@ -56,7 +56,6 @@ pub fn memset_continue_loop( #[cfg(test)] mod tests { use super::*; - use crate::types::relocatable::Relocatable; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use crate::{ any_box, @@ -97,9 +96,8 @@ mod tests { let ids_data = ids_data!["n"]; assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 1)) + Err(HintError::IdentifierNotInteger(x, y + )) if x == "n" && y == (1,1).into() ); } diff --git a/src/hint_processor/builtin_hint_processor/pow_utils.rs b/src/hint_processor/builtin_hint_processor/pow_utils.rs index 732918c486..cb903b1d3e 100644 --- a/src/hint_processor/builtin_hint_processor/pow_utils.rs +++ b/src/hint_processor/builtin_hint_processor/pow_utils.rs @@ -21,8 +21,11 @@ pub fn pow( ids_data: &HashMap, ap_tracking: &ApTracking, ) -> Result<(), HintError> { - let prev_locs_addr = get_relocatable_from_var_name("prev_locs", vm, ids_data, ap_tracking)?; - let prev_locs_exp = vm.get_integer(prev_locs_addr + 4_i32)?; + let prev_locs_exp = vm + .get_integer(get_relocatable_from_var_name("prev_locs", vm, ids_data, ap_tracking)? + 4_i32) + .map_err(|_| { + HintError::IdentifierHasNoMember("prev_locs".to_string(), "exp".to_string()) + })?; let locs_bit = prev_locs_exp.is_odd(); insert_value_from_var_name("locs", Felt::new(locs_bit as u8), vm, ids_data, ap_tracking)?; Ok(()) @@ -31,7 +34,6 @@ pub fn pow( #[cfg(test)] mod tests { use super::*; - use crate::types::relocatable::Relocatable; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use crate::{ any_box, @@ -76,7 +78,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::FailedToGetIds) + Err(HintError::UnknownIdentifier(x)) if x == "prev_locs" ); } @@ -92,9 +94,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::UnknownMemoryCell( - x - ))) if x == Relocatable::from((1, 10)) + Err(HintError::IdentifierHasNoMember(x, y)) if x =="prev_locs" && y == "exp" ); } @@ -112,9 +112,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 10)) + Err(HintError::IdentifierHasNoMember(x, y)) if x == "prev_locs" && y == "exp" ); } diff --git a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs index b6fba2edd6..e76f4e4dae 100644 --- a/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs @@ -7,11 +7,52 @@ use crate::{ hint_processor_definition::HintReference, }, serde::deserialize_program::ApTracking, - types::{exec_scope::ExecutionScopes, relocatable::MaybeRelocatable}, + types::{ + exec_scope::ExecutionScopes, + relocatable::{MaybeRelocatable, Relocatable}, + }, vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, }; use felt::Felt; -use std::collections::HashMap; +use std::{borrow::Cow, collections::HashMap}; + +#[derive(Debug, PartialEq)] +pub(crate) struct BigInt3<'a> { + pub d0: Cow<'a, Felt>, + pub d1: Cow<'a, Felt>, + pub d2: Cow<'a, Felt>, +} + +impl BigInt3<'_> { + pub(crate) fn from_base_addr<'a>( + addr: Relocatable, + name: &str, + vm: &'a VirtualMachine, + ) -> Result, HintError> { + Ok(BigInt3 { + d0: vm.get_integer(addr).map_err(|_| { + HintError::IdentifierHasNoMember(name.to_string(), "d0".to_string()) + })?, + d1: vm.get_integer(addr + 1).map_err(|_| { + HintError::IdentifierHasNoMember(name.to_string(), "d1".to_string()) + })?, + d2: vm.get_integer(addr + 2).map_err(|_| { + HintError::IdentifierHasNoMember(name.to_string(), "d2".to_string()) + })?, + }) + } + + pub(crate) fn from_var_name<'a>( + name: &str, + vm: &'a VirtualMachine, + ids_data: &HashMap, + ap_tracking: &ApTracking, + ) -> Result, HintError> { + let base_addr = get_relocatable_from_var_name(name, vm, ids_data, ap_tracking)?; + BigInt3::from_base_addr(base_addr, name, vm) + } +} + /* Implements hint: %{ @@ -72,8 +113,11 @@ mod tests { use crate::types::relocatable::MaybeRelocatable; use crate::types::relocatable::Relocatable; use crate::utils::test_utils::*; + use crate::vm::errors::memory_errors::MemoryError; use crate::vm::runners::builtin_runner::RangeCheckBuiltinRunner; use crate::vm::vm_core::VirtualMachine; + use crate::vm::vm_memory::memory::Memory; + use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use assert_matches::assert_matches; use num_traits::One; use std::any::Any; @@ -126,7 +170,7 @@ mod tests { let ids_data = non_continuous_ids_data![("res", 5)]; assert_matches!( run_hint!(vm, ids_data, hint_code), - Err(HintError::VariableNotInScopeError(x)) if x == *"value".to_string() + Err(HintError::VariableNotInScopeError(x)) if x == "value" ); } @@ -144,4 +188,57 @@ mod tests { Err(HintError::BigIntToBigUintFail) ); } + + #[test] + fn get_bigint3_from_base_addr_ok() { + //BigInt3(1,2,3) + let mut vm = vm!(); + vm.segments = segments![((0, 0), 1), ((0, 1), 2), ((0, 2), 3)]; + let x = BigInt3::from_base_addr((0, 0).into(), "x", &vm).unwrap(); + assert_eq!(x.d0.as_ref(), &Felt::one()); + assert_eq!(x.d1.as_ref(), &Felt::from(2)); + assert_eq!(x.d2.as_ref(), &Felt::from(3)); + } + + #[test] + fn get_bigint3_from_base_addr_missing_member() { + //BigInt3(1,2,x) + let mut vm = vm!(); + vm.segments = segments![((0, 0), 1), ((0, 1), 2)]; + let r = BigInt3::from_base_addr((0, 0).into(), "x", &vm); + assert_matches!(r, Err(HintError::IdentifierHasNoMember(x, y)) if x == "x" && y == "d2") + } + + #[test] + fn get_bigint3_from_var_name_ok() { + //BigInt3(1,2,3) + let mut vm = vm!(); + vm.set_fp(1); + vm.segments = segments![((1, 0), 1), ((1, 1), 2), ((1, 2), 3)]; + let ids_data = ids_data!["x"]; + let x = BigInt3::from_var_name("x", &vm, &ids_data, &ApTracking::default()).unwrap(); + assert_eq!(x.d0.as_ref(), &Felt::one()); + assert_eq!(x.d1.as_ref(), &Felt::from(2)); + assert_eq!(x.d2.as_ref(), &Felt::from(3)); + } + + #[test] + fn get_bigint3_from_var_name_missing_member() { + //BigInt3(1,2,x) + let mut vm = vm!(); + vm.set_fp(1); + vm.segments = segments![((1, 0), 1), ((1, 1), 2)]; + let ids_data = ids_data!["x"]; + let r = BigInt3::from_var_name("x", &vm, &ids_data, &ApTracking::default()); + assert_matches!(r, Err(HintError::IdentifierHasNoMember(x, y)) if x == "x" && y == "d2") + } + + #[test] + fn get_bigint3_from_var_name_invalid_reference() { + let mut vm = vm!(); + vm.segments = segments![((1, 0), 1), ((1, 1), 2), ((1, 2), 3)]; + let ids_data = ids_data!["x"]; + let r = BigInt3::from_var_name("x", &vm, &ids_data, &ApTracking::default()); + assert_matches!(r, Err(HintError::UnknownIdentifier(x)) if x == "x") + } } diff --git a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs index 20041d728b..6e1f3b3a17 100644 --- a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs @@ -4,7 +4,7 @@ use crate::{ hint_utils::{ get_integer_from_var_name, get_relocatable_from_var_name, insert_value_into_ap, }, - secp::secp_utils::{pack, pack_from_relocatable, SECP_REM}, + secp::secp_utils::{pack, SECP_REM}, }, hint_processor_definition::HintReference, }, @@ -22,6 +22,29 @@ use std::{ ops::{BitAnd, Shl}, }; +use super::bigint_utils::BigInt3; + +#[derive(Debug, PartialEq)] +struct EcPoint<'a> { + x: BigInt3<'a>, + y: BigInt3<'a>, +} +impl EcPoint<'_> { + fn from_var_name<'a>( + name: &'a str, + vm: &'a VirtualMachine, + ids_data: &'a HashMap, + ap_tracking: &'a ApTracking, + ) -> Result, HintError> { + // Get first addr of EcPoint struct + let point_addr = get_relocatable_from_var_name(name, vm, ids_data, ap_tracking)?; + Ok(EcPoint { + x: BigInt3::from_base_addr(point_addr, &format!("{}.x", name), vm)?, + y: BigInt3::from_base_addr(point_addr + 3, &format!("{}.y", name), vm)?, + }) + } +} + /* Implements hint: %{ @@ -49,7 +72,8 @@ pub fn ec_negate( //ids.point let point_y = get_relocatable_from_var_name("point", vm, ids_data, ap_tracking)? + 3i32; - let y = pack_from_relocatable(point_y, vm)?; + let y_bigint3 = BigInt3::from_base_addr(point_y, "point.y", vm)?; + let y = pack(y_bigint3); let value = (-y).mod_floor(&secp_p); exec_scopes.insert_value("value", value); Ok(()) @@ -82,25 +106,9 @@ pub fn compute_doubling_slope( .to_bigint(); //ids.point - let point_reloc = get_relocatable_from_var_name("point", vm, ids_data, ap_tracking)?; - - let (x_d0, x_d1, x_d2, y_d0, y_d1, y_d2) = ( - vm.get_integer(point_reloc)?, - vm.get_integer(point_reloc + 1i32)?, - vm.get_integer(point_reloc + 2i32)?, - vm.get_integer(point_reloc + 3i32)?, - vm.get_integer(point_reloc + 4i32)?, - vm.get_integer(point_reloc + 5i32)?, - ); + let point = EcPoint::from_var_name("point", vm, ids_data, ap_tracking)?; - let value = ec_double_slope( - &( - pack(x_d0.as_ref(), x_d1.as_ref(), x_d2.as_ref()), - pack(y_d0.as_ref(), y_d1.as_ref(), y_d2.as_ref()), - ), - &BigInt::zero(), - &secp_p, - ); + let value = ec_double_slope(&(pack(point.x), pack(point.y)), &BigInt::zero(), &secp_p); exec_scopes.insert_value("value", value.clone()); exec_scopes.insert_value("slope", value); Ok(()) @@ -135,54 +143,13 @@ pub fn compute_slope( .to_bigint(); //ids.point0 - let point0_reloc = get_relocatable_from_var_name("point0", vm, ids_data, ap_tracking)?; - - let (point0_x_d0, point0_x_d1, point0_x_d2, point0_y_d0, point0_y_d1, point0_y_d2) = ( - vm.get_integer(point0_reloc)?, - vm.get_integer(point0_reloc + 1i32)?, - vm.get_integer(point0_reloc + 2i32)?, - vm.get_integer(point0_reloc + 3i32)?, - vm.get_integer(point0_reloc + 4i32)?, - vm.get_integer(point0_reloc + 5i32)?, - ); - + let point0 = EcPoint::from_var_name("point0", vm, ids_data, ap_tracking)?; //ids.point1 - let point1_reloc = get_relocatable_from_var_name("point1", vm, ids_data, ap_tracking)?; - - let (point1_x_d0, point1_x_d1, point1_x_d2, point1_y_d0, point1_y_d1, point1_y_d2) = ( - vm.get_integer(point1_reloc)?, - vm.get_integer(point1_reloc + 1i32)?, - vm.get_integer(point1_reloc + 2i32)?, - vm.get_integer(point1_reloc + 3i32)?, - vm.get_integer(point1_reloc + 4i32)?, - vm.get_integer(point1_reloc + 5i32)?, - ); + let point1 = EcPoint::from_var_name("point1", vm, ids_data, ap_tracking)?; let value = line_slope( - &( - pack( - point0_x_d0.as_ref(), - point0_x_d1.as_ref(), - point0_x_d2.as_ref(), - ), - pack( - point0_y_d0.as_ref(), - point0_y_d1.as_ref(), - point0_y_d2.as_ref(), - ), - ), - &( - pack( - point1_x_d0.as_ref(), - point1_x_d1.as_ref(), - point1_x_d2.as_ref(), - ), - pack( - point1_y_d0.as_ref(), - point1_y_d1.as_ref(), - point1_y_d2.as_ref(), - ), - ), + &(pack(point0.x), pack(point0.y)), + &(pack(point1.x), pack(point1.y)), &secp_p, ); exec_scopes.insert_value("value", value.clone()); @@ -217,29 +184,13 @@ pub fn ec_double_assign_new_x( .to_bigint(); //ids.slope - let slope_reloc = get_relocatable_from_var_name("slope", vm, ids_data, ap_tracking)?; - - let (slope_d0, slope_d1, slope_d2) = ( - vm.get_integer(slope_reloc)?, - vm.get_integer(slope_reloc + 1_i32)?, - vm.get_integer(slope_reloc + 2_i32)?, - ); - + let slope = BigInt3::from_var_name("slope", vm, ids_data, ap_tracking)?; //ids.point - let point_reloc = get_relocatable_from_var_name("point", vm, ids_data, ap_tracking)?; - - let (x_d0, x_d1, x_d2, y_d0, y_d1, y_d2) = ( - vm.get_integer(point_reloc)?, - vm.get_integer(point_reloc + 1i32)?, - vm.get_integer(point_reloc + 2i32)?, - vm.get_integer(point_reloc + 3i32)?, - vm.get_integer(point_reloc + 4i32)?, - vm.get_integer(point_reloc + 5i32)?, - ); + let point = EcPoint::from_var_name("point", vm, ids_data, ap_tracking)?; - let slope = pack(slope_d0.as_ref(), slope_d1.as_ref(), slope_d2.as_ref()); - let x = pack(x_d0.as_ref(), x_d1.as_ref(), x_d2.as_ref()); - let y = pack(y_d0.as_ref(), y_d1.as_ref(), y_d2.as_ref()); + let slope = pack(slope); + let x = pack(point.x); + let y = pack(point.y); let value = (slope.pow(2) - (&x << 1u32)).mod_floor(&secp_p); @@ -309,51 +260,16 @@ pub fn fast_ec_add_assign_new_x( .to_bigint(); //ids.slope - let slope_reloc = get_relocatable_from_var_name("slope", vm, ids_data, ap_tracking)?; - - let (slope_d0, slope_d1, slope_d2) = ( - vm.get_integer(slope_reloc)?, - vm.get_integer(slope_reloc + 1i32)?, - vm.get_integer(slope_reloc + 2i32)?, - ); - + let slope = BigInt3::from_var_name("slope", vm, ids_data, ap_tracking)?; //ids.point0 - let point0_reloc = get_relocatable_from_var_name("point0", vm, ids_data, ap_tracking)?; - - let (point0_x_d0, point0_x_d1, point0_x_d2, point0_y_d0, point0_y_d1, point0_y_d2) = ( - vm.get_integer(point0_reloc)?, - vm.get_integer(point0_reloc + 1i32)?, - vm.get_integer(point0_reloc + 2i32)?, - vm.get_integer(point0_reloc + 3i32)?, - vm.get_integer(point0_reloc + 4i32)?, - vm.get_integer(point0_reloc + 5i32)?, - ); - + let point0 = EcPoint::from_var_name("point0", vm, ids_data, ap_tracking)?; //ids.point1.x - let point1_reloc = get_relocatable_from_var_name("point1", vm, ids_data, ap_tracking)?; - - let (point1_x_d0, point1_x_d1, point1_x_d2) = ( - vm.get_integer(point1_reloc)?, - vm.get_integer(point1_reloc + 1i32)?, - vm.get_integer(point1_reloc + 2i32)?, - ); + let point1 = EcPoint::from_var_name("point1", vm, ids_data, ap_tracking)?; - let slope = pack(slope_d0.as_ref(), slope_d1.as_ref(), slope_d2.as_ref()); - let x0 = pack( - point0_x_d0.as_ref(), - point0_x_d1.as_ref(), - point0_x_d2.as_ref(), - ); - let x1 = pack( - point1_x_d0.as_ref(), - point1_x_d1.as_ref(), - point1_x_d2.as_ref(), - ); - let y0 = pack( - point0_y_d0.as_ref(), - point0_y_d1.as_ref(), - point0_y_d2.as_ref(), - ); + let slope = pack(slope); + let x0 = pack(point0.x); + let x1 = pack(point1.x); + let y0 = pack(point0.y); let value = (&slope * &slope - &x0 - &x1).mod_floor(&secp_p); //Assign variables to vm scope @@ -931,4 +847,56 @@ mod tests { //Check hint memory inserts check_memory![vm.segments.memory, ((1, 2), 0)]; } + + #[test] + fn get_ec_point_from_var_name_ok() { + /*EcPoint { + x: (1,2,3) + y: (4,5,6) + }*/ + let mut vm = vm!(); + vm.set_fp(1); + vm.segments = segments![ + ((1, 0), 1), + ((1, 1), 2), + ((1, 2), 3), + ((1, 3), 4), + ((1, 4), 5), + ((1, 5), 6) + ]; + let ids_data = ids_data!["e"]; + let ap_tracking = ApTracking::default(); + let e = EcPoint::from_var_name("e", &vm, &ids_data, &ap_tracking).unwrap(); + assert_eq!(e.x.d0.as_ref(), &Felt::one()); + assert_eq!(e.x.d1.as_ref(), &Felt::from(2)); + assert_eq!(e.x.d2.as_ref(), &Felt::from(3)); + assert_eq!(e.y.d0.as_ref(), &Felt::from(4)); + assert_eq!(e.y.d1.as_ref(), &Felt::from(5)); + assert_eq!(e.y.d2.as_ref(), &Felt::from(6)); + } + + #[test] + fn get_ec_point_from_var_name_missing_member() { + /*EcPoint { + x: (1,2,3) + y: (4,_,_) + }*/ + let mut vm = vm!(); + vm.set_fp(1); + vm.segments = segments![((1, 0), 1), ((1, 1), 2), ((1, 2), 3), ((1, 3), 4)]; + let ids_data = ids_data!["e"]; + let ap_tracking = ApTracking::default(); + let r = EcPoint::from_var_name("e", &vm, &ids_data, &ap_tracking); + assert_matches!(r, Err(HintError::IdentifierHasNoMember(x, y)) if x == "e.y" && y == "d1") + } + + #[test] + fn get_ec_point_from_var_name_invalid_reference() { + let mut vm = vm!(); + vm.segments = segments![((1, 0), 1), ((1, 1), 2)]; + let ids_data = ids_data!["e"]; + let ap_tracking = ApTracking::default(); + let r = EcPoint::from_var_name("e", &vm, &ids_data, &ap_tracking); + assert_matches!(r, Err(HintError::UnknownIdentifier(x)) if x == "e") + } } diff --git a/src/hint_processor/builtin_hint_processor/secp/field_utils.rs b/src/hint_processor/builtin_hint_processor/secp/field_utils.rs index d979046d45..3fb1a80068 100644 --- a/src/hint_processor/builtin_hint_processor/secp/field_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/field_utils.rs @@ -1,4 +1,3 @@ -use super::secp_utils::pack_from_var_name; use crate::{ hint_processor::{ builtin_hint_processor::{ @@ -18,6 +17,8 @@ use num_integer::Integer; use num_traits::{One, Zero}; use std::{collections::HashMap, ops::Shl}; +use super::{bigint_utils::BigInt3, secp_utils::pack}; + /* Implements hint: %{ @@ -41,7 +42,7 @@ pub fn verify_zero( .ok_or(HintError::MissingConstant(SECP_REM))? .to_bigint(); - let val = pack_from_var_name("val", vm, ids_data, ap_tracking)?; + let val = pack(BigInt3::from_var_name("val", vm, ids_data, ap_tracking)?); let (q, r) = val.div_rem(&secp_p); if !r.is_zero() { return Err(HintError::SecpVerifyZero(val)); @@ -72,7 +73,7 @@ pub fn reduce( .ok_or(HintError::MissingConstant(SECP_REM))? .to_bigint(); - let value = pack_from_var_name("x", vm, ids_data, ap_tracking)?; + let value = pack(BigInt3::from_var_name("x", vm, ids_data, ap_tracking)?); exec_scopes.insert_value("value", value.mod_floor(&secp_p)); Ok(()) } @@ -99,7 +100,7 @@ pub fn is_zero_pack( .ok_or(HintError::MissingConstant(SECP_REM))? .to_bigint(); - let x_packed = pack_from_var_name("x", vm, ids_data, ap_tracking)?; + let x_packed = pack(BigInt3::from_var_name("x", vm, ids_data, ap_tracking)?); let x = x_packed.mod_floor(&secp_p); exec_scopes.insert_value("x", x); Ok(()) @@ -386,9 +387,8 @@ mod tests { .map(|(k, v)| (k.to_string(), v)) .collect() ), - Err(HintError::Memory(MemoryError::UnknownMemoryCell( - x - ))) if x == Relocatable::from((1, 20)) + Err(HintError::IdentifierHasNoMember(x, y + )) if x == "x" && y == "d0" ); } @@ -481,9 +481,8 @@ mod tests { .map(|(k, v)| (k.to_string(), v)) .collect() ), - Err(HintError::Memory(MemoryError::UnknownMemoryCell( - x - ))) if x == Relocatable::from((1, 10)) + Err(HintError::IdentifierHasNoMember(x, y + )) if x == "x" && y == "d0" ); } diff --git a/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs b/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs index 9d139e1136..7952efd40b 100644 --- a/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs +++ b/src/hint_processor/builtin_hint_processor/secp/secp_utils.rs @@ -1,18 +1,12 @@ -use crate::{ - hint_processor::{ - builtin_hint_processor::hint_utils::get_relocatable_from_var_name, - hint_processor_definition::HintReference, - }, - serde::deserialize_program::ApTracking, - types::relocatable::Relocatable, - vm::{errors::hint_errors::HintError, vm_core::VirtualMachine}, -}; +use crate::vm::errors::hint_errors::HintError; use felt::Felt; -use num_bigint::BigInt; + use num_traits::Zero; use std::collections::HashMap; use std::ops::Shl; +use super::bigint_utils::BigInt3; + // Constants in package "starkware.cairo.common.cairo_secp.constants". pub const BASE_86: &str = "starkware.cairo.common.cairo_secp.constants.BASE"; pub const BETA: &str = "starkware.cairo.common.cairo_secp.constants.BETA"; @@ -58,41 +52,20 @@ Takes an UnreducedFelt3 struct which represents a triple of limbs (d0, d1, d2) o elements and reconstructs the corresponding 256-bit integer (see split()). Note that the limbs do not have to be in the range [0, BASE). */ -pub fn pack(d0: &Felt, d1: &Felt, d2: &Felt) -> num_bigint::BigInt { - let unreduced_big_int_3 = vec![d0, d1, d2]; - +pub(crate) fn pack(num: BigInt3) -> num_bigint::BigInt { + let limbs = vec![num.d0, num.d1, num.d2]; #[allow(deprecated)] - unreduced_big_int_3 + limbs .into_iter() .enumerate() .map(|(idx, value)| value.to_bigint().shl(idx * 86)) .sum() } -pub fn pack_from_var_name( - name: &str, - vm: &VirtualMachine, - ids_data: &HashMap, - ap_tracking: &ApTracking, -) -> Result { - let to_pack = get_relocatable_from_var_name(name, vm, ids_data, ap_tracking)?; - - let d0 = vm.get_integer(to_pack)?; - let d1 = vm.get_integer(to_pack + 1_usize)?; - let d2 = vm.get_integer(to_pack + 2_usize)?; - Ok(pack(d0.as_ref(), d1.as_ref(), d2.as_ref())) -} - -pub fn pack_from_relocatable(rel: Relocatable, vm: &VirtualMachine) -> Result { - let d0 = vm.get_integer(rel)?; - let d1 = vm.get_integer(rel + 1_usize)?; - let d2 = vm.get_integer(rel + 2_usize)?; - - Ok(pack(d0.as_ref(), d1.as_ref(), d2.as_ref())) -} - #[cfg(test)] mod tests { + use std::borrow::Cow; + use super::*; use crate::utils::test_utils::*; use assert_matches::assert_matches; @@ -172,17 +145,21 @@ mod tests { #[test] fn secp_pack() { - let pack_1 = pack(&Felt::new(10_i32), &Felt::new(10_i32), &Felt::new(10_i32)); + let pack_1 = pack(BigInt3 { + d0: Cow::Borrowed(&Felt::new(10_i32)), + d1: Cow::Borrowed(&Felt::new(10_i32)), + d2: Cow::Borrowed(&Felt::new(10_i32)), + }); assert_eq!( pack_1, bigint_str!("59863107065073783529622931521771477038469668772249610") ); - let pack_2 = pack( - &felt_str!("773712524553362"), - &felt_str!("57408430697461422066401280"), - &felt_str!("1292469707114105"), - ); + let pack_2 = pack(BigInt3 { + d0: Cow::Borrowed(&felt_str!("773712524553362")), + d1: Cow::Borrowed(&felt_str!("57408430697461422066401280")), + d2: Cow::Borrowed(&felt_str!("1292469707114105")), + }); assert_eq!( pack_2, bigint_str!("7737125245533626718119526477371252455336267181195264773712524553362") diff --git a/src/hint_processor/builtin_hint_processor/secp/signature.rs b/src/hint_processor/builtin_hint_processor/secp/signature.rs index 81d067c15d..f3095dbe30 100644 --- a/src/hint_processor/builtin_hint_processor/secp/signature.rs +++ b/src/hint_processor/builtin_hint_processor/secp/signature.rs @@ -2,7 +2,7 @@ use crate::{ hint_processor::{ builtin_hint_processor::{ hint_utils::get_integer_from_var_name, - secp::secp_utils::{pack_from_var_name, BASE_86, BETA, N0, N1, N2, SECP_REM}, + secp::secp_utils::{pack, BASE_86, BETA, N0, N1, N2, SECP_REM}, }, hint_processor_definition::HintReference, }, @@ -21,6 +21,8 @@ use std::{ ops::{Shl, Shr}, }; +use super::bigint_utils::BigInt3; + /* Implements hint: from starkware.cairo.common.cairo_secp.secp_utils import N, pack from starkware.python.math_utils import div_mod, safe_div @@ -36,8 +38,8 @@ pub fn div_mod_n_packed_divmod( ap_tracking: &ApTracking, constants: &HashMap, ) -> Result<(), HintError> { - let a = pack_from_var_name("a", vm, ids_data, ap_tracking)?; - let b = pack_from_var_name("b", vm, ids_data, ap_tracking)?; + let a = pack(BigInt3::from_var_name("a", vm, ids_data, ap_tracking)?); + let b = pack(BigInt3::from_var_name("b", vm, ids_data, ap_tracking)?); #[allow(deprecated)] let n = { @@ -126,7 +128,8 @@ pub fn get_point_from_x( .ok_or(HintError::MissingConstant(SECP_REM))? .to_bigint(); - let x_cube_int = pack_from_var_name("x_cube", vm, ids_data, ap_tracking)?.mod_floor(&secp_p); + let x_cube_int = + pack(BigInt3::from_var_name("x_cube", vm, ids_data, ap_tracking)?).mod_floor(&secp_p); //.mod_floor(&BigInt::from_biguint(num_bigint::Sign::Plus, secp_p.clone())) //.to_biguint().ok_or(VirtualMachineError::BigIntToBigUintFail)?; let y_cube_int = (x_cube_int + beta).mod_floor(&secp_p); diff --git a/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs b/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs index 3e30913506..e24847c735 100644 --- a/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs +++ b/src/hint_processor/builtin_hint_processor/squash_dict_utils.rs @@ -298,7 +298,6 @@ pub fn squash_dict( mod tests { use super::*; use crate::types::relocatable::MaybeRelocatable; - use crate::types::relocatable::Relocatable; use crate::vm::vm_memory::memory_segments::MemorySegmentManager; use crate::{ any_box, @@ -648,9 +647,7 @@ mod tests { //Execute the hint assert_matches!( run_hint!(vm, ids_data, hint_code, &mut exec_scopes), - Err(HintError::Memory(MemoryError::ExpectedInteger( - x - ))) if x == Relocatable::from((1, 0)) + Err(HintError::IdentifierNotInteger(x, y)) if x == "n_used_accesses" && y == (1,0).into() ); } diff --git a/src/hint_processor/hint_processor_utils.rs b/src/hint_processor/hint_processor_utils.rs index e8fbbfba13..04a13ded80 100644 --- a/src/hint_processor/hint_processor_utils.rs +++ b/src/hint_processor/hint_processor_utils.rs @@ -22,11 +22,13 @@ pub fn insert_value_from_reference( hint_reference: &HintReference, ap_tracking: &ApTracking, ) -> Result<(), HintError> { - let var_addr = compute_addr_from_reference(hint_reference, vm, ap_tracking)?; + let var_addr = compute_addr_from_reference(hint_reference, vm, ap_tracking) + .ok_or(HintError::UnknownIdentifierInternal)?; vm.insert_value(var_addr, value).map_err(HintError::Memory) } ///Returns the Integer value stored in the given ids variable +/// Returns an internal error, users should map it into a more informative type pub fn get_integer_from_reference<'a>( vm: &'a VirtualMachine, hint_reference: &'a HintReference, @@ -39,8 +41,10 @@ pub fn get_integer_from_reference<'a>( return Ok(Cow::Borrowed(int_1)); } - let var_addr = compute_addr_from_reference(hint_reference, vm, ap_tracking)?; - vm.get_integer(var_addr).map_err(HintError::Memory) + let var_addr = compute_addr_from_reference(hint_reference, vm, ap_tracking) + .ok_or(HintError::UnknownIdentifierInternal)?; + vm.get_integer(var_addr) + .map_err(|_| HintError::WrongIdentifierTypeInternal(var_addr)) } ///Returns the Relocatable value stored in the given ids variable @@ -49,9 +53,11 @@ pub fn get_ptr_from_reference( hint_reference: &HintReference, ap_tracking: &ApTracking, ) -> Result { - let var_addr = compute_addr_from_reference(hint_reference, vm, ap_tracking)?; + let var_addr = compute_addr_from_reference(hint_reference, vm, ap_tracking) + .ok_or(HintError::UnknownIdentifierInternal)?; if hint_reference.dereference { - Ok(vm.get_relocatable(var_addr)?) + vm.get_relocatable(var_addr) + .map_err(|_| HintError::WrongIdentifierTypeInternal(var_addr)) } else { Ok(var_addr) } @@ -62,20 +68,18 @@ pub fn get_maybe_relocatable_from_reference( vm: &VirtualMachine, hint_reference: &HintReference, ap_tracking: &ApTracking, -) -> Result { +) -> Option { //First handle case on only immediate if let OffsetValue::Immediate(num) = &hint_reference.offset1 { - return Ok(MaybeRelocatable::from(num)); + return Some(MaybeRelocatable::from(num)); } //Then calculate address let var_addr = compute_addr_from_reference(hint_reference, vm, ap_tracking)?; - let value = if hint_reference.dereference { + if hint_reference.dereference { vm.get_maybe(&var_addr) } else { - return Ok(MaybeRelocatable::from(var_addr)); - }; - - value.ok_or(HintError::FailedToGetIds) + Some(MaybeRelocatable::from(var_addr)) + } } ///Computes the memory address of the ids variable indicated by the HintReference as a [Relocatable] @@ -85,7 +89,7 @@ pub fn compute_addr_from_reference( vm: &VirtualMachine, //ApTracking of the Hint itself hint_ap_tracking: &ApTracking, -) -> Result { +) -> Option { let offset1 = if let OffsetValue::Reference(_register, _offset, _deref) = &hint_reference.offset1 { get_offset_value_reference( @@ -94,10 +98,9 @@ pub fn compute_addr_from_reference( hint_ap_tracking, &hint_reference.offset1, )? - .get_relocatable() - .ok_or(HintError::FailedToGetIds)? + .get_relocatable()? } else { - return Err(HintError::NoRegisterInReference); + return None; }; match &hint_reference.offset2 { @@ -111,15 +114,10 @@ pub fn compute_addr_from_reference( &hint_reference.offset2, )?; - Ok(offset1 - + value - .get_int_ref() - .ok_or(HintError::FailedToGetIds)? - .to_usize() - .ok_or(VirtualMachineError::BigintToUsizeFail)?) + Some(offset1 + value.get_int_ref()?.to_usize()?) } - OffsetValue::Value(value) => Ok(offset1 + *value), - _ => Err(HintError::NoRegisterInReference), + OffsetValue::Value(value) => Some(offset1 + *value), + _ => None, } } @@ -127,16 +125,13 @@ fn apply_ap_tracking_correction( ap: Relocatable, ref_ap_tracking: &ApTracking, hint_ap_tracking: &ApTracking, -) -> Result { +) -> Option { // check that both groups are the same if ref_ap_tracking.group != hint_ap_tracking.group { - return Err(HintError::InvalidTrackingGroup( - ref_ap_tracking.group, - hint_ap_tracking.group, - )); + return None; } let ap_diff = hint_ap_tracking.offset - ref_ap_tracking.offset; - ap.sub_usize(ap_diff).map_err(HintError::Internal) + ap.sub_usize(ap_diff).ok() } //Tries to convert a Felt value to usize @@ -155,38 +150,28 @@ fn get_offset_value_reference( hint_reference: &HintReference, hint_ap_tracking: &ApTracking, offset_value: &OffsetValue, -) -> Result { - // let (register, offset , deref) = if let OffsetValue::Reference(register, offset ,deref ) = offset_value { - // (register, offset_value, deref) - // } else { - // return Err(HintError::FailedToGetIds); - // }; +) -> Option { let (register, offset, deref) = match offset_value { OffsetValue::Reference(register, offset, deref) => (register, offset, deref), - _ => return Err(HintError::FailedToGetIds), + _ => return None, }; let base_addr = if register == &Register::FP { vm.get_fp() } else { - let var_ap_trackig = hint_reference - .ap_tracking_data - .as_ref() - .ok_or(HintError::NoneApTrackingData)?; + let var_ap_trackig = hint_reference.ap_tracking_data.as_ref()?; apply_ap_tracking_correction(vm.get_ap(), var_ap_trackig, hint_ap_tracking)? }; if offset.is_negative() && base_addr.offset < offset.unsigned_abs() as usize { - return Err(HintError::FailedToGetIds); + return None; } if *deref { - Ok(vm - .get_maybe(&(base_addr + *offset)) - .ok_or(HintError::FailedToGetIds)?) + vm.get_maybe(&(base_addr + *offset)) } else { - Ok((base_addr + *offset).into()) + Some((base_addr + *offset).into()) } } @@ -228,7 +213,7 @@ mod tests { assert_matches!( get_offset_value_reference(&vm, &hint_ref, &ApTracking::new(), &hint_ref.offset1), - Ok(x) if x == mayberelocatable!(1, 2) + Some(x) if x == mayberelocatable!(1, 2) ); } @@ -241,7 +226,7 @@ mod tests { assert_matches!( get_offset_value_reference(&vm, &hint_ref, &ApTracking::new(), &hint_ref.offset1), - Err(HintError::FailedToGetIds) + None ); } @@ -295,10 +280,7 @@ mod tests { let mut hint_reference = HintReference::new(0, 0, false, false); hint_reference.offset1 = OffsetValue::Immediate(Felt::new(2_i32)); - assert_matches!( - compute_addr_from_reference(&hint_reference, &vm, &ApTracking::new()), - Err(HintError::NoRegisterInReference) - ); + assert!(compute_addr_from_reference(&hint_reference, &vm, &ApTracking::new()).is_none()); } #[test] @@ -311,7 +293,7 @@ mod tests { assert_matches!( compute_addr_from_reference(&hint_reference, &vm, &ApTracking::new()), - Err(HintError::FailedToGetIds) + None ); } @@ -324,7 +306,7 @@ mod tests { assert_matches!( apply_ap_tracking_correction(relocatable!(1, 0), &ref_ap_tracking, &hint_ap_tracking), - Ok(relocatable!(1, 0)) + Some(relocatable!(1, 0)) ); } @@ -335,10 +317,12 @@ mod tests { let mut hint_ap_tracking = ApTracking::new(); hint_ap_tracking.group = 2; - assert_matches!( - apply_ap_tracking_correction(relocatable!(1, 0), &ref_ap_tracking, &hint_ap_tracking), - Err(HintError::InvalidTrackingGroup(1, 2)) - ); + assert!(apply_ap_tracking_correction( + relocatable!(1, 0), + &ref_ap_tracking, + &hint_ap_tracking + ) + .is_none()); } #[test] @@ -348,7 +332,7 @@ mod tests { let hint_ref = HintReference::new_simple(0); assert_matches!( get_maybe_relocatable_from_reference(&vm, &hint_ref, &ApTracking::new()), - Ok(x) if x == mayberelocatable!(0, 0) + Some(x) if x == mayberelocatable!(0, 0) ); } @@ -359,7 +343,7 @@ mod tests { let hint_ref = HintReference::new_simple(0); assert_matches!( get_maybe_relocatable_from_reference(&vm, &hint_ref, &ApTracking::new()), - Err(HintError::FailedToGetIds) + None ); } } diff --git a/src/vm/errors/hint_errors.rs b/src/vm/errors/hint_errors.rs index 02dfdb3481..160d2535ce 100644 --- a/src/vm/errors/hint_errors.rs +++ b/src/vm/errors/hint_errors.rs @@ -12,10 +12,18 @@ use super::{ pub enum HintError { #[error("HintProcessor failed retrieve the compiled data necessary for hint execution")] WrongHintData, - #[error("Failed to get ids for hint execution")] - FailedToGetIds, - #[error("Tried to compute an address but there was no register in the reference.")] - NoRegisterInReference, + #[error("Unknown identifier {0}")] + UnknownIdentifier(String), + #[error("Expected ids.{0} at address {1} to be an Integer value")] + IdentifierNotInteger(String, Relocatable), + #[error("Expected ids.{0} at address {1} to be a Relocatable value")] + IdentifierNotRelocatable(String, Relocatable), + #[error("ids.{0} has no member {1} or it is of incorrect type")] + IdentifierHasNoMember(String, String), + #[error("Unknown identifier")] + UnknownIdentifierInternal, + #[error("Wrong identifier type at address {0}")] + WrongIdentifierTypeInternal(Relocatable), #[error("Custom Hint Error: {0}")] CustomHint(String), #[error("Missing constant: {0}")] diff --git a/src/vm/errors/vm_errors.rs b/src/vm/errors/vm_errors.rs index 46f17d5b13..9467acbb73 100644 --- a/src/vm/errors/vm_errors.rs +++ b/src/vm/errors/vm_errors.rs @@ -142,6 +142,8 @@ pub enum VirtualMachineError { InvalidMemoryValueTemporaryAddress(Relocatable), #[error("accessed_addresses is None.")] MissingAccessedAddresses, + #[error("Unknown memory cell at address {0}")] + UnknownMemoryCell(Relocatable), #[error(transparent)] Other(Box), } diff --git a/src/vm/errors/vm_exception.rs b/src/vm/errors/vm_exception.rs index 7d56819252..070214f72f 100644 --- a/src/vm/errors/vm_exception.rs +++ b/src/vm/errors/vm_exception.rs @@ -180,9 +180,9 @@ fn get_value_from_simple_reference( _ => { // Filer complex types (only felt/felt pointers) match reference.cairo_type { - Some(ref cairo_type) if cairo_type.contains("felt") => { - Some(get_maybe_relocatable_from_reference(vm, &reference, ap_tracking).ok()?) - } + Some(ref cairo_type) if cairo_type.contains("felt") => Some( + get_maybe_relocatable_from_reference(vm, &reference, ap_tracking)?, + ), _ => None, } }