Skip to content

Commit b925279

Browse files
committed
starknet_committer: add utility that returns sorted leaf indices
1 parent 526b5f0 commit b925279

1 file changed

Lines changed: 77 additions & 44 deletions

File tree

  • crates/starknet_committer/src/patricia_merkle_tree

crates/starknet_committer/src/patricia_merkle_tree/tree.rs

Lines changed: 77 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,26 @@ 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

1112
use crate::block_committer::input::{
1213
contract_address_into_node_index,
1314
try_node_index_into_contract_address,
1415
StarknetStorageKey,
15-
StarknetStorageValue,
1616
};
1717
use crate::db::db_layout::DbLayout;
1818
use crate::db::facts_db::FactsNodeLayout;
1919
use crate::db::trie_traversal::fetch_patricia_paths;
2020
use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState;
2121
use crate::patricia_merkle_tree::types::{
2222
class_hash_into_node_index,
23-
CompiledClassHash,
2423
ContractsTrieProof,
2524
RootHashes,
2625
StarknetForestProofs,
2726
};
28-
2927
#[derive(Clone, Default)]
3028
pub struct OriginalSkeletonTrieConfig {
3129
compare_modified_leaves: bool,
@@ -52,6 +50,56 @@ impl OriginalSkeletonTreeConfig for OriginalSkeletonTrieConfig {
5250
}
5351
}
5452

53+
/// Requested trie leaves for Patricia witness collection (classes trie, contracts trie, and
54+
/// per-contract storage leaves). Returned by [`get_leaf_indices`].
55+
#[derive(Clone)]
56+
pub struct LeavesRequest {
57+
pub class_leaf_indices: Vec<NodeIndex>,
58+
pub contract_leaf_indices: Vec<NodeIndex>,
59+
pub contract_storage_leaf_indices: HashMap<NodeIndex, Vec<NodeIndex>>,
60+
}
61+
62+
impl LeavesRequest {
63+
/// Sorts class, contract, and per-contract storage leaf index buffers in place, then returns
64+
/// [`SortedLeafIndices`] views.
65+
pub fn get_sorted(
66+
&mut self,
67+
) -> (SortedLeafIndices<'_>, SortedLeafIndices<'_>, HashMap<NodeIndex, SortedLeafIndices<'_>>)
68+
{
69+
let class_sorted = SortedLeafIndices::new(&mut self.class_leaf_indices);
70+
let contract_sorted = SortedLeafIndices::new(&mut self.contract_leaf_indices);
71+
let storage_sorted: HashMap<_, _> = self
72+
.contract_storage_leaf_indices
73+
.iter_mut()
74+
.map(|(address, leaf_indices)| (*address, SortedLeafIndices::new(leaf_indices)))
75+
.collect();
76+
(class_sorted, contract_sorted, storage_sorted)
77+
}
78+
}
79+
80+
/// Builds index buffers expected by [`fetch_all_patricia_paths`].
81+
pub fn get_leaf_indices(
82+
class_hashes: &[ClassHash],
83+
contract_addresses: &[ContractAddress],
84+
contract_storage_keys: &HashMap<ContractAddress, Vec<StarknetStorageKey>>,
85+
) -> LeavesRequest {
86+
let contract_leaf_indices: Vec<NodeIndex> =
87+
contract_addresses.iter().map(contract_address_into_node_index).collect();
88+
let contract_storage_leaf_indices: HashMap<NodeIndex, Vec<NodeIndex>> = contract_storage_keys
89+
.iter()
90+
.map(|(address, keys)| {
91+
let node_index = contract_address_into_node_index(address);
92+
let leaf_indices: Vec<_> = keys.iter().map(NodeIndex::from).collect();
93+
(node_index, leaf_indices)
94+
})
95+
.collect();
96+
LeavesRequest {
97+
class_leaf_indices: class_hashes.iter().map(class_hash_into_node_index).collect(),
98+
contract_leaf_indices,
99+
contract_storage_leaf_indices,
100+
}
101+
}
102+
55103
/// Fetch all tries patricia paths given the modified leaves.
56104
/// Fetch the leaves in the contracts trie only, to be able to get the storage root hashes.
57105
/// Assumption: `contract_sorted_leaf_indices` contains all `contract_storage_sorted_leaf_indices`
@@ -88,25 +136,25 @@ where
88136
let leaves = None;
89137
let classes_trie_proof =
90138
fetch_patricia_paths::<Layout::CompiledClassHashDbLeaf, Layout::NodeLayout>(
91-
storage,
92-
classes_trie_root_hash,
93-
class_sorted_leaf_indices,
94-
leaves,
95-
&EmptyKeyContext,
96-
)
97-
.await?;
139+
storage,
140+
classes_trie_root_hash,
141+
class_sorted_leaf_indices,
142+
leaves,
143+
&EmptyKeyContext,
144+
)
145+
.await?;
98146

99147
// Contracts trie - the leaves are required.
100148
let mut leaves = HashMap::new();
101149
let contracts_proof_nodes =
102150
fetch_patricia_paths::<Layout::ContractStateDbLeaf, Layout::NodeLayout>(
103-
storage,
104-
contracts_trie_root_hash,
105-
contract_sorted_leaf_indices,
106-
Some(&mut leaves),
107-
&EmptyKeyContext,
108-
)
109-
.await?;
151+
storage,
152+
contracts_trie_root_hash,
153+
contract_sorted_leaf_indices,
154+
Some(&mut leaves),
155+
&EmptyKeyContext,
156+
)
157+
.await?;
110158

111159
// Contracts storage tries.
112160
let mut contracts_trie_storage_proofs =
@@ -182,43 +230,28 @@ pub async fn fetch_previous_and_new_patricia_paths(
182230
contract_addresses: &[ContractAddress],
183231
contract_storage_keys: &HashMap<ContractAddress, Vec<StarknetStorageKey>>,
184232
) -> TraversalResult<StarknetForestProofs> {
185-
let mut class_leaf_indices: Vec<NodeIndex> =
186-
class_hashes.iter().map(class_hash_into_node_index).collect();
187-
let class_sorted_leaf_indices = SortedLeafIndices::new(&mut class_leaf_indices);
233+
let mut leaves_request =
234+
get_leaf_indices(class_hashes, contract_addresses, contract_storage_keys);
188235

189-
let mut contract_leaf_indices: Vec<NodeIndex> =
190-
contract_addresses.iter().map(contract_address_into_node_index).collect();
191-
let contract_sorted_leaf_indices = SortedLeafIndices::new(&mut contract_leaf_indices);
192-
193-
let mut contract_storage_leaf_indices: HashMap<NodeIndex, Vec<NodeIndex>> =
194-
contract_storage_keys
195-
.iter()
196-
.map(|(address, keys)| {
197-
let node_index = contract_address_into_node_index(address);
198-
let leaf_indices: Vec<_> = keys.iter().map(NodeIndex::from).collect();
199-
(node_index, leaf_indices)
200-
})
201-
.collect();
202-
let contract_storage_sorted_leaf_indices = &contract_storage_leaf_indices
203-
.iter_mut()
204-
.map(|(address, leaf_indices)| (*address, SortedLeafIndices::new(leaf_indices)))
205-
.collect();
236+
let (class_sorted, contract_sorted, storage_sorted) = leaves_request.get_sorted();
206237
let prev_proofs = fetch_all_patricia_paths::<FactsNodeLayout>(
207238
storage,
208239
classes_trie_root_hashes.previous_root_hash,
209240
contracts_trie_root_hashes.previous_root_hash,
210-
class_sorted_leaf_indices,
211-
contract_sorted_leaf_indices,
212-
contract_storage_sorted_leaf_indices,
241+
class_sorted,
242+
contract_sorted,
243+
&storage_sorted,
213244
)
214245
.await?;
246+
247+
let (class_sorted, contract_sorted, storage_sorted) = leaves_request.get_sorted();
215248
let new_proofs = fetch_all_patricia_paths::<FactsNodeLayout>(
216249
storage,
217250
classes_trie_root_hashes.new_root_hash,
218251
contracts_trie_root_hashes.new_root_hash,
219-
class_sorted_leaf_indices,
220-
contract_sorted_leaf_indices,
221-
contract_storage_sorted_leaf_indices,
252+
class_sorted,
253+
contract_sorted,
254+
&storage_sorted,
222255
)
223256
.await?;
224257

0 commit comments

Comments
 (0)