Skip to content

Commit 6ee8f1d

Browse files
committed
starknet_committer: add utility that returns sorted leaf indices
1 parent 815bf53 commit 6ee8f1d

1 file changed

Lines changed: 71 additions & 31 deletions

File tree

  • crates/starknet_committer/src/patricia_merkle_tree

crates/starknet_committer/src/patricia_merkle_tree/tree.rs

Lines changed: 71 additions & 31 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,10 +51,64 @@ 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+
pub struct SortedLeavesRequest<'a> {
64+
pub class_sorted: SortedLeafIndices<'a>,
65+
pub contract_sorted: SortedLeafIndices<'a>,
66+
pub storage_sorted: HashMap<NodeIndex, SortedLeafIndices<'a>>,
67+
}
68+
69+
impl LeavesRequest {
70+
/// Builds index buffers expected by [`fetch_all_patricia_paths`].
71+
pub fn from(
72+
class_hashes: &[ClassHash],
73+
contract_addresses: &[ContractAddress],
74+
contract_storage_keys: &HashMap<ContractAddress, Vec<StarknetStorageKey>>,
75+
) -> Self {
76+
let contract_leaf_indices: Vec<NodeIndex> =
77+
contract_addresses.iter().map(contract_address_into_node_index).collect();
78+
let contract_storage_leaf_indices: HashMap<NodeIndex, Vec<NodeIndex>> =
79+
contract_storage_keys
80+
.iter()
81+
.map(|(address, keys)| {
82+
let node_index = contract_address_into_node_index(address);
83+
let leaf_indices: Vec<_> = keys.iter().map(NodeIndex::from).collect();
84+
(node_index, leaf_indices)
85+
})
86+
.collect();
87+
Self {
88+
class_leaf_indices: class_hashes.iter().map(class_hash_into_node_index).collect(),
89+
contract_leaf_indices,
90+
contract_storage_leaf_indices,
91+
}
92+
}
93+
94+
/// Sorts class, contract, and per-contract storage leaf index buffers in place, then returns
95+
/// a single [`SortedLeavesRequest`].
96+
pub fn get_sorted(&mut self) -> SortedLeavesRequest<'_> {
97+
let class_sorted = SortedLeafIndices::new(&mut self.class_leaf_indices);
98+
let contract_sorted = SortedLeafIndices::new(&mut self.contract_leaf_indices);
99+
let storage_sorted: HashMap<_, _> = self
100+
.contract_storage_leaf_indices
101+
.iter_mut()
102+
.map(|(address, leaf_indices)| (*address, SortedLeafIndices::new(leaf_indices)))
103+
.collect();
104+
SortedLeavesRequest { class_sorted, contract_sorted, storage_sorted }
105+
}
106+
}
107+
53108
/// Fetch all tries patricia paths given the modified leaves.
54109
/// Fetch the leaves in the contracts trie only, to be able to get the storage root hashes.
55-
/// Assumption: `contract_sorted_leaf_indices` contains all `contract_storage_sorted_leaf_indices`
56-
/// keys.
110+
/// Assumption: `contract_sorted_leaf_indices` lists every contract that appears in
111+
/// `contract_storage_sorted_leaf_indices`.
57112
pub async fn fetch_all_patricia_paths<Layout>(
58113
storage: &mut impl ReadOnlyStorage,
59114
classes_trie_root_hash: HashOutput,
@@ -78,7 +133,8 @@ where
78133
address_counter,
79134
contract_storage_sorted_leaf_indices.len(),
80135
"contract_sorted_leaf_indices is missing an address with requested storage witnesses. \
81-
contract_sorted_leaf_indices: {contract_sorted_leaf_indices:?}, storage addresses: {:?}",
136+
contract_sorted_leaf_indices: {:?}, storage addresses: {:?}",
137+
contract_sorted_leaf_indices,
82138
contract_storage_sorted_leaf_indices.keys()
83139
);
84140

@@ -179,43 +235,27 @@ pub async fn fetch_previous_and_new_patricia_paths(
179235
contract_addresses: &[ContractAddress],
180236
contract_storage_keys: &HashMap<ContractAddress, Vec<StarknetStorageKey>>,
181237
) -> 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();
238+
let mut leaves_request =
239+
LeavesRequest::from(class_hashes, contract_addresses, contract_storage_keys);
240+
241+
let sorted_leaves = leaves_request.get_sorted();
203242
let prev_proofs = fetch_all_patricia_paths::<FactsNodeLayout>(
204243
storage,
205244
classes_trie_root_hashes.previous_root_hash,
206245
contracts_trie_root_hashes.previous_root_hash,
207-
class_sorted_leaf_indices,
208-
contract_sorted_leaf_indices,
209-
contract_storage_sorted_leaf_indices,
246+
sorted_leaves.class_sorted,
247+
sorted_leaves.contract_sorted,
248+
&sorted_leaves.storage_sorted,
210249
)
211250
.await?;
251+
212252
let new_proofs = fetch_all_patricia_paths::<FactsNodeLayout>(
213253
storage,
214254
classes_trie_root_hashes.new_root_hash,
215255
contracts_trie_root_hashes.new_root_hash,
216-
class_sorted_leaf_indices,
217-
contract_sorted_leaf_indices,
218-
contract_storage_sorted_leaf_indices,
256+
sorted_leaves.class_sorted,
257+
sorted_leaves.contract_sorted,
258+
&sorted_leaves.storage_sorted,
219259
)
220260
.await?;
221261

0 commit comments

Comments
 (0)