11use std:: collections:: HashMap ;
22
3- use starknet_api:: core:: { ClassHash , ContractAddress } ;
3+ use blockifier:: state:: accessed_keys:: AccessedKeys ;
4+ use starknet_api:: core:: ContractAddress ;
45use starknet_api:: hash:: HashOutput ;
56use starknet_patricia:: patricia_merkle_tree:: original_skeleton_tree:: config:: OriginalSkeletonTreeConfig ;
67use starknet_patricia:: patricia_merkle_tree:: traversal:: TraversalResult ;
@@ -52,7 +53,7 @@ impl OriginalSkeletonTreeConfig for OriginalSkeletonTrieConfig {
5253}
5354
5455/// Requested trie leaves for Patricia witness collection (classes trie, contracts trie, and
55- /// per-contract storage leaves). Built via [`LeavesRequest::from_accessed_leaves `].
56+ /// per-contract storage leaves). Built via [`From`] from [`AccessedKeys `].
5657#[ derive( Clone ) ]
5758pub struct LeavesRequest {
5859 pub class_leaf_indices : Vec < NodeIndex > ,
@@ -67,31 +68,35 @@ pub struct SortedLeavesRequest<'a> {
6768 pub storage_sorted : HashMap < NodeIndex , SortedLeafIndices < ' a > > ,
6869}
6970
70- impl LeavesRequest {
71- /// Builds index buffers expected by [`fetch_all_patricia_paths`].
72- pub fn from_accessed_leaves (
73- class_hashes : & [ ClassHash ] ,
74- contract_addresses : & [ ContractAddress ] ,
75- contract_storage_keys : & HashMap < ContractAddress , Vec < StarknetStorageKey > > ,
76- ) -> Self {
77- let contract_leaf_indices: Vec < NodeIndex > =
78- contract_addresses. iter ( ) . map ( contract_address_into_node_index) . collect ( ) ;
79- let contract_storage_leaf_indices: HashMap < NodeIndex , Vec < NodeIndex > > =
80- contract_storage_keys
81- . iter ( )
82- . map ( |( address, keys) | {
83- let node_index = contract_address_into_node_index ( address) ;
84- let leaf_indices: Vec < _ > = keys. iter ( ) . map ( NodeIndex :: from) . collect ( ) ;
85- ( node_index, leaf_indices)
86- } )
87- . collect ( ) ;
71+ impl From < & AccessedKeys > for LeavesRequest {
72+ fn from ( accessed_keys : & AccessedKeys ) -> Self {
73+ let contract_storage_leaf_indices: HashMap < NodeIndex , Vec < NodeIndex > > = accessed_keys
74+ . storage_keys
75+ . iter ( )
76+ . fold ( HashMap :: new ( ) , |mut accumulator, ( address, key) | {
77+ accumulator
78+ . entry ( contract_address_into_node_index ( address) )
79+ . or_default ( )
80+ . push ( NodeIndex :: from ( & StarknetStorageKey ( * key) ) ) ;
81+ accumulator
82+ } ) ;
8883 Self {
89- class_leaf_indices : class_hashes. iter ( ) . map ( class_hash_into_node_index) . collect ( ) ,
90- contract_leaf_indices,
84+ class_leaf_indices : accessed_keys
85+ . accessed_class_hashes
86+ . iter ( )
87+ . map ( class_hash_into_node_index)
88+ . collect ( ) ,
89+ contract_leaf_indices : accessed_keys
90+ . accessed_contracts
91+ . iter ( )
92+ . map ( contract_address_into_node_index)
93+ . collect ( ) ,
9194 contract_storage_leaf_indices,
9295 }
9396 }
97+ }
9498
99+ impl LeavesRequest {
95100 /// Total number of trie leaves requested (classes, contracts, and storage slots).
96101 pub fn total_leaf_count ( & self ) -> usize {
97102 self . class_leaf_indices . len ( )
@@ -101,18 +106,17 @@ impl LeavesRequest {
101106 . values ( )
102107 . fold ( 0 , |count, leaf_indices| count + leaf_indices. len ( ) )
103108 }
104- }
105109
106- impl < ' a > From < & ' a mut LeavesRequest > for SortedLeavesRequest < ' a > {
107- fn from ( leaves_request : & ' a mut LeavesRequest ) -> Self {
108- let class_sorted = SortedLeafIndices :: new ( & mut leaves_request . class_leaf_indices ) ;
109- let contract_sorted = SortedLeafIndices :: new ( & mut leaves_request . contract_leaf_indices ) ;
110- let storage_sorted: HashMap < _ , _ > = leaves_request
110+ /// Sorts leaf indices in place and returns borrowed views for Patricia traversal.
111+ pub fn sorted ( & mut self ) -> SortedLeavesRequest < ' _ > {
112+ let class_sorted = SortedLeafIndices :: new ( & mut self . class_leaf_indices ) ;
113+ let contract_sorted = SortedLeafIndices :: new ( & mut self . contract_leaf_indices ) ;
114+ let storage_sorted: HashMap < _ , _ > = self
111115 . contract_storage_leaf_indices
112116 . iter_mut ( )
113117 . map ( |( address, leaf_indices) | ( * address, SortedLeafIndices :: new ( leaf_indices) ) )
114118 . collect ( ) ;
115- Self { class_sorted, contract_sorted, storage_sorted }
119+ SortedLeavesRequest { class_sorted, contract_sorted, storage_sorted }
116120 }
117121}
118122
@@ -241,18 +245,12 @@ pub async fn fetch_previous_and_new_patricia_paths(
241245 storage : & mut impl ReadOnlyStorage ,
242246 classes_trie_root_hashes : RootHashes ,
243247 contracts_trie_root_hashes : RootHashes ,
244- class_hashes : & [ ClassHash ] ,
245- contract_addresses : & [ ContractAddress ] ,
246- contract_storage_keys : & HashMap < ContractAddress , Vec < StarknetStorageKey > > ,
248+ accessed_keys : & AccessedKeys ,
247249) -> TraversalResult < StarknetForestProofs > {
248- let mut leaves_request = LeavesRequest :: from_accessed_leaves (
249- class_hashes,
250- contract_addresses,
251- contract_storage_keys,
252- ) ;
250+ let mut leaves_request = LeavesRequest :: from ( accessed_keys) ;
253251
254252 let SortedLeavesRequest { class_sorted, contract_sorted, storage_sorted } =
255- SortedLeavesRequest :: from ( & mut leaves_request) ;
253+ leaves_request. sorted ( ) ;
256254 let prev_proofs = fetch_all_patricia_paths :: < FactsNodeLayout > (
257255 storage,
258256 classes_trie_root_hashes. previous_root_hash ,
0 commit comments