Skip to content

Commit d2492d4

Browse files
starknet_os: aliases test
1 parent 5202af2 commit d2492d4

File tree

5 files changed

+186
-16
lines changed

5 files changed

+186
-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: 11 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;
@@ -30,6 +31,7 @@ pub fn run_cairo_function_and_check_result(
3031
expected_implicit_retdata: &[EndpointArg],
3132
hint_locals: HashMap<String, Box<dyn Any>>,
3233
) -> Cairo0EntryPointRunnerResult<()> {
34+
let state_reader = None;
3335
let (actual_implicit_retdata, actual_explicit_retdata, _) = run_cairo_0_entry_point(
3436
runner_config,
3537
program_bytes,
@@ -38,6 +40,7 @@ pub fn run_cairo_function_and_check_result(
3840
implicit_args,
3941
expected_explicit_retdata,
4042
hint_locals,
43+
state_reader,
4144
)?;
4245
assert_eq!(expected_explicit_retdata, &actual_explicit_retdata);
4346
assert_eq!(expected_implicit_retdata, &actual_implicit_retdata);
@@ -123,3 +126,11 @@ pub fn pack_bigint3(limbs: &[Felt]) -> BigInt {
123126
acc + as_int(&limb, &DEFAULT_PRIME) * BASE.pow(i.try_into().unwrap())
124127
})
125128
}
129+
130+
pub(crate) fn get_entrypoint_runner_config() -> EntryPointRunnerConfig {
131+
EntryPointRunnerConfig {
132+
layout: LayoutName::small,
133+
add_main_prefix_to_entrypoint: false,
134+
..Default::default()
135+
}
136+
}

crates/starknet_os/src/tests/aliases.rs

Lines changed: 164 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,147 @@ fn test_constants() {
2946
HashMap::new(),
3047
)
3148
}
49+
50+
#[rstest]
51+
#[case(
52+
Vec::new(),
53+
Vec::new(),
54+
HashMap::from([(0.into(), 128.into())])
55+
)]
56+
#[case(
57+
vec![Felt::from(&*L2_ADDRESS_UPPER_BOUND)],
58+
vec![128],
59+
HashMap::from([
60+
(0.into(), 129.into()),
61+
(Felt::from(&*L2_ADDRESS_UPPER_BOUND), 128.into())
62+
])
63+
)]
64+
#[case(
65+
vec![2000.into(), 1999999999.into(), 3000.into(), 2000.into()],
66+
vec![128, 129, 130, 128],
67+
HashMap::from([
68+
(0.into(), 131.into()),
69+
(2000.into(), 128.into()),
70+
(3000.into(), 130.into()),
71+
(1999999999.into(), 129.into())
72+
])
73+
)]
74+
#[case(
75+
Vec::from_iter((0..128).map(Felt::from)),
76+
(0..128).collect::<Vec<_>>(),
77+
HashMap::from_iter([(0.into(), 128.into())])
78+
)]
79+
#[case(
80+
Vec::from_iter((0..129).map(Felt::from)),
81+
(0..129).collect::<Vec<_>>(),
82+
HashMap::from_iter([
83+
(0.into(), 129.into()),
84+
(128.into(), 128.into())
85+
])
86+
)]
87+
#[case(
88+
vec![
89+
13.into(),
90+
500.into(),
91+
11.into(),
92+
2000.into(),
93+
2001.into(),
94+
13.into(),
95+
501.into(),
96+
98.into(),
97+
222.into(),
98+
2000.into(),
99+
127.into(),
100+
128.into()
101+
],
102+
vec![13, 128, 11, 129, 130, 13, 131, 98, 132, 129, 127, 133],
103+
HashMap::from([
104+
(0.into(), 134.into()),
105+
(128.into(), 133.into()),
106+
(222.into(), 132.into()),
107+
(500.into(), 128.into()),
108+
(501.into(), 131.into()),
109+
(2000.into(), 129.into()),
110+
(2001.into(), 130.into())
111+
])
112+
)]
113+
fn allocate_and_replace_keys_from_empty_storage(
114+
#[case] keys: Vec<Felt>,
115+
#[case] expected_alias_per_key: Vec<u128>,
116+
#[case] expected_alias_storage: HashMap<Felt, Felt>,
117+
) {
118+
let expected_alias_per_key: Vec<_> =
119+
expected_alias_per_key.into_iter().map(Felt::from).collect();
120+
let (actual_alias_storage, actual_alias_per_key) =
121+
allocate_aliases_for_keys_and_replace(keys, HashMap::new());
122+
123+
assert_eq!(actual_alias_storage, expected_alias_storage);
124+
assert_eq!(actual_alias_per_key, expected_alias_per_key);
125+
}
126+
127+
fn allocate_aliases_for_keys_and_replace(
128+
keys: Vec<Felt>,
129+
initial_storage: HashMap<StorageKey, Felt>,
130+
) -> (HashMap<Felt, Felt>, Vec<Felt>) {
131+
let runner_config = get_entrypoint_runner_config();
132+
let entrypoint = "__main__.allocate_alias_for_keys_and_replace";
133+
let implicit_args = [ImplicitArg::Builtin(BuiltinName::range_check)];
134+
let unique_keys: HashSet<Felt> = HashSet::from_iter(
135+
keys.iter()
136+
.filter(|key| key >= &&INITIAL_AVAILABLE_ALIAS)
137+
.copied()
138+
.chain([*ALIAS_COUNTER_STORAGE_KEY.key()]),
139+
);
140+
let expected_explicit_return_values = vec![
141+
EndpointArg::Value(ValueArg::Single(Felt::ZERO)), // Aliases.len
142+
EndpointArg::Pointer(PointerArg::Array(vec![ // Aliases.ptr
143+
Felt::ZERO;
144+
(unique_keys.len()) * DICT_ACCESS_SIZE
145+
])),
146+
EndpointArg::Pointer(PointerArg::Array(vec![Felt::ZERO; keys.len()])),
147+
];
148+
let n_keys_arg = EndpointArg::Value(ValueArg::Single(keys.len().into()));
149+
let keys_arg = EndpointArg::Pointer(PointerArg::Array(keys));
150+
let explicit_args = vec![n_keys_arg, keys_arg];
151+
let alias_contract_address: ContractAddress = Felt::TWO.try_into().unwrap();
152+
let storage_view = initial_storage
153+
.into_iter()
154+
.map(|(key, value)| ((alias_contract_address, key), value))
155+
.collect();
156+
157+
let state_reader = DictStateReader { storage_view, ..Default::default() };
158+
let (_, explicit_return_values, _) = run_cairo_0_entry_point(
159+
&runner_config,
160+
ALIASES_TEST_BYTES,
161+
entrypoint,
162+
&explicit_args,
163+
&implicit_args,
164+
&expected_explicit_return_values,
165+
HashMap::new(),
166+
Some(state_reader),
167+
)
168+
.unwrap();
169+
let mut actual_alias_storage = HashMap::new();
170+
if let [
171+
EndpointArg::Value(ValueArg::Single(n_aliases)),
172+
EndpointArg::Pointer(PointerArg::Array(aliases_storage_updates)),
173+
EndpointArg::Pointer(PointerArg::Array(alias_per_key)),
174+
] = explicit_return_values.as_slice()
175+
{
176+
let n_aliases = felt_to_usize(n_aliases).unwrap();
177+
assert!(aliases_storage_updates.len() % DICT_ACCESS_SIZE == 0);
178+
assert!(aliases_storage_updates.len() / DICT_ACCESS_SIZE == n_aliases);
179+
let key_offset = 0;
180+
let new_value_offset = 2;
181+
for i in 0..n_aliases {
182+
let key = aliases_storage_updates[i * DICT_ACCESS_SIZE + key_offset];
183+
let new_value = aliases_storage_updates[i * DICT_ACCESS_SIZE + new_value_offset];
184+
actual_alias_storage.insert(key, new_value);
185+
}
186+
(actual_alias_storage, alias_per_key.clone().to_vec())
187+
} else {
188+
panic!(
189+
"The return value doesn't match the given format.\n Got: {explicit_return_values:?}"
190+
);
191+
}
192+
}

crates/starknet_os/src/tests/bls_field.rs

Lines changed: 3 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())),
@@ -151,6 +142,7 @@ fn test_horner_eval() {
151142
)));
152143
let implicit_args = [ImplicitArg::Builtin(BuiltinName::range_check)];
153144

145+
let state_reader = None;
154146
let (_, explicit_retdata, _) = run_cairo_0_entry_point(
155147
&entrypoint_runner_config,
156148
OS_PROGRAM_BYTES,
@@ -159,6 +151,7 @@ fn test_horner_eval() {
159151
&implicit_args,
160152
&[EndpointArg::Value(ValueArg::Array(vec![Felt::ZERO, Felt::ZERO, Felt::ZERO]))],
161153
HashMap::new(),
154+
state_reader,
162155
)
163156
.unwrap();
164157

0 commit comments

Comments
 (0)