Skip to content

Commit 13ea978

Browse files
committed
starknet_committer: add utility that returns sorted leaf indices
1 parent b6e6d57 commit 13ea978

1 file changed

Lines changed: 64 additions & 28 deletions

File tree

  • crates/starknet_committer/src/patricia_merkle_tree

crates/starknet_committer/src/patricia_merkle_tree/tree.rs

Lines changed: 64 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ use starknet_api::core::{ClassHash, ContractAddress};
44
use starknet_api::hash::HashOutput;
55
use starknet_patricia::patricia_merkle_tree::original_skeleton_tree::config::OriginalSkeletonTreeConfig;
66
use 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;
89
use starknet_patricia_storage::db_object::EmptyKeyContext;
910
use starknet_patricia_storage::storage_trait::ReadOnlyStorage;
1011

@@ -50,6 +51,57 @@ 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+
impl LeavesRequest {
64+
/// Builds index buffers expected by [`fetch_all_patricia_paths`].
65+
pub fn from(
66+
class_hashes: &[ClassHash],
67+
contract_addresses: &[ContractAddress],
68+
contract_storage_keys: &HashMap<ContractAddress, Vec<StarknetStorageKey>>,
69+
) -> Self {
70+
let contract_leaf_indices: Vec<NodeIndex> =
71+
contract_addresses.iter().map(contract_address_into_node_index).collect();
72+
let contract_storage_leaf_indices: HashMap<NodeIndex, Vec<NodeIndex>> =
73+
contract_storage_keys
74+
.iter()
75+
.map(|(address, keys)| {
76+
let node_index = contract_address_into_node_index(address);
77+
let leaf_indices: Vec<_> = keys.iter().map(NodeIndex::from).collect();
78+
(node_index, leaf_indices)
79+
})
80+
.collect();
81+
Self {
82+
class_leaf_indices: class_hashes.iter().map(class_hash_into_node_index).collect(),
83+
contract_leaf_indices,
84+
contract_storage_leaf_indices,
85+
}
86+
}
87+
88+
/// Sorts class, contract, and per-contract storage leaf index buffers in place, then returns
89+
/// [`SortedLeafIndices`] views.
90+
pub fn get_sorted(
91+
&mut self,
92+
) -> (SortedLeafIndices<'_>, SortedLeafIndices<'_>, HashMap<NodeIndex, SortedLeafIndices<'_>>)
93+
{
94+
let class_sorted = SortedLeafIndices::new(&mut self.class_leaf_indices);
95+
let contract_sorted = SortedLeafIndices::new(&mut self.contract_leaf_indices);
96+
let storage_sorted: HashMap<_, _> = self
97+
.contract_storage_leaf_indices
98+
.iter_mut()
99+
.map(|(address, leaf_indices)| (*address, SortedLeafIndices::new(leaf_indices)))
100+
.collect();
101+
(class_sorted, contract_sorted, storage_sorted)
102+
}
103+
}
104+
53105
/// Fetch all tries patricia paths given the modified leaves.
54106
/// Fetch the leaves in the contracts trie only, to be able to get the storage root hashes.
55107
/// Assumption: `contract_sorted_leaf_indices` contains all `contract_storage_sorted_leaf_indices`
@@ -179,43 +231,27 @@ pub async fn fetch_previous_and_new_patricia_paths(
179231
contract_addresses: &[ContractAddress],
180232
contract_storage_keys: &HashMap<ContractAddress, Vec<StarknetStorageKey>>,
181233
) -> 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();
234+
let mut leaves_request =
235+
LeavesRequest::from(class_hashes, contract_addresses, contract_storage_keys);
236+
237+
let (class_sorted, contract_sorted, storage_sorted) = leaves_request.get_sorted();
203238
let prev_proofs = fetch_all_patricia_paths::<FactsNodeLayout>(
204239
storage,
205240
classes_trie_root_hashes.previous_root_hash,
206241
contracts_trie_root_hashes.previous_root_hash,
207-
class_sorted_leaf_indices,
208-
contract_sorted_leaf_indices,
209-
contract_storage_sorted_leaf_indices,
242+
class_sorted,
243+
contract_sorted,
244+
&storage_sorted,
210245
)
211246
.await?;
247+
212248
let new_proofs = fetch_all_patricia_paths::<FactsNodeLayout>(
213249
storage,
214250
classes_trie_root_hashes.new_root_hash,
215251
contracts_trie_root_hashes.new_root_hash,
216-
class_sorted_leaf_indices,
217-
contract_sorted_leaf_indices,
218-
contract_storage_sorted_leaf_indices,
252+
class_sorted,
253+
contract_sorted,
254+
&storage_sorted,
219255
)
220256
.await?;
221257

0 commit comments

Comments
 (0)