@@ -4,8 +4,7 @@ use blockifier::state::cached_state::StateMaps;
44use starknet_api:: block:: BlockNumber ;
55use starknet_api:: core:: { ClassHash , ContractAddress , Nonce } ;
66use starknet_api:: hash:: HashOutput ;
7- use starknet_api:: state:: StorageKey ;
8- use starknet_os:: io:: os_input:: { CachedStateInput , CommitmentInfo , CommitmentInfos } ;
7+ use starknet_os:: io:: os_input:: { CommitmentInfo , StateCommitmentInfos } ;
98use starknet_patricia:: patricia_merkle_tree:: node_data:: inner_node:: {
109 flatten_preimages,
1110 Preimage ,
@@ -20,9 +19,26 @@ use starknet_rust_core::types::{
2019 Felt ,
2120 StorageProof as RpcStorageProof ,
2221} ;
23- use starknet_types_core:: felt:: Felt as TypesFelt ;
2422
2523use crate :: errors:: ProofProviderError ;
24+ use crate :: virtual_block_executor:: VirtualBlockExecutionData ;
25+
26+ /// Provides Patricia Merkle proofs for the initial state used in transaction execution.
27+ ///
28+ /// This trait abstracts the retrieval of storage proofs, which are essential for OS input
29+ /// generation. The proofs allow the OS to verify that the initial state values (read during
30+ /// execution) are consistent with the global state commitment (Patricia root).
31+ ///
32+ /// The returned `StorageProofs` contains:
33+ /// - `proof_state`: The ambient state values (nonces, class hashes) discovered in the proof.
34+ /// - `commitment_infos`: The Patricia Merkle proof nodes for contracts, classes, and storage tries.
35+ pub trait StorageProofProvider {
36+ fn get_storage_proofs (
37+ & self ,
38+ block_number : BlockNumber ,
39+ execution_data : & VirtualBlockExecutionData ,
40+ ) -> Result < StorageProofs , ProofProviderError > ;
41+ }
2642
2743/// Query parameters for fetching storage proofs from RPC.
2844pub struct RpcStorageProofsQuery {
@@ -33,8 +49,11 @@ pub struct RpcStorageProofsQuery {
3349
3450/// Complete OS input data built from RPC proofs.
3551pub struct StorageProofs {
36- pub cached_state_input : CachedStateInput ,
37- pub commitment_infos : CommitmentInfos ,
52+ /// State information discovered in the Patricia proof (nonces, class hashes)
53+ /// that might not have been explicitly read during transaction execution.
54+ /// This data is required by the OS to verify the contract state leaves.
55+ pub proof_state : StateMaps ,
56+ pub commitment_infos : StateCommitmentInfos ,
3857}
3958
4059/// Converts RPC merkle nodes (hash → MerkleNode mapping) to a PreimageMap.
@@ -55,12 +74,11 @@ impl RpcStorageProofsProvider {
5574 }
5675
5776 /// Extract query parameters from StateMaps.
58- pub fn prepare_query (
59- initial_reads : & StateMaps ,
60- executed_class_hashes : & HashSet < ClassHash > ,
61- ) -> RpcStorageProofsQuery {
62- let class_hashes: Vec < Felt > = executed_class_hashes. iter ( ) . map ( |ch| ch. 0 ) . collect ( ) ;
77+ pub fn prepare_query ( execution_data : & VirtualBlockExecutionData ) -> RpcStorageProofsQuery {
78+ let class_hashes: Vec < Felt > =
79+ execution_data. executed_class_hashes . iter ( ) . map ( |ch| ch. 0 ) . collect ( ) ;
6380
81+ let initial_reads = & execution_data. initial_reads ;
6482 let contract_addresses: Vec < ContractAddress > =
6583 initial_reads. get_contract_addresses ( ) . into_iter ( ) . collect ( ) ;
6684
@@ -107,49 +125,26 @@ impl RpcStorageProofsProvider {
107125 /// Converts an RPC storage proof response to OS input format.
108126 pub fn to_storage_proofs (
109127 rpc_proof : & RpcStorageProof ,
110- initial_reads : & StateMaps ,
111128 contract_addresses : & [ ContractAddress ] ,
112129 ) -> StorageProofs {
113- let cached_state_input =
114- Self :: build_cached_state_input ( rpc_proof, initial_reads, contract_addresses) ;
130+ let mut proof_state = StateMaps :: default ( ) ;
115131 let commitment_infos = Self :: build_commitment_infos ( rpc_proof, contract_addresses) ;
116132
117- StorageProofs { cached_state_input, commitment_infos }
118- }
119-
120- fn build_cached_state_input (
121- rpc_proof : & RpcStorageProof ,
122- initial_reads : & StateMaps ,
123- contract_addresses : & [ ContractAddress ] ,
124- ) -> CachedStateInput {
125- let ( address_to_class_hash, address_to_nonce) = rpc_proof
126- . contracts_proof
127- . contract_leaves_data
128- . iter ( )
129- . zip ( contract_addresses)
130- . map ( |( leaf, addr) | ( ( * addr, ClassHash ( leaf. class_hash ) ) , ( * addr, Nonce ( leaf. nonce ) ) ) )
131- . unzip ( ) ;
132-
133- let storage = initial_reads. storage . iter ( ) . fold (
134- HashMap :: < ContractAddress , HashMap < StorageKey , TypesFelt > > :: new ( ) ,
135- |mut acc, ( ( addr, key) , val) | {
136- acc. entry ( * addr) . or_default ( ) . insert ( * key, * val) ;
137- acc
138- } ,
139- ) ;
140-
141- CachedStateInput {
142- storage,
143- address_to_class_hash,
144- address_to_nonce,
145- class_hash_to_compiled_class_hash : initial_reads. compiled_class_hashes . clone ( ) ,
133+ // Update proof_state with class hashes and nonces from the proof.
134+ for ( leaf, addr) in
135+ rpc_proof. contracts_proof . contract_leaves_data . iter ( ) . zip ( contract_addresses)
136+ {
137+ proof_state. class_hashes . insert ( * addr, ClassHash ( leaf. class_hash ) ) ;
138+ proof_state. nonces . insert ( * addr, Nonce ( leaf. nonce ) ) ;
146139 }
140+
141+ StorageProofs { proof_state, commitment_infos }
147142 }
148143
149144 fn build_commitment_infos (
150145 rpc_proof : & RpcStorageProof ,
151146 contract_addresses : & [ ContractAddress ] ,
152- ) -> CommitmentInfos {
147+ ) -> StateCommitmentInfos {
153148 let contracts_tree_root = HashOutput ( rpc_proof. global_roots . contracts_tree_root ) ;
154149 let classes_tree_root = HashOutput ( rpc_proof. global_roots . classes_tree_root ) ;
155150
@@ -174,7 +169,7 @@ impl RpcStorageProofsProvider {
174169 let storage_tries_commitment_infos =
175170 Self :: build_storage_commitment_infos ( rpc_proof, contract_addresses) ;
176171
177- CommitmentInfos {
172+ StateCommitmentInfos {
178173 contracts_trie_commitment_info,
179174 classes_trie_commitment_info,
180175 storage_tries_commitment_infos,
@@ -219,3 +214,19 @@ impl RpcStorageProofsProvider {
219214 . collect ( )
220215 }
221216}
217+
218+ impl StorageProofProvider for RpcStorageProofsProvider {
219+ fn get_storage_proofs (
220+ & self ,
221+ block_number : BlockNumber ,
222+ execution_data : & VirtualBlockExecutionData ,
223+ ) -> Result < StorageProofs , ProofProviderError > {
224+ let query = Self :: prepare_query ( execution_data) ;
225+ let contract_addresses = query. contract_addresses . clone ( ) ;
226+
227+ let runtime = tokio:: runtime:: Runtime :: new ( ) . expect ( "Failed to create tokio runtime" ) ;
228+ let rpc_proof = runtime. block_on ( self . fetch_proofs ( block_number, & query) ) ?;
229+
230+ Ok ( Self :: to_storage_proofs ( & rpc_proof, & contract_addresses) )
231+ }
232+ }
0 commit comments