@@ -4,6 +4,7 @@ use blockifier::state::cached_state::StateChangesKeys;
44use starknet_api:: core:: { ClassHash , ContractAddress } ;
55use starknet_api:: hash:: { HashOutput , StateRoots } ;
66use starknet_committer:: block_committer:: input:: {
7+ contract_address_into_node_index,
78 try_node_index_into_contract_address,
89 StarknetStorageKey ,
910} ;
@@ -66,124 +67,110 @@ pub enum CommitmentInfosError {
6667 FetchStorageProofs ( #[ from] TraversalError ) ,
6768}
6869
69- /// Creates the commitment infos for the OS.
70- pub async fn create_commitment_infos (
71- previous_state_roots : & StateRoots ,
72- new_state_roots : & StateRoots ,
73- commitments : & mut MapStorage ,
74- initial_reads_keys : & StateChangesKeys ,
75- ) -> Result < StateCommitmentInfos , CommitmentInfosError > {
76- let ( previous_contract_states, new_storage_roots) = get_previous_states_and_new_storage_roots (
77- initial_reads_keys. modified_contracts . iter ( ) . copied ( ) ,
78- previous_state_roots. contracts_trie_root_hash ,
79- new_state_roots. contracts_trie_root_hash ,
80- commitments,
81- )
82- . await ?;
83- let mut address_to_previous_storage_root_hash = HashMap :: new ( ) ;
84- for ( address, contract_state) in previous_contract_states. into_iter ( ) {
85- let address = try_node_index_into_contract_address ( & address)
86- . map_err ( CommitmentInfosError :: InvalidNodeIndex ) ?;
87- address_to_previous_storage_root_hash. insert ( address, contract_state. storage_root_hash ) ;
88- }
70+ impl StateCommitmentInfos {
71+ /// Creates the commitment infos for the OS from previous and new state roots and the
72+ /// keys that were read during execution.
73+ pub async fn new (
74+ previous_state_roots : & StateRoots ,
75+ new_state_roots : & StateRoots ,
76+ commitments : & mut MapStorage ,
77+ initial_reads_keys : & StateChangesKeys ,
78+ ) -> Result < Self , CommitmentInfosError > {
79+ let addresses: Vec < ContractAddress > =
80+ initial_reads_keys. modified_contracts . iter ( ) . copied ( ) . collect ( ) ;
8981
90- let storage_proofs = fetch_storage_proofs_from_state_changes_keys (
91- initial_reads_keys,
92- commitments,
93- RootHashes {
94- previous_root_hash : previous_state_roots. classes_trie_root_hash ,
95- new_root_hash : new_state_roots. classes_trie_root_hash ,
96- } ,
97- RootHashes {
98- previous_root_hash : previous_state_roots. contracts_trie_root_hash ,
99- new_root_hash : new_state_roots. contracts_trie_root_hash ,
100- } ,
101- )
102- . await ?;
103- let contracts_trie_commitment_info = CommitmentInfo {
104- previous_root : previous_state_roots. contracts_trie_root_hash ,
105- updated_root : new_state_roots. contracts_trie_root_hash ,
106- tree_height : starknet_patricia:: patricia_merkle_tree:: types:: SubTreeHeight :: ACTUAL_HEIGHT ,
107- commitment_facts : flatten_preimages ( & storage_proofs. contracts_trie_proof . nodes ) ,
108- } ;
109- let classes_trie_commitment_info = CommitmentInfo {
110- previous_root : previous_state_roots. classes_trie_root_hash ,
111- updated_root : new_state_roots. classes_trie_root_hash ,
112- tree_height : starknet_patricia:: patricia_merkle_tree:: types:: SubTreeHeight :: ACTUAL_HEIGHT ,
113- commitment_facts : flatten_preimages ( & storage_proofs. classes_trie_proof ) ,
114- } ;
115- let storage_tries_commitment_infos = address_to_previous_storage_root_hash
116- . iter ( )
117- . map ( |( address, previous_root_hash) | {
118- // Not all contracts in `address_to_previous_storage_root_hash` are in
119- // `extended_state_diff`. For example a contract that only its Nonce was
120- // changed.
121- let storage_proof = flatten_preimages (
122- storage_proofs
123- . contracts_trie_storage_proofs
124- . get ( address)
125- . unwrap_or ( & HashMap :: new ( ) ) ,
126- ) ;
127- (
128- * address,
129- CommitmentInfo {
130- previous_root : * previous_root_hash,
131- updated_root : new_storage_roots[ address] ,
132- tree_height :
133- starknet_patricia:: patricia_merkle_tree:: types:: SubTreeHeight :: ACTUAL_HEIGHT ,
134- commitment_facts : storage_proof,
135- } ,
136- )
137- } )
138- . collect ( ) ;
82+ let previous_storage_roots = get_storage_roots (
83+ & addresses,
84+ previous_state_roots. contracts_trie_root_hash ,
85+ commitments,
86+ )
87+ . await ?;
88+ let new_storage_roots =
89+ get_storage_roots ( & addresses, new_state_roots. contracts_trie_root_hash , commitments)
90+ . await ?;
91+
92+ let storage_proofs = fetch_storage_proofs_from_state_changes_keys (
93+ initial_reads_keys,
94+ commitments,
95+ RootHashes {
96+ previous_root_hash : previous_state_roots. classes_trie_root_hash ,
97+ new_root_hash : new_state_roots. classes_trie_root_hash ,
98+ } ,
99+ RootHashes {
100+ previous_root_hash : previous_state_roots. contracts_trie_root_hash ,
101+ new_root_hash : new_state_roots. contracts_trie_root_hash ,
102+ } ,
103+ )
104+ . await ?;
139105
140- Ok ( StateCommitmentInfos {
141- contracts_trie_commitment_info,
142- classes_trie_commitment_info,
143- storage_tries_commitment_infos,
144- } )
106+ let contracts_trie_commitment_info = CommitmentInfo {
107+ previous_root : previous_state_roots. contracts_trie_root_hash ,
108+ updated_root : new_state_roots. contracts_trie_root_hash ,
109+ tree_height : SubTreeHeight :: ACTUAL_HEIGHT ,
110+ commitment_facts : flatten_preimages ( & storage_proofs. contracts_trie_proof . nodes ) ,
111+ } ;
112+ let classes_trie_commitment_info = CommitmentInfo {
113+ previous_root : previous_state_roots. classes_trie_root_hash ,
114+ updated_root : new_state_roots. classes_trie_root_hash ,
115+ tree_height : SubTreeHeight :: ACTUAL_HEIGHT ,
116+ commitment_facts : flatten_preimages ( & storage_proofs. classes_trie_proof ) ,
117+ } ;
118+ let storage_tries_commitment_infos = previous_storage_roots
119+ . iter ( )
120+ . map ( |( address, previous_root_hash) | {
121+ // Not all contracts in `previous_storage_roots` have storage proofs. For
122+ // example, a contract that only had its nonce changed.
123+ let storage_proof = flatten_preimages (
124+ storage_proofs
125+ . contracts_trie_storage_proofs
126+ . get ( address)
127+ . unwrap_or ( & HashMap :: new ( ) ) ,
128+ ) ;
129+ (
130+ * address,
131+ CommitmentInfo {
132+ previous_root : * previous_root_hash,
133+ updated_root : new_storage_roots[ address] ,
134+ tree_height : SubTreeHeight :: ACTUAL_HEIGHT ,
135+ commitment_facts : storage_proof,
136+ } ,
137+ )
138+ } )
139+ . collect ( ) ;
140+
141+ Ok ( Self {
142+ contracts_trie_commitment_info,
143+ classes_trie_commitment_info,
144+ storage_tries_commitment_infos,
145+ } )
146+ }
145147}
146148
147- pub async fn get_previous_states_and_new_storage_roots < I : Iterator < Item = ContractAddress > > (
148- contract_addresses : I ,
149- previous_contract_trie_root : HashOutput ,
150- new_contract_trie_root : HashOutput ,
149+ /// Fetches the storage root hash of each contract from the contracts trie at the given root.
150+ async fn get_storage_roots (
151+ contract_addresses : & [ ContractAddress ] ,
152+ contracts_trie_root : HashOutput ,
151153 commitments : & mut MapStorage ,
152- ) -> Result <
153- ( HashMap < NodeIndex , ContractState > , HashMap < ContractAddress , HashOutput > ) ,
154- CommitmentInfosError ,
155- > {
154+ ) -> Result < HashMap < ContractAddress , HashOutput > , CommitmentInfosError > {
156155 let mut contract_leaf_indices: Vec < NodeIndex > =
157- contract_addresses. map ( |address| NodeIndex :: from_leaf_felt ( & address. 0 ) ) . collect ( ) ;
158-
159- // Get previous contract state leaves.
160- let sorted_contract_leaf_indices = SortedLeafIndices :: new ( & mut contract_leaf_indices) ;
161- // Get the previous and the new contract states.
162- let previous_contract_states = get_leaves (
163- commitments,
164- previous_contract_trie_root,
165- sorted_contract_leaf_indices,
166- & EmptyKeyContext ,
167- )
168- . await ?;
156+ contract_addresses. iter ( ) . map ( contract_address_into_node_index) . collect ( ) ;
169157 let sorted_contract_leaf_indices = SortedLeafIndices :: new ( & mut contract_leaf_indices) ;
170- let new_contract_states : HashMap < NodeIndex , ContractState > = get_leaves (
158+ let contract_states : HashMap < NodeIndex , ContractState > = get_leaves (
171159 commitments,
172- new_contract_trie_root ,
160+ contracts_trie_root ,
173161 sorted_contract_leaf_indices,
174162 & EmptyKeyContext ,
175163 )
176164 . await ?;
177165
178- let new_contract_roots : HashMap < ContractAddress , HashOutput > = new_contract_states
166+ contract_states
179167 . into_iter ( )
180168 . map ( |( idx, contract_state) | {
181169 let address = try_node_index_into_contract_address ( & idx)
182- . map_err ( |e| CommitmentInfosError :: InvalidNodeIndex ( e . to_string ( ) ) ) ?;
170+ . map_err ( CommitmentInfosError :: InvalidNodeIndex ) ?;
183171 Ok ( ( address, contract_state. storage_root_hash ) )
184172 } )
185- . collect :: < Result < HashMap < _ , _ > , CommitmentInfosError > > ( ) ?;
186- Ok ( ( previous_contract_states, new_contract_roots) )
173+ . collect ( )
187174}
188175
189176async fn fetch_storage_proofs_from_state_changes_keys (
0 commit comments