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 blockifier:: test_utils:: ALIAS_CONTRACT_ADDRESS ;
7+ use cairo_vm:: hint_processor:: builtin_hint_processor:: dict_hint_utils:: DICT_ACCESS_SIZE ;
8+ use cairo_vm:: hint_processor:: hint_processor_utils:: felt_to_usize;
9+ use cairo_vm:: types:: builtin_name:: BuiltinName ;
10+ use rstest:: rstest;
11+ use starknet_api:: core:: L2_ADDRESS_UPPER_BOUND ;
12+ use starknet_api:: state:: StorageKey ;
13+ use starknet_types_core:: felt:: Felt ;
14+
15+ use crate :: test_utils:: cairo_runner:: {
16+ run_cairo_0_entry_point,
17+ EndpointArg ,
18+ EntryPointRunnerConfig ,
19+ ImplicitArg ,
20+ PointerArg ,
21+ ValueArg ,
22+ } ;
23+ use crate :: test_utils:: utils:: {
24+ get_entrypoint_runner_config,
25+ parse_squashed_cairo_dict,
26+ test_cairo_function,
27+ } ;
428
5- use crate :: test_utils:: cairo_runner:: EntryPointRunnerConfig ;
6- use crate :: test_utils:: utils:: test_cairo_function;
729// TODO(Nimrod): Move this next to the stateful compression hints implementation.
830// TODO(Amos): This test is incomplete. Add the rest of the test cases and remove this todo.
931
@@ -29,3 +51,153 @@ fn test_constants() {
2951 HashMap :: new ( ) ,
3052 )
3153}
54+
55+ #[ rstest]
56+ #[ case(
57+ Vec :: new( ) ,
58+ Vec :: new( ) ,
59+ HashMap :: from( [ ( 0 . into( ) , 128 . into( ) ) ] )
60+ ) ]
61+ #[ case(
62+ vec![ Felt :: from( & * L2_ADDRESS_UPPER_BOUND ) ] ,
63+ vec![ 128 ] ,
64+ HashMap :: from( [
65+ ( 0 . into( ) , 129 . into( ) ) ,
66+ ( Felt :: from( & * L2_ADDRESS_UPPER_BOUND ) , 128 . into( ) )
67+ ] )
68+ ) ]
69+ #[ case(
70+ vec![ 2000 . into( ) , 1999999999 . into( ) , 3000 . into( ) , 2000 . into( ) ] ,
71+ vec![ 128 , 129 , 130 , 128 ] ,
72+ HashMap :: from( [
73+ ( 0 . into( ) , 131 . into( ) ) ,
74+ ( 2000 . into( ) , 128 . into( ) ) ,
75+ ( 3000 . into( ) , 130 . into( ) ) ,
76+ ( 1999999999 . into( ) , 129 . into( ) )
77+ ] )
78+ ) ]
79+ #[ case(
80+ Vec :: from_iter( ( 0 ..128 ) . map( Felt :: from) ) ,
81+ ( 0 ..128 ) . collect:: <Vec <_>>( ) ,
82+ HashMap :: from_iter( [ ( 0 . into( ) , 128 . into( ) ) ] )
83+ ) ]
84+ #[ case(
85+ Vec :: from_iter( ( 0 ..129 ) . map( Felt :: from) ) ,
86+ ( 0 ..129 ) . collect:: <Vec <_>>( ) ,
87+ HashMap :: from_iter( [
88+ ( 0 . into( ) , 129 . into( ) ) ,
89+ ( 128 . into( ) , 128 . into( ) )
90+ ] )
91+ ) ]
92+ #[ case(
93+ vec![
94+ 13 . into( ) ,
95+ 500 . into( ) ,
96+ 11 . into( ) ,
97+ 2000 . into( ) ,
98+ 2001 . into( ) ,
99+ 13 . into( ) ,
100+ 501 . into( ) ,
101+ 98 . into( ) ,
102+ 222 . into( ) ,
103+ 2000 . into( ) ,
104+ 127 . into( ) ,
105+ 128 . into( )
106+ ] ,
107+ vec![ 13 , 128 , 11 , 129 , 130 , 13 , 131 , 98 , 132 , 129 , 127 , 133 ] ,
108+ HashMap :: from( [
109+ ( 0 . into( ) , 134 . into( ) ) ,
110+ ( 128 . into( ) , 133 . into( ) ) ,
111+ ( 222 . into( ) , 132 . into( ) ) ,
112+ ( 500 . into( ) , 128 . into( ) ) ,
113+ ( 501 . into( ) , 131 . into( ) ) ,
114+ ( 2000 . into( ) , 129 . into( ) ) ,
115+ ( 2001 . into( ) , 130 . into( ) )
116+ ] )
117+ ) ]
118+ #[ case(
119+ ( 0 ..150_u8 )
120+ . map( |i| Felt :: from( 128 ) + Felt :: TWO . pow( i) )
121+ . chain( ( 0 ..150_u8 ) . map( |i| Felt :: from( 128 ) + Felt :: TWO . pow( i) ) )
122+ . collect:: <Vec <_>>( ) ,
123+ ( 0 ..150_u128 )
124+ . map( |i| i + 128 )
125+ . chain( ( 0 ..150_u128 ) . map( |i| i + 128 ) )
126+ . collect:: <Vec <_>>( ) ,
127+ HashMap :: from_iter(
128+ ( 0 ..150_u128 )
129+ . map( |i| ( Felt :: from( 128 ) + Felt :: TWO . pow( i) , Felt :: from( i + 128 ) ) )
130+ . chain( [ ( 0 . into( ) , ( 128 + 150 ) . into( ) ) ] )
131+ )
132+ ) ]
133+ fn allocate_and_replace_keys_from_empty_storage (
134+ #[ case] keys : Vec < Felt > ,
135+ #[ case] expected_alias_per_key : Vec < u128 > ,
136+ #[ case] expected_alias_storage : HashMap < Felt , Felt > ,
137+ ) {
138+ let expected_alias_per_key: Vec < _ > =
139+ expected_alias_per_key. into_iter ( ) . map ( Felt :: from) . collect ( ) ;
140+ let ( actual_alias_storage, actual_alias_per_key) =
141+ allocate_aliases_for_keys_and_replace ( keys, HashMap :: new ( ) ) ;
142+ assert_eq ! ( actual_alias_storage, expected_alias_storage) ;
143+ assert_eq ! ( actual_alias_per_key, expected_alias_per_key) ;
144+ }
145+
146+ fn allocate_aliases_for_keys_and_replace (
147+ keys : Vec < Felt > ,
148+ initial_storage : HashMap < StorageKey , Felt > ,
149+ ) -> ( HashMap < Felt , Felt > , Vec < Felt > ) {
150+ let runner_config = get_entrypoint_runner_config ( ) ;
151+ let entrypoint = "__main__.allocate_alias_for_keys_and_replace" ;
152+ let implicit_args = [ ImplicitArg :: Builtin ( BuiltinName :: range_check) ] ;
153+ let unique_keys: HashSet < Felt > = HashSet :: from_iter (
154+ keys. iter ( )
155+ . filter ( |key| key >= & & INITIAL_AVAILABLE_ALIAS )
156+ . copied ( )
157+ . chain ( [ * ALIAS_COUNTER_STORAGE_KEY . key ( ) ] ) ,
158+ ) ;
159+ let expected_explicit_return_values = vec ! [
160+ EndpointArg :: Value ( ValueArg :: Single ( Felt :: ZERO ) ) , // Aliases.len
161+ EndpointArg :: Pointer ( PointerArg :: Array ( vec![ // Aliases.ptr
162+ Felt :: ZERO ;
163+ ( unique_keys. len( ) ) * DICT_ACCESS_SIZE
164+ ] ) ) ,
165+ // Aliases per-key ptr.
166+ EndpointArg :: Pointer ( PointerArg :: Array ( vec![ Felt :: ZERO ; keys. len( ) ] ) ) ,
167+ ] ;
168+ let n_keys_arg = EndpointArg :: Value ( ValueArg :: Single ( keys. len ( ) . into ( ) ) ) ;
169+ let keys_arg = EndpointArg :: Pointer ( PointerArg :: Array ( keys) ) ;
170+ let explicit_args = vec ! [ n_keys_arg, keys_arg] ;
171+ let storage_view = initial_storage
172+ . into_iter ( )
173+ . map ( |( key, value) | ( ( * ALIAS_CONTRACT_ADDRESS , key) , value) )
174+ . collect ( ) ;
175+
176+ let state_reader = DictStateReader { storage_view, ..Default :: default ( ) } ;
177+ let ( _, explicit_return_values, _) = run_cairo_0_entry_point (
178+ & runner_config,
179+ ALIASES_TEST_BYTES ,
180+ entrypoint,
181+ & explicit_args,
182+ & implicit_args,
183+ & expected_explicit_return_values,
184+ HashMap :: new ( ) ,
185+ Some ( state_reader) ,
186+ )
187+ . unwrap ( ) ;
188+ if let [
189+ EndpointArg :: Value ( ValueArg :: Single ( n_aliases) ) ,
190+ EndpointArg :: Pointer ( PointerArg :: Array ( aliases_storage_updates) ) ,
191+ EndpointArg :: Pointer ( PointerArg :: Array ( alias_per_key) ) ,
192+ ] = explicit_return_values. as_slice ( )
193+ {
194+ let n_aliases = felt_to_usize ( n_aliases) . unwrap ( ) ;
195+ assert_eq ! ( n_aliases, aliases_storage_updates. len( ) / DICT_ACCESS_SIZE ) ;
196+ let actual_alias_storage = parse_squashed_cairo_dict ( aliases_storage_updates) ;
197+ ( actual_alias_storage, alias_per_key. clone ( ) . to_vec ( ) )
198+ } else {
199+ panic ! (
200+ "The return value doesn't match the given format.\n Got: {explicit_return_values:?}"
201+ ) ;
202+ }
203+ }
0 commit comments