Skip to content

Commit e6c0fb5

Browse files
starknet_os: aliases test
1 parent d07b00f commit e6c0fb5

File tree

5 files changed

+128
-16
lines changed

5 files changed

+128
-16
lines changed

crates/starknet_os/src/hint_processor/snos_hint_processor.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,15 +341,17 @@ impl<'a> SnosHintProcessor<'a, DictStateReader> {
341341
let state_inputs = vec![os_state_input.unwrap_or_default()];
342342
let os_hints_config = os_hints_config.unwrap_or_default();
343343

344-
SnosHintProcessor::new(
344+
let mut hint_processor = SnosHintProcessor::new(
345345
os_program,
346346
os_hints_config,
347347
block_inputs,
348348
state_inputs,
349349
BTreeMap::new(),
350350
BTreeMap::new(),
351351
vec![state_reader],
352-
)
352+
)?;
353+
hint_processor.execution_helpers_manager.increment_current_helper_index();
354+
Ok(hint_processor)
353355
}
354356
}
355357

crates/starknet_os/src/test_utils/cairo_runner.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::any::Any;
22
use std::collections::{HashMap, HashSet};
33

44
use blockifier::blockifier_versioned_constants::VersionedConstants;
5+
use blockifier::test_utils::dict_state_reader::DictStateReader;
56
use cairo_vm::serde::deserialize_program::Member;
67
use cairo_vm::types::builtin_name::BuiltinName;
78
use cairo_vm::types::layout_name::LayoutName;
@@ -553,6 +554,7 @@ fn get_return_values(
553554
/// Hint locals are added to the outermost exec scope.
554555
/// If the endpoint used builtins, the respective returned (implicit) arg is the builtin instance
555556
/// usage, unless the builtin is the output builtin, in which case the arg is the output.
557+
#[allow(clippy::too_many_arguments)]
556558
pub fn run_cairo_0_entry_point(
557559
runner_config: &EntryPointRunnerConfig,
558560
program_bytes: &[u8],
@@ -561,6 +563,7 @@ pub fn run_cairo_0_entry_point(
561563
implicit_args: &[ImplicitArg],
562564
expected_explicit_return_values: &[EndpointArg],
563565
hint_locals: HashMap<String, Box<dyn Any>>,
566+
state_reader: Option<DictStateReader>,
564567
) -> Cairo0EntryPointRunnerResult<(Vec<EndpointArg>, Vec<EndpointArg>, CairoRunner)> {
565568
let mut entrypoint = entrypoint.to_string();
566569
if runner_config.add_main_prefix_to_entrypoint {
@@ -571,7 +574,7 @@ pub fn run_cairo_0_entry_point(
571574
let program = inject_builtins(program_bytes, implicit_args)?;
572575
info!("Successfully injected builtins into program.");
573576

574-
let (state_reader, os_hints_config, os_state_input) = (None, None, None);
577+
let (os_hints_config, os_state_input) = (None, None);
575578
let os_block_input = OsBlockInput::default();
576579
let mut hint_processor = SnosHintProcessor::new_for_testing(
577580
state_reader,

crates/starknet_os/src/test_utils/utils.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::any::Any;
22
use std::collections::HashMap;
33
use std::sync::LazyLock;
44

5+
use cairo_vm::types::layout_name::LayoutName;
56
use ethnum::U256;
67
use num_bigint::{BigInt, Sign};
78
use rand::rngs::StdRng;
@@ -38,6 +39,7 @@ pub fn run_cairo_function_and_check_result(
3839
implicit_args,
3940
expected_explicit_retdata,
4041
hint_locals,
42+
None,
4143
)?;
4244
assert_eq!(expected_explicit_retdata, &actual_explicit_retdata);
4345
assert_eq!(expected_implicit_retdata, &actual_implicit_retdata);
@@ -123,3 +125,11 @@ pub fn pack_bigint3(limbs: &[Felt]) -> BigInt {
123125
acc + as_int(&limb, &DEFAULT_PRIME) * BASE.pow(i.try_into().unwrap())
124126
})
125127
}
128+
129+
pub(crate) fn get_entrypoint_runner_config() -> EntryPointRunnerConfig {
130+
EntryPointRunnerConfig {
131+
layout: LayoutName::small,
132+
add_main_prefix_to_entrypoint: false,
133+
..Default::default()
134+
}
135+
}

crates/starknet_os/src/tests/aliases.rs

Lines changed: 108 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,26 @@
1-
use std::collections::HashMap;
1+
use std::collections::{HashMap, HashSet};
22

33
use apollo_starknet_os_program::test_programs::ALIASES_TEST_BYTES;
4+
use blockifier::state::stateful_compression::{ALIAS_COUNTER_STORAGE_KEY, INITIAL_AVAILABLE_ALIAS};
5+
use blockifier::test_utils::dict_state_reader::DictStateReader;
6+
use cairo_vm::hint_processor::builtin_hint_processor::dict_hint_utils::DICT_ACCESS_SIZE;
7+
use cairo_vm::hint_processor::hint_processor_utils::felt_to_usize;
8+
use cairo_vm::types::builtin_name::BuiltinName;
9+
use rstest::rstest;
10+
use starknet_api::core::{ContractAddress, L2_ADDRESS_UPPER_BOUND};
11+
use starknet_api::state::StorageKey;
12+
use starknet_types_core::felt::Felt;
13+
14+
use crate::test_utils::cairo_runner::{
15+
run_cairo_0_entry_point,
16+
EndpointArg,
17+
EntryPointRunnerConfig,
18+
ImplicitArg,
19+
PointerArg,
20+
ValueArg,
21+
};
22+
use crate::test_utils::utils::{get_entrypoint_runner_config, test_cairo_function};
423

5-
use crate::test_utils::cairo_runner::EntryPointRunnerConfig;
6-
use crate::test_utils::utils::test_cairo_function;
724
// TODO(Nimrod): Move this next to the stateful compression hints implementation.
825
// TODO(Amos): This test is incomplete. Add the rest of the test cases and remove this todo.
926

@@ -29,3 +46,91 @@ fn test_constants() {
2946
HashMap::new(),
3047
)
3148
}
49+
50+
#[rstest]
51+
#[case(Vec::new(), Vec::new(), HashMap::from([(0.into(), 128.into())]))]
52+
#[case(vec![Felt::from(&*L2_ADDRESS_UPPER_BOUND)], vec![128], HashMap::from([(0.into(), 129.into()), (Felt::from(&*L2_ADDRESS_UPPER_BOUND), 128.into())]))]
53+
#[case(vec![2000.into(), 1999999999.into(), 3000.into(), 2000.into()], vec![128, 129, 130, 128], HashMap::from([(0.into(), 131.into()), (2000.into(), 128.into()), (3000.into(), 130.into()), (1999999999.into(), 129.into())]))]
54+
#[case(Vec::from_iter((0..128).map(Felt::from)), (0..128).collect::<Vec<_>>(), HashMap::from_iter([(0.into(), 128.into())]))]
55+
#[case(Vec::from_iter((0..129).map(Felt::from)), (0..129).collect::<Vec<_>>(), HashMap::from_iter([(0.into(), 129.into()), (128.into(), 128.into())]))]
56+
#[case(vec![13.into(), 500.into(), 11.into(), 2000.into(), 2001.into(), 13.into(), 501.into(), 98.into(), 222.into(), 2000.into(), 127.into(), 128.into()], vec![13, 128, 11, 129, 130, 13, 131, 98, 132, 129, 127, 133], HashMap::from([(0.into(), 134.into()), (128.into(), 133.into()), (222.into(), 132.into()), (500.into(), 128.into()), (501.into(), 131.into()), (2000.into(), 129.into()), (2001.into(), 130.into())]))]
57+
fn allocate_and_replace_keys_from_empty_storage(
58+
#[case] keys: Vec<Felt>,
59+
#[case] expected_alias_per_key: Vec<u128>,
60+
#[case] expected_alias_storage: HashMap<Felt, Felt>,
61+
) {
62+
let expected_alias_per_key: Vec<_> =
63+
expected_alias_per_key.into_iter().map(Felt::from).collect();
64+
let (actual_alias_storage, actual_alias_per_key) =
65+
allocate_aliases_for_keys_and_replace(keys, HashMap::new());
66+
67+
assert_eq!(actual_alias_storage, expected_alias_storage);
68+
assert_eq!(actual_alias_per_key, expected_alias_per_key);
69+
}
70+
71+
fn allocate_aliases_for_keys_and_replace(
72+
keys: Vec<Felt>,
73+
initial_storage: HashMap<StorageKey, Felt>,
74+
) -> (HashMap<Felt, Felt>, Vec<Felt>) {
75+
let runner_config = get_entrypoint_runner_config();
76+
let entrypoint = "__main__.allocate_alias_for_keys_and_replace";
77+
let implicit_args = [ImplicitArg::Builtin(BuiltinName::range_check)];
78+
let unique_keys: HashSet<Felt> = HashSet::from_iter(
79+
keys.iter()
80+
.filter(|key| key >= &&INITIAL_AVAILABLE_ALIAS)
81+
.copied()
82+
.chain([*ALIAS_COUNTER_STORAGE_KEY.key()]),
83+
);
84+
let expected_explicit_return_values = vec![
85+
EndpointArg::Value(ValueArg::Single(Felt::ZERO)), // Aliases.len
86+
EndpointArg::Pointer(PointerArg::Array(vec![ // Aliases.ptr
87+
Felt::ZERO;
88+
(unique_keys.len()) * DICT_ACCESS_SIZE
89+
])),
90+
EndpointArg::Pointer(PointerArg::Array(vec![Felt::ZERO; keys.len()])),
91+
];
92+
let n_keys_arg = EndpointArg::Value(ValueArg::Single(keys.len().into()));
93+
let keys_arg = EndpointArg::Pointer(PointerArg::Array(keys));
94+
let explicit_args = vec![n_keys_arg, keys_arg];
95+
let alias_contract_address: ContractAddress = Felt::TWO.try_into().unwrap();
96+
let storage_view = initial_storage
97+
.into_iter()
98+
.map(|(key, value)| ((alias_contract_address, key), value))
99+
.collect();
100+
101+
let state_reader = DictStateReader { storage_view, ..Default::default() };
102+
let (_, explicit_return_values, _) = run_cairo_0_entry_point(
103+
&runner_config,
104+
ALIASES_TEST_BYTES,
105+
entrypoint,
106+
&explicit_args,
107+
&implicit_args,
108+
&expected_explicit_return_values,
109+
HashMap::new(),
110+
Some(state_reader),
111+
)
112+
.unwrap();
113+
let mut actual_alias_storage = HashMap::new();
114+
if let [
115+
EndpointArg::Value(ValueArg::Single(n_aliases)),
116+
EndpointArg::Pointer(PointerArg::Array(aliases_storage_updates)),
117+
EndpointArg::Pointer(PointerArg::Array(alias_per_key)),
118+
] = explicit_return_values.as_slice()
119+
{
120+
let n_aliases = felt_to_usize(n_aliases).unwrap();
121+
assert!(aliases_storage_updates.len() % DICT_ACCESS_SIZE == 0);
122+
assert!(aliases_storage_updates.len() / DICT_ACCESS_SIZE == n_aliases);
123+
let key_offset = 0;
124+
let new_value_offset = 2;
125+
for i in 0..n_aliases {
126+
let key = aliases_storage_updates[i * DICT_ACCESS_SIZE + key_offset];
127+
let new_value = aliases_storage_updates[i * DICT_ACCESS_SIZE + new_value_offset];
128+
actual_alias_storage.insert(key, new_value);
129+
}
130+
(actual_alias_storage, alias_per_key.clone().to_vec())
131+
} else {
132+
panic!(
133+
"The return value doesn't match the given format.\n Got: {explicit_return_values:?}"
134+
);
135+
}
136+
}

crates/starknet_os/src/tests/bls_field.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use std::collections::HashMap;
33

44
use apollo_starknet_os_program::OS_PROGRAM_BYTES;
55
use cairo_vm::types::builtin_name::BuiltinName;
6-
use cairo_vm::types::layout_name::LayoutName;
76
use cairo_vm::types::program::Program;
87
use ethnum::U256;
98
use num_bigint::{BigInt, BigUint, RandBigInt, RandomBits, Sign, ToBigInt};
@@ -16,12 +15,12 @@ use crate::hints::hint_implementation::kzg::utils::{split_bigint3, BASE, BLS_PRI
1615
use crate::test_utils::cairo_runner::{
1716
run_cairo_0_entry_point,
1817
EndpointArg,
19-
EntryPointRunnerConfig,
2018
ImplicitArg,
2119
PointerArg,
2220
ValueArg,
2321
};
2422
use crate::test_utils::utils::{
23+
get_entrypoint_runner_config,
2524
pack_bigint3,
2625
seeded_random_prng,
2726
test_cairo_function,
@@ -32,14 +31,6 @@ const REDUCED_MUL_LIMB_BOUND: i128 = 2_i128.pow(104);
3231

3332
// TODO(Nimrod): Move this next to the BLS hints implementation.
3433

35-
fn get_entrypoint_runner_config() -> EntryPointRunnerConfig {
36-
EntryPointRunnerConfig {
37-
layout: LayoutName::small,
38-
add_main_prefix_to_entrypoint: false,
39-
..Default::default()
40-
}
41-
}
42-
4334
fn run_reduced_mul_test(a_split: &[Felt], b_split: &[Felt]) {
4435
let explicit_args = [
4536
EndpointArg::Value(ValueArg::Array(a_split.to_vec())),
@@ -159,6 +150,7 @@ fn test_horner_eval() {
159150
&implicit_args,
160151
&[EndpointArg::Value(ValueArg::Array(vec![Felt::ZERO, Felt::ZERO, Felt::ZERO]))],
161152
HashMap::new(),
153+
None,
162154
)
163155
.unwrap();
164156

0 commit comments

Comments
 (0)