Skip to content

Commit c2ddcba

Browse files
starknet_os: aliases test
1 parent 60073ba commit c2ddcba

File tree

5 files changed

+127
-16
lines changed

5 files changed

+127
-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);
@@ -122,3 +124,11 @@ pub fn pack_bigint3(limbs: &[Felt]) -> BigInt {
122124
acc + as_int(&limb, &DEFAULT_PRIME) * BASE.pow(i.try_into().unwrap())
123125
})
124126
}
127+
128+
pub(crate) fn get_entrypoint_runner_config() -> EntryPointRunnerConfig {
129+
EntryPointRunnerConfig {
130+
layout: LayoutName::small,
131+
add_main_prefix_to_entrypoint: false,
132+
..Default::default()
133+
}
134+
}

crates/starknet_os/src/tests/aliases.rs

Lines changed: 107 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,25 @@
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;
413

5-
use crate::test_utils::cairo_runner::EntryPointRunnerConfig;
6-
use crate::test_utils::utils::test_cairo_function;
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};
723

824
// TODO(Amos): This test is incomplete. Add the rest of the test cases and remove this todo.
925

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

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};
@@ -15,12 +14,12 @@ use crate::hints::hint_implementation::kzg::utils::{split_bigint3, BASE, BLS_PRI
1514
use crate::test_utils::cairo_runner::{
1615
run_cairo_0_entry_point,
1716
EndpointArg,
18-
EntryPointRunnerConfig,
1917
ImplicitArg,
2018
PointerArg,
2119
ValueArg,
2220
};
2321
use crate::test_utils::utils::{
22+
get_entrypoint_runner_config,
2423
pack_bigint3,
2524
seeded_random_prng,
2625
test_cairo_function,
@@ -29,14 +28,6 @@ use crate::test_utils::utils::{
2928

3029
const REDUCED_MUL_LIMB_BOUND: i128 = 2_i128.pow(104);
3130

32-
fn get_entrypoint_runner_config() -> EntryPointRunnerConfig {
33-
EntryPointRunnerConfig {
34-
layout: LayoutName::small,
35-
add_main_prefix_to_entrypoint: false,
36-
..Default::default()
37-
}
38-
}
39-
4031
fn run_reduced_mul_test(a_split: &[Felt], b_split: &[Felt]) {
4132
let explicit_args = [
4233
EndpointArg::Value(ValueArg::Array(a_split.to_vec())),
@@ -155,6 +146,7 @@ fn test_horner_eval() {
155146
&implicit_args,
156147
&[EndpointArg::Value(ValueArg::Array(vec![Felt::ZERO, Felt::ZERO, Felt::ZERO]))],
157148
HashMap::new(),
149+
None,
158150
)
159151
.unwrap();
160152

0 commit comments

Comments
 (0)