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 ;
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+ }
0 commit comments