Skip to content

Commit 5cd04c2

Browse files
committed
starknet_committer: fetch patricia paths concurrently
1 parent 3cbe5fb commit 5cd04c2

3 files changed

Lines changed: 81 additions & 59 deletions

File tree

crates/starknet_committer/src/db/trie_traversal.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -927,7 +927,6 @@ where
927927

928928
/// Fetches Patricia proofs for the storage tries. If the storage has a [GatherableStorage] version,
929929
/// then the paths are fetched concurrently. Otherwise, they are fetched sequentially.
930-
#[allow(dead_code)]
931930
pub(crate) async fn fetch_contract_storage_paths<StorageLayout, ContractLeaf>(
932931
storage: &mut impl ReadOnlyStorage,
933932
contract_storage_sorted_leaf_indices: &HashMap<NodeIndex, SortedLeafIndices<'_>>,
@@ -961,6 +960,7 @@ where
961960
/// The contract address might not exist in the contracts trie in the following cases:
962961
/// 1. We are looking at the previous tree and the contract is new.
963962
/// 2. We are looking at the new tree and the contract is deleted (revert).
963+
///
964964
/// In either case, the storage trie of this contract is empty, so there is nothing to
965965
/// prove regarding the contract storage.
966966
pub(crate) fn get_address_and_storage_root<ContractLeaf: AsRef<ContractState>>(
@@ -978,7 +978,6 @@ pub(crate) fn get_address_and_storage_root<ContractLeaf: AsRef<ContractState>>(
978978
}
979979

980980
/// Sequentially fetches Patricia proofs for the storage tries.
981-
#[allow(dead_code)]
982981
async fn fetch_contract_storage_paths_sequentially<StorageLayout, ContractLeaf>(
983982
storage: &mut impl ReadOnlyStorage,
984983
contract_storage_sorted_leaf_indices: &HashMap<NodeIndex, SortedLeafIndices<'_>>,
@@ -1016,7 +1015,6 @@ where
10161015
}
10171016

10181017
/// Concurrently fetches Patricia proofs for the storage tries.
1019-
#[allow(dead_code)]
10201018
async fn fetch_contract_storage_paths_concurrently<S, StorageLayout, ContractLeaf>(
10211019
storage: &mut S,
10221020
contract_storage_sorted_leaf_indices: &HashMap<NodeIndex, SortedLeafIndices<'_>>,

crates/starknet_committer/src/patricia_merkle_tree/tree.rs

Lines changed: 42 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
11
use std::collections::HashMap;
22

33
use blockifier::state::accessed_keys::AccessedKeys;
4-
use starknet_api::core::ContractAddress;
54
use starknet_api::hash::HashOutput;
5+
use starknet_patricia::patricia_merkle_tree::node_data::inner_node::PreimageMap;
66
use starknet_patricia::patricia_merkle_tree::original_skeleton_tree::config::OriginalSkeletonTreeConfig;
77
use starknet_patricia::patricia_merkle_tree::traversal::TraversalResult;
88
use starknet_patricia::patricia_merkle_tree::types::NodeIndex;
99
pub use starknet_patricia::patricia_merkle_tree::types::SortedLeafIndices;
1010
use starknet_patricia_storage::db_object::EmptyKeyContext;
1111
use starknet_patricia_storage::storage_trait::ReadOnlyStorage;
1212

13-
use crate::block_committer::input::{
14-
contract_address_into_node_index,
15-
try_node_index_into_contract_address,
16-
StarknetStorageKey,
17-
};
13+
use crate::block_committer::input::{contract_address_into_node_index, StarknetStorageKey};
1814
use crate::db::db_layout::DbLayout;
1915
use crate::db::facts_db::FactsNodeLayout;
20-
use crate::db::trie_traversal::{fetch_patricia_paths, get_address_and_storage_root};
16+
use crate::db::trie_traversal::{fetch_contract_storage_paths, fetch_patricia_paths};
2117
use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState;
2218
use crate::patricia_merkle_tree::types::{
2319
class_hash_into_node_index,
24-
ContractsTrieProof,
2520
RootHashes,
2621
StarknetForestProofs,
2722
};
@@ -132,6 +127,44 @@ pub async fn fetch_all_patricia_paths<Layout>(
132127
contract_sorted_leaf_indices: SortedLeafIndices<'_>,
133128
contract_storage_sorted_leaf_indices: &HashMap<NodeIndex, SortedLeafIndices<'_>>,
134129
) -> TraversalResult<StarknetForestProofs>
130+
where
131+
Layout: DbLayout,
132+
Layout::ContractStateDbLeaf: AsRef<ContractState> + Into<ContractState>,
133+
Layout::NodeLayout: Send + 'static,
134+
{
135+
let (classes_trie_proof, contracts_proof_nodes, contract_leaves) =
136+
fetch_classes_and_contracts_patricia_paths::<Layout>(
137+
storage,
138+
classes_trie_root_hash,
139+
contracts_trie_root_hash,
140+
class_sorted_leaf_indices,
141+
contract_sorted_leaf_indices,
142+
contract_storage_sorted_leaf_indices,
143+
)
144+
.await?;
145+
let contracts_trie_storage_proofs =
146+
fetch_contract_storage_paths::<Layout::NodeLayout, Layout::ContractStateDbLeaf>(
147+
storage,
148+
contract_storage_sorted_leaf_indices,
149+
&contract_leaves,
150+
)
151+
.await?;
152+
Ok(StarknetForestProofs::build::<Layout>(
153+
classes_trie_proof,
154+
contracts_proof_nodes,
155+
contract_leaves,
156+
contracts_trie_storage_proofs,
157+
))
158+
}
159+
160+
async fn fetch_classes_and_contracts_patricia_paths<Layout>(
161+
storage: &mut impl ReadOnlyStorage,
162+
classes_trie_root_hash: HashOutput,
163+
contracts_trie_root_hash: HashOutput,
164+
class_sorted_leaf_indices: SortedLeafIndices<'_>,
165+
contract_sorted_leaf_indices: SortedLeafIndices<'_>,
166+
contract_storage_sorted_leaf_indices: &HashMap<NodeIndex, SortedLeafIndices<'_>>,
167+
) -> TraversalResult<(PreimageMap, PreimageMap, HashMap<NodeIndex, Layout::ContractStateDbLeaf>)>
135168
where
136169
Layout: DbLayout,
137170
Layout::ContractStateDbLeaf: AsRef<ContractState> + Into<ContractState>,
@@ -176,53 +209,7 @@ where
176209
)
177210
.await?;
178211

179-
// Contracts storage tries.
180-
let mut contracts_trie_storage_proofs =
181-
HashMap::with_capacity(contract_storage_sorted_leaf_indices.len());
182-
183-
for (idx, sorted_leaf_indices) in contract_storage_sorted_leaf_indices {
184-
let Some((contract_address, storage_root_hash)) =
185-
get_address_and_storage_root(idx, &leaves)
186-
else {
187-
continue;
188-
};
189-
// No need to fetch the leaves.
190-
let leaves = None;
191-
let proof = fetch_patricia_paths::<Layout::StarknetStorageValueDbLeaf, Layout::NodeLayout>(
192-
storage,
193-
storage_root_hash,
194-
*sorted_leaf_indices,
195-
leaves,
196-
&contract_address,
197-
)
198-
.await?;
199-
contracts_trie_storage_proofs.insert(contract_address, proof);
200-
}
201-
202-
// Convert contract_leaves_data keys from NodeIndex to ContractAddress.
203-
let contract_leaves_data: HashMap<ContractAddress, ContractState> = leaves
204-
.into_iter()
205-
.map(|(idx, contract_state_leaf)| {
206-
(
207-
try_node_index_into_contract_address(&idx).unwrap_or_else(|_| {
208-
panic!(
209-
"Converting leaf NodeIndex to ContractAddress should succeed; failed to \
210-
convert {idx:?}."
211-
)
212-
}),
213-
contract_state_leaf.into(),
214-
)
215-
})
216-
.collect();
217-
218-
Ok(StarknetForestProofs {
219-
classes_trie_proof,
220-
contracts_trie_proof: ContractsTrieProof {
221-
nodes: contracts_proof_nodes,
222-
leaves: contract_leaves_data,
223-
},
224-
contracts_trie_storage_proofs,
225-
})
212+
Ok((classes_trie_proof, contracts_proof_nodes, leaves))
226213
}
227214

228215
/// Fetch the Patricia paths (inner nodes) in the classes trie, contracts trie,

crates/starknet_committer/src/patricia_merkle_tree/types.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ use starknet_patricia::patricia_merkle_tree::node_data::leaf::SkeletonLeaf;
1010
use starknet_patricia::patricia_merkle_tree::types::NodeIndex;
1111
use starknet_types_core::felt::{Felt, FromStrError};
1212

13-
use crate::block_committer::input::StarknetStorageValue;
13+
use crate::block_committer::input::{try_node_index_into_contract_address, StarknetStorageValue};
14+
use crate::db::db_layout::DbLayout;
1415
use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState;
1516

1617
pub fn fixed_hex_string_no_prefix(felt: &Felt) -> String {
@@ -57,6 +58,42 @@ pub struct StarknetForestProofs {
5758
}
5859

5960
impl StarknetForestProofs {
61+
pub fn build<Layout>(
62+
classes_trie_proof: PreimageMap,
63+
contracts_proof_nodes: PreimageMap,
64+
contract_leaves: HashMap<NodeIndex, Layout::ContractStateDbLeaf>,
65+
contracts_trie_storage_proofs: HashMap<ContractAddress, PreimageMap>,
66+
) -> Self
67+
where
68+
Layout: DbLayout,
69+
Layout::ContractStateDbLeaf: Into<ContractState>,
70+
{
71+
// Convert contract_leaves_data keys from NodeIndex to ContractAddress.
72+
let contract_leaves_data: HashMap<ContractAddress, ContractState> = contract_leaves
73+
.into_iter()
74+
.map(|(idx, contract_state_leaf)| {
75+
(
76+
try_node_index_into_contract_address(&idx).unwrap_or_else(|_| {
77+
panic!(
78+
"Converting leaf NodeIndex to ContractAddress should succeed; failed \
79+
to convert {idx:?}."
80+
)
81+
}),
82+
contract_state_leaf.into(),
83+
)
84+
})
85+
.collect();
86+
87+
Self {
88+
classes_trie_proof,
89+
contracts_trie_proof: ContractsTrieProof {
90+
nodes: contracts_proof_nodes,
91+
leaves: contract_leaves_data,
92+
},
93+
contracts_trie_storage_proofs,
94+
}
95+
}
96+
6097
pub fn extend(&mut self, other: Self) {
6198
self.classes_trie_proof.extend(other.classes_trie_proof);
6299
self.contracts_trie_proof.nodes.extend(other.contracts_trie_proof.nodes);

0 commit comments

Comments
 (0)