Skip to content

Commit 5c73129

Browse files
Improve identifier lookup
1 parent cbd764b commit 5c73129

File tree

13 files changed

+136
-81
lines changed

13 files changed

+136
-81
lines changed

vm/src/hint_processor/builtin_hint_processor/cairo_keccak/keccak_hints.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name,
2+
hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name,
33
serde::deserialize_program::Identifier,
44
stdlib::{
55
borrow::{Cow, ToOwned},
@@ -81,7 +81,7 @@ pub fn compare_bytes_in_word_nondet(
8181
// or too big, which also means n_bytes > BYTES_IN_WORD). The other option is to exctract
8282
// Felt252::from(BYTES_INTO_WORD) into a lazy_static!
8383
let bytes_in_word =
84-
get_constant_from_var_name("BYTES_IN_WORD", identifiers, accessible_scopes)?;
84+
get_constant_from_scoped_name("BYTES_IN_WORD", identifiers, accessible_scopes)?;
8585
let value = Felt252::from((n_bytes < bytes_in_word) as usize);
8686
insert_value_into_ap(vm, value)
8787
}
@@ -105,7 +105,7 @@ pub fn compare_keccak_full_rate_in_bytes_nondet(
105105
let n_bytes = n_bytes.as_ref();
106106

107107
let keccak_full_rate_in_bytes =
108-
get_constant_from_var_name("KECCAK_FULL_RATE_IN_BYTES", identifiers, accessible_scopes)?;
108+
get_constant_from_scoped_name("KECCAK_FULL_RATE_IN_BYTES", identifiers, accessible_scopes)?;
109109
let value = Felt252::from((n_bytes >= keccak_full_rate_in_bytes) as usize);
110110
insert_value_into_ap(vm, value)
111111
}
@@ -139,7 +139,7 @@ pub(crate) fn block_permutation_v1(
139139
accessible_scopes: &[String],
140140
) -> Result<(), HintError> {
141141
let keccak_state_size_felts =
142-
get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?;
142+
get_constant_from_scoped_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?;
143143
if keccak_state_size_felts >= &Felt252::from(100_i32) {
144144
return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new(
145145
*keccak_state_size_felts,
@@ -206,7 +206,7 @@ pub(crate) fn block_permutation_v2(
206206
accessible_scopes: &[String],
207207
) -> Result<(), HintError> {
208208
let keccak_state_size_felts =
209-
get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?;
209+
get_constant_from_scoped_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?;
210210
if keccak_state_size_felts >= &Felt252::from(100_i32) {
211211
return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new(
212212
*keccak_state_size_felts,
@@ -243,8 +243,8 @@ fn cairo_keccak_finalize(
243243
block_size_limit: usize,
244244
) -> Result<(), HintError> {
245245
let keccak_state_size_felts =
246-
get_constant_from_var_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?;
247-
let block_size = get_constant_from_var_name("BLOCK_SIZE", identifiers, accessible_scopes)?;
246+
get_constant_from_scoped_name("KECCAK_STATE_SIZE_FELTS", identifiers, accessible_scopes)?;
247+
let block_size = get_constant_from_scoped_name("BLOCK_SIZE", identifiers, accessible_scopes)?;
248248

249249
if keccak_state_size_felts >= &Felt252::from(100_i32) {
250250
return Err(HintError::InvalidKeccakStateSizeFelt252s(Box::new(

vm/src/hint_processor/builtin_hint_processor/excess_balance.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use lazy_static::lazy_static;
2222
use super::{
2323
dict_manager::DictManager,
2424
hint_utils::{
25-
get_constant_from_var_name, get_integer_from_var_name, get_ptr_from_var_name,
25+
get_constant_from_scoped_name, get_integer_from_var_name, get_ptr_from_var_name,
2626
insert_value_from_var_name,
2727
},
2828
};
@@ -270,7 +270,7 @@ pub fn excess_balance_hint(
270270
let margin_check_type =
271271
get_integer_from_var_name("margin_check_type", vm, ids_data, ap_tracking)?;
272272
let margin_check_initial =
273-
get_constant_from_var_name("MARGIN_CHECK_INITIAL", identifiers, accessible_scopes)?;
273+
get_constant_from_scoped_name("MARGIN_CHECK_INITIAL", identifiers, accessible_scopes)?;
274274
let token_assets_value_d =
275275
get_integer_from_var_name("token_assets_value_d", vm, ids_data, ap_tracking)?;
276276
let account = get_integer_from_var_name("account", vm, ids_data, ap_tracking)?;

vm/src/hint_processor/builtin_hint_processor/hint_utils.rs

Lines changed: 85 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use hashbrown::HashSet;
2+
13
use crate::stdlib::{boxed::Box, collections::HashMap, prelude::*};
24

35
use crate::Felt252;
@@ -182,66 +184,66 @@ pub fn get_identifier_from_scoped_name<'a>(
182184
for scope in accessible_scopes.iter().rev() {
183185
let full_path = format!("{}.{}", scope, scoped_name);
184186

185-
if let Some(identifier) = identifiers.get(&full_path) {
186-
return Ok(identifier);
187-
}
187+
let Some(mut identifier) = identifiers.get(&full_path) else {
188+
// The scoped_name can itself contain multiple components (i.e. a.b.c).
189+
// If there is a match for at least the first component, we should
190+
// not continue with the next scope.
191+
if let Some(first_component) = scoped_name.split('.').next() {
192+
if identifiers
193+
.get(&format!("{}.{}", scope, first_component))
194+
.is_some()
195+
{
196+
break;
197+
}
198+
}
199+
200+
continue;
201+
};
202+
203+
let mut visited_aliases = HashSet::new();
204+
visited_aliases.insert(&full_path);
188205

189-
// The scoped_name can itself contain multiple components (i.e. a.b.c).
190-
// If there is a match for at least the first component, we should
191-
// not continue with the next scope.
192-
if let Some(first_component) = scoped_name.split('.').next() {
193-
if identifiers
194-
.get(&format!("{}.{}", scope, first_component))
195-
.is_some()
196-
{
197-
break;
206+
// If the identifier is of alias type, we resolve the alias.
207+
while identifier.type_.as_deref() == Some("alias") {
208+
let destination = identifier
209+
.destination
210+
.as_ref()
211+
.ok_or_else(|| HintError::UnknownIdentifierInternal)?;
212+
213+
if !visited_aliases.insert(destination) {
214+
return Err(HintError::CyclicAliasing);
198215
}
216+
217+
identifier = identifiers.get(destination).ok_or_else(|| {
218+
HintError::UnknownIdentifier(destination.clone().into_boxed_str())
219+
})?;
199220
}
221+
222+
return Ok(identifier);
200223
}
201224

202225
Err(HintError::UnknownIdentifier(
203226
scoped_name.to_string().into_boxed_str(),
204227
))
205228
}
206229

207-
pub fn get_constant_from_var_name<'a>(
208-
var_name: &str,
230+
pub fn get_constant_from_scoped_name<'a>(
231+
scoped_name: &str,
209232
identifiers: &'a HashMap<String, Identifier>,
210233
accessible_scopes: &[String],
211234
) -> Result<&'a Felt252, HintError> {
212-
for scope in accessible_scopes.iter().rev() {
213-
let full_path = format!("{}.{}", scope, var_name);
214-
let identifier = identifiers.get(&full_path);
215-
216-
let Some(identifier) = identifier else {
217-
continue;
218-
};
219-
220-
let identifier_type = identifier
221-
.type_
235+
let identifier = get_identifier_from_scoped_name(scoped_name, identifiers, accessible_scopes)?;
236+
237+
if identifier.type_.as_deref() != Some("const") {
238+
Err(HintError::MissingConstant(Box::new(
239+
scoped_name.to_string(),
240+
)))
241+
} else {
242+
identifier
243+
.value
222244
.as_ref()
223-
.ok_or_else(|| HintError::MissingConstant(Box::new(var_name.to_string())))?;
224-
225-
match &identifier_type[..] {
226-
"const" => {
227-
return identifier
228-
.value
229-
.as_ref()
230-
.ok_or_else(|| HintError::MissingConstant(Box::new(var_name.to_string())))
231-
}
232-
"alias" => {
233-
let destination = identifier
234-
.destination
235-
.as_ref()
236-
.ok_or_else(|| HintError::MissingConstant(Box::new(var_name.to_string())))?;
237-
238-
return get_constant_from_alias(destination, identifiers);
239-
}
240-
_ => return Err(HintError::MissingConstant(Box::new(var_name.to_string()))),
241-
}
245+
.ok_or_else(|| HintError::MissingConstant(Box::new(scoped_name.to_string())))
242246
}
243-
244-
Err(HintError::MissingConstant(Box::new(var_name.to_string())))
245247
}
246248

247249
pub fn get_constant_from_alias<'a>(
@@ -474,4 +476,42 @@ mod tests {
474476
Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "constant1.constant2"
475477
);
476478
}
479+
480+
#[test]
481+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
482+
fn get_identifier_from_scoped_name_with_alias() {
483+
let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()];
484+
485+
let identifier = const_identifier(5);
486+
let alias = alias_identifier("scope3.constant1");
487+
488+
let identifiers = HashMap::from([
489+
("scope1.scope2.alias1".to_string(), alias.clone()),
490+
("scope3.constant1".to_string(), identifier.clone()),
491+
]);
492+
493+
assert_matches!(
494+
get_identifier_from_scoped_name("alias1", &identifiers, accessible_scopes),
495+
Ok(id) if id == &identifier
496+
);
497+
}
498+
499+
#[test]
500+
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
501+
fn get_identifier_from_scoped_name_with_cyclic_alias() {
502+
let accessible_scopes = &["scope1".to_string(), "scope1.scope2".to_string()];
503+
504+
let alias1 = alias_identifier("scope3.alias2");
505+
let alias2 = alias_identifier("scope1.scope2.alias1");
506+
507+
let identifiers = HashMap::from([
508+
("scope1.scope2.alias1".to_string(), alias1.clone()),
509+
("scope3.alias2".to_string(), alias2.clone()),
510+
]);
511+
512+
assert_matches!(
513+
get_identifier_from_scoped_name("alias1", &identifiers, accessible_scopes),
514+
Err(HintError::CyclicAliasing)
515+
);
516+
}
477517
}

vm/src/hint_processor/builtin_hint_processor/keccak_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use num_integer::Integer;
1919
use num_traits::ToPrimitive;
2020
use sha3::{Digest, Keccak256};
2121

22-
use super::hint_utils::{get_constant_from_var_name, insert_value_from_var_name};
22+
use super::hint_utils::{get_constant_from_scoped_name, insert_value_from_var_name};
2323

2424
/* Implements hint:
2525
%{
@@ -247,7 +247,7 @@ pub fn split_n_bytes(
247247
.ok_or_else(|| HintError::Math(MathError::Felt252ToU64Conversion(Box::new(x))))
248248
})?;
249249
let bytes_in_word =
250-
get_constant_from_var_name("BYTES_IN_WORD", identifiers, accessible_scopes)?;
250+
get_constant_from_scoped_name("BYTES_IN_WORD", identifiers, accessible_scopes)?;
251251
let bytes_in_word = bytes_in_word
252252
.to_u64()
253253
.ok_or_else(|| MathError::Felt252ToU64Conversion(Box::new(*bytes_in_word)))?;

vm/src/hint_processor/builtin_hint_processor/math_utils.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::{
2-
hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name,
2+
hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name,
33
math_utils::signed_felt,
44
serde::deserialize_program::Identifier,
55
stdlib::{boxed::Box, collections::HashMap, prelude::*},
@@ -93,9 +93,9 @@ pub fn assert_le_felt(
9393
accessible_scopes: &[String],
9494
) -> Result<(), HintError> {
9595
let prime_over_3_high =
96-
get_constant_from_var_name("PRIME_OVER_3_HIGH", identifiers, accessible_scopes)?;
96+
get_constant_from_scoped_name("PRIME_OVER_3_HIGH", identifiers, accessible_scopes)?;
9797
let prime_over_2_high =
98-
get_constant_from_var_name("PRIME_OVER_2_HIGH", identifiers, accessible_scopes)?;
98+
get_constant_from_scoped_name("PRIME_OVER_2_HIGH", identifiers, accessible_scopes)?;
9999
let a = get_integer_from_var_name("a", vm, ids_data, ap_tracking)?.to_biguint();
100100
let b = get_integer_from_var_name("b", vm, ids_data, ap_tracking)?.to_biguint();
101101
let range_check_ptr = get_ptr_from_var_name("range_check_ptr", vm, ids_data, ap_tracking)?;
@@ -387,8 +387,8 @@ pub fn split_felt(
387387
.ok_or_else(|| HintError::AssertionFailed(msg.to_string().into_boxed_str()))
388388
};
389389
let bound = pow2_const(128);
390-
let max_high = get_constant_from_var_name("MAX_HIGH", identifiers, accessible_scopes)?;
391-
let max_low = get_constant_from_var_name("MAX_LOW", identifiers, accessible_scopes)?;
390+
let max_high = get_constant_from_scoped_name("MAX_HIGH", identifiers, accessible_scopes)?;
391+
let max_low = get_constant_from_scoped_name("MAX_LOW", identifiers, accessible_scopes)?;
392392
assert(
393393
max_high < &bound && max_low < &bound,
394394
"assert ids.MAX_HIGH < 2**128 and ids.MAX_LOW < 2**128",
@@ -521,8 +521,8 @@ pub fn assert_250_bit(
521521
accessible_scopes: &[String],
522522
) -> Result<(), HintError> {
523523
//Declare constant values
524-
let upper_bound = get_constant_from_var_name("UPPER_BOUND", identifiers, accessible_scopes)?;
525-
let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?;
524+
let upper_bound = get_constant_from_scoped_name("UPPER_BOUND", identifiers, accessible_scopes)?;
525+
let shift = get_constant_from_scoped_name("SHIFT", identifiers, accessible_scopes)?;
526526
let value = Felt252::from(&signed_felt(get_integer_from_var_name(
527527
"value",
528528
vm,
@@ -574,7 +574,7 @@ pub fn is_addr_bounded(
574574
let addr = get_integer_from_var_name("addr", vm, ids_data, ap_tracking)?;
575575

576576
let addr_bound =
577-
get_constant_from_var_name("ADDR_BOUND", identifiers, accessible_scopes)?.to_biguint();
577+
get_constant_from_scoped_name("ADDR_BOUND", identifiers, accessible_scopes)?.to_biguint();
578578

579579
let lower_bound = BigUint::one() << 250_usize;
580580
let upper_bound = BigUint::one() << 251_usize;
@@ -2050,7 +2050,7 @@ mod tests {
20502050
//Execute the hint
20512051
assert_matches!(
20522052
run_hint!(vm, ids_data, hint_code),
2053-
Err(HintError::MissingConstant(bx)) if *bx == "ADDR_BOUND"
2053+
Err(HintError::UnknownIdentifier(bx)) if bx.as_ref() == "ADDR_BOUND"
20542054
);
20552055
}
20562056

@@ -2319,7 +2319,7 @@ mod tests {
23192319
//Execute the hint
23202320
assert_matches!(
23212321
run_hint!(vm, ids_data, hint_code),
2322-
Err(HintError::MissingConstant(x)) if (*x) == "MAX_HIGH"
2322+
Err(HintError::UnknownIdentifier(x)) if x.as_ref() == "MAX_HIGH"
23232323
);
23242324
}
23252325

vm/src/hint_processor/builtin_hint_processor/mod_circuit.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use crate::{
1010
use num_traits::ToPrimitive;
1111

1212
use super::hint_utils::{
13-
get_constant_from_var_name, get_integer_from_var_name, get_ptr_from_var_name,
13+
get_constant_from_scoped_name, get_integer_from_var_name, get_ptr_from_var_name,
1414
};
1515
/* Implements Hint:
1616
%{
@@ -54,7 +54,7 @@ pub fn run_p_mod_circuit_with_large_batch_size(
5454
identifiers: &HashMap<String, Identifier>,
5555
accessible_scopes: &[String],
5656
) -> Result<(), HintError> {
57-
let batch_size = get_constant_from_var_name("BATCH_SIZE", identifiers, accessible_scopes)?;
57+
let batch_size = get_constant_from_scoped_name("BATCH_SIZE", identifiers, accessible_scopes)?;
5858
let batch_size = batch_size
5959
.to_usize()
6060
.ok_or_else(|| MathError::Felt252ToUsizeConversion(Box::new(*batch_size)))?;

vm/src/hint_processor/builtin_hint_processor/secp/bigint_utils.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core::ops::Shl;
22

3-
use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name;
3+
use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name;
44
use crate::hint_processor::builtin_hint_processor::uint_utils::{pack, split};
55
use crate::math_utils::signed_felt;
66
use crate::serde::deserialize_program::Identifier;
@@ -161,7 +161,7 @@ pub fn bigint_to_uint256(
161161
let d1 = vm.get_integer((x_struct + 1_i32)?)?;
162162
let d0 = d0.as_ref();
163163
let d1 = d1.as_ref();
164-
let base_86 = get_constant_from_var_name("BASE", identifiers, accessible_scopes)?;
164+
let base_86 = get_constant_from_scoped_name("BASE", identifiers, accessible_scopes)?;
165165
let mask = pow2_const_nz(128);
166166
let low = (d0 + (d1 * base_86)).mod_floor(mask);
167167
insert_value_from_var_name("low", low, vm, ids_data, ap_tracking)

vm/src/hint_processor/builtin_hint_processor/secp/cairo0_hints.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::{
99

1010
use crate::define_hint_string_map;
1111
use crate::hint_processor::builtin_hint_processor::hint_utils::{
12-
get_constant_from_var_name, get_integer_from_var_name, insert_value_from_var_name,
12+
get_constant_from_scoped_name, get_integer_from_var_name, insert_value_from_var_name,
1313
};
1414
use crate::hint_processor::builtin_hint_processor::uint256_utils::Uint256;
1515
use crate::hint_processor::hint_processor_definition::HintReference;
@@ -176,8 +176,8 @@ pub fn compute_ids_high_low(
176176
) -> Result<(), HintError> {
177177
exec_scopes.insert_value::<BigInt>("SECP256R1_P", SECP256R1_P.clone());
178178

179-
let upper_bound = get_constant_from_var_name("UPPER_BOUND", identifiers, accessible_scopes)?;
180-
let shift = get_constant_from_var_name("SHIFT", identifiers, accessible_scopes)?;
179+
let upper_bound = get_constant_from_scoped_name("UPPER_BOUND", identifiers, accessible_scopes)?;
180+
let shift = get_constant_from_scoped_name("SHIFT", identifiers, accessible_scopes)?;
181181
let value = Felt252::from(&signed_felt(get_integer_from_var_name(
182182
"value",
183183
vm,

vm/src/hint_processor/builtin_hint_processor/secp/signature.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_var_name;
1+
use crate::hint_processor::builtin_hint_processor::hint_utils::get_constant_from_scoped_name;
22
use crate::serde::deserialize_program::Identifier;
33
use crate::{
44
any_box,
@@ -111,7 +111,7 @@ pub fn get_point_from_x(
111111
accessible_scopes: &[String],
112112
) -> Result<(), HintError> {
113113
exec_scopes.insert_value("SECP_P", SECP_P.clone());
114-
let beta = get_constant_from_var_name("BETA", identifiers, accessible_scopes)?.to_bigint();
114+
let beta = get_constant_from_scoped_name("BETA", identifiers, accessible_scopes)?.to_bigint();
115115

116116
let x_cube_int = Uint384::from_var_name("x_cube", vm, ids_data, ap_tracking)?
117117
.pack86()

0 commit comments

Comments
 (0)