@@ -4,7 +4,8 @@ use starknet_api::core::{ClassHash, ContractAddress};
44use starknet_api:: hash:: HashOutput ;
55use starknet_patricia:: patricia_merkle_tree:: original_skeleton_tree:: config:: OriginalSkeletonTreeConfig ;
66use starknet_patricia:: patricia_merkle_tree:: traversal:: TraversalResult ;
7- use starknet_patricia:: patricia_merkle_tree:: types:: { NodeIndex , SortedLeafIndices } ;
7+ use starknet_patricia:: patricia_merkle_tree:: types:: NodeIndex ;
8+ pub use starknet_patricia:: patricia_merkle_tree:: types:: SortedLeafIndices ;
89use starknet_patricia_storage:: db_object:: EmptyKeyContext ;
910use starknet_patricia_storage:: storage_trait:: ReadOnlyStorage ;
1011
@@ -50,10 +51,64 @@ impl OriginalSkeletonTreeConfig for OriginalSkeletonTrieConfig {
5051 }
5152}
5253
54+ /// Requested trie leaves for Patricia witness collection (classes trie, contracts trie, and
55+ /// per-contract storage leaves). Built via [`LeavesRequest::from`].
56+ #[ derive( Clone ) ]
57+ pub struct LeavesRequest {
58+ pub class_leaf_indices : Vec < NodeIndex > ,
59+ pub contract_leaf_indices : Vec < NodeIndex > ,
60+ pub contract_storage_leaf_indices : HashMap < NodeIndex , Vec < NodeIndex > > ,
61+ }
62+
63+ pub struct SortedLeavesRequest < ' a > {
64+ pub class_sorted : SortedLeafIndices < ' a > ,
65+ pub contract_sorted : SortedLeafIndices < ' a > ,
66+ pub storage_sorted : HashMap < NodeIndex , SortedLeafIndices < ' a > > ,
67+ }
68+
69+ impl LeavesRequest {
70+ /// Builds index buffers expected by [`fetch_all_patricia_paths`].
71+ pub fn from (
72+ class_hashes : & [ ClassHash ] ,
73+ contract_addresses : & [ ContractAddress ] ,
74+ contract_storage_keys : & HashMap < ContractAddress , Vec < StarknetStorageKey > > ,
75+ ) -> Self {
76+ let contract_leaf_indices: Vec < NodeIndex > =
77+ contract_addresses. iter ( ) . map ( contract_address_into_node_index) . collect ( ) ;
78+ let contract_storage_leaf_indices: HashMap < NodeIndex , Vec < NodeIndex > > =
79+ contract_storage_keys
80+ . iter ( )
81+ . map ( |( address, keys) | {
82+ let node_index = contract_address_into_node_index ( address) ;
83+ let leaf_indices: Vec < _ > = keys. iter ( ) . map ( NodeIndex :: from) . collect ( ) ;
84+ ( node_index, leaf_indices)
85+ } )
86+ . collect ( ) ;
87+ Self {
88+ class_leaf_indices : class_hashes. iter ( ) . map ( class_hash_into_node_index) . collect ( ) ,
89+ contract_leaf_indices,
90+ contract_storage_leaf_indices,
91+ }
92+ }
93+
94+ /// Sorts class, contract, and per-contract storage leaf index buffers in place, then returns
95+ /// a single [`SortedLeavesRequest`].
96+ pub fn get_sorted ( & mut self ) -> SortedLeavesRequest < ' _ > {
97+ let class_sorted = SortedLeafIndices :: new ( & mut self . class_leaf_indices ) ;
98+ let contract_sorted = SortedLeafIndices :: new ( & mut self . contract_leaf_indices ) ;
99+ let storage_sorted: HashMap < _ , _ > = self
100+ . contract_storage_leaf_indices
101+ . iter_mut ( )
102+ . map ( |( address, leaf_indices) | ( * address, SortedLeafIndices :: new ( leaf_indices) ) )
103+ . collect ( ) ;
104+ SortedLeavesRequest { class_sorted, contract_sorted, storage_sorted }
105+ }
106+ }
107+
53108/// Fetch all tries patricia paths given the modified leaves.
54109/// Fetch the leaves in the contracts trie only, to be able to get the storage root hashes.
55- /// Assumption: `contract_sorted_leaf_indices` contains all `contract_storage_sorted_leaf_indices`
56- /// keys .
110+ /// Assumption: `contract_sorted_leaf_indices` lists every contract that appears in
111+ /// `contract_storage_sorted_leaf_indices` .
57112pub async fn fetch_all_patricia_paths < Layout > (
58113 storage : & mut impl ReadOnlyStorage ,
59114 classes_trie_root_hash : HashOutput ,
78133 address_counter,
79134 contract_storage_sorted_leaf_indices. len( ) ,
80135 "contract_sorted_leaf_indices is missing an address with requested storage witnesses. \
81- contract_sorted_leaf_indices: {contract_sorted_leaf_indices:?}, storage addresses: {:?}",
136+ contract_sorted_leaf_indices: {:?}, storage addresses: {:?}",
137+ contract_sorted_leaf_indices,
82138 contract_storage_sorted_leaf_indices. keys( )
83139 ) ;
84140
@@ -179,43 +235,27 @@ pub async fn fetch_previous_and_new_patricia_paths(
179235 contract_addresses : & [ ContractAddress ] ,
180236 contract_storage_keys : & HashMap < ContractAddress , Vec < StarknetStorageKey > > ,
181237) -> TraversalResult < StarknetForestProofs > {
182- let mut class_leaf_indices: Vec < NodeIndex > =
183- class_hashes. iter ( ) . map ( class_hash_into_node_index) . collect ( ) ;
184- let class_sorted_leaf_indices = SortedLeafIndices :: new ( & mut class_leaf_indices) ;
185-
186- let mut contract_leaf_indices: Vec < NodeIndex > =
187- contract_addresses. iter ( ) . map ( contract_address_into_node_index) . collect ( ) ;
188- let contract_sorted_leaf_indices = SortedLeafIndices :: new ( & mut contract_leaf_indices) ;
189-
190- let mut contract_storage_leaf_indices: HashMap < NodeIndex , Vec < NodeIndex > > =
191- contract_storage_keys
192- . iter ( )
193- . map ( |( address, keys) | {
194- let node_index = contract_address_into_node_index ( address) ;
195- let leaf_indices: Vec < _ > = keys. iter ( ) . map ( NodeIndex :: from) . collect ( ) ;
196- ( node_index, leaf_indices)
197- } )
198- . collect ( ) ;
199- let contract_storage_sorted_leaf_indices = & contract_storage_leaf_indices
200- . iter_mut ( )
201- . map ( |( address, leaf_indices) | ( * address, SortedLeafIndices :: new ( leaf_indices) ) )
202- . collect ( ) ;
238+ let mut leaves_request =
239+ LeavesRequest :: from ( class_hashes, contract_addresses, contract_storage_keys) ;
240+
241+ let sorted_leaves = leaves_request. get_sorted ( ) ;
203242 let prev_proofs = fetch_all_patricia_paths :: < FactsNodeLayout > (
204243 storage,
205244 classes_trie_root_hashes. previous_root_hash ,
206245 contracts_trie_root_hashes. previous_root_hash ,
207- class_sorted_leaf_indices ,
208- contract_sorted_leaf_indices ,
209- contract_storage_sorted_leaf_indices ,
246+ sorted_leaves . class_sorted ,
247+ sorted_leaves . contract_sorted ,
248+ & sorted_leaves . storage_sorted ,
210249 )
211250 . await ?;
251+
212252 let new_proofs = fetch_all_patricia_paths :: < FactsNodeLayout > (
213253 storage,
214254 classes_trie_root_hashes. new_root_hash ,
215255 contracts_trie_root_hashes. new_root_hash ,
216- class_sorted_leaf_indices ,
217- contract_sorted_leaf_indices ,
218- contract_storage_sorted_leaf_indices ,
256+ sorted_leaves . class_sorted ,
257+ sorted_leaves . contract_sorted ,
258+ & sorted_leaves . storage_sorted ,
219259 )
220260 . await ?;
221261
0 commit comments