1- use std:: collections:: HashMap ;
1+ use std:: collections:: { HashMap , HashSet } ;
22
33use 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+ }
0 commit comments