Skip to content

Commit 2787ec6

Browse files
authored
starknet_committer, starknet_patricia: refactor key context (#11592)
1 parent f6252e8 commit 2787ec6

File tree

17 files changed

+144
-122
lines changed

17 files changed

+144
-122
lines changed

crates/starknet_committer/src/db/external_test_utils.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use serde_json::json;
44
use starknet_api::hash::HashOutput;
55
use starknet_patricia::patricia_merkle_tree::filled_tree::tree::{FilledTree, FilledTreeImpl};
66
use starknet_patricia::patricia_merkle_tree::node_data::leaf::{
7+
Leaf,
78
LeafModifications,
8-
LeafWithEmptyKeyContext,
99
SkeletonLeaf,
1010
};
1111
use starknet_patricia::patricia_merkle_tree::original_skeleton_tree::config::OriginalSkeletonTreeConfig;
@@ -15,7 +15,7 @@ use starknet_patricia::patricia_merkle_tree::updated_skeleton_tree::tree::{
1515
UpdatedSkeletonTree,
1616
UpdatedSkeletonTreeImpl,
1717
};
18-
use starknet_patricia_storage::db_object::EmptyKeyContext;
18+
use starknet_patricia_storage::db_object::HasStaticPrefix;
1919
use starknet_patricia_storage::map_storage::MapStorage;
2020

2121
use crate::db::facts_db::db::FactsNodeLayout;
@@ -27,10 +27,11 @@ pub async fn tree_computation_flow<L, TH>(
2727
storage: &mut MapStorage,
2828
root_hash: HashOutput,
2929
config: impl OriginalSkeletonTreeConfig,
30+
key_context: &<L as HasStaticPrefix>::KeyContext,
3031
) -> FilledTreeImpl<L>
3132
where
3233
TH: TreeHashFunction<L> + 'static,
33-
L: LeafWithEmptyKeyContext + 'static,
34+
L: Leaf + 'static,
3435
{
3536
let mut sorted_leaf_indices: Vec<NodeIndex> = leaf_modifications.keys().copied().collect();
3637
let sorted_leaf_indices = SortedLeafIndices::new(&mut sorted_leaf_indices);
@@ -41,7 +42,7 @@ where
4142
&config,
4243
&leaf_modifications,
4344
None,
44-
&EmptyKeyContext,
45+
key_context,
4546
)
4647
.await
4748
.expect("Failed to create the original skeleton tree");
@@ -68,14 +69,12 @@ where
6869
.expect("Failed to create the filled tree")
6970
}
7071

71-
pub async fn single_tree_flow_test<
72-
L: LeafWithEmptyKeyContext + 'static,
73-
TH: TreeHashFunction<L> + 'static,
74-
>(
72+
pub async fn single_tree_flow_test<L: Leaf + 'static, TH: TreeHashFunction<L> + 'static>(
7573
leaf_modifications: LeafModifications<L>,
7674
storage: &mut MapStorage,
7775
root_hash: HashOutput,
7876
config: impl OriginalSkeletonTreeConfig,
77+
key_context: &<L as HasStaticPrefix>::KeyContext,
7978
) -> String {
8079
// Move from leaf number to actual index.
8180
let leaf_modifications = leaf_modifications
@@ -84,7 +83,8 @@ pub async fn single_tree_flow_test<
8483
.collect::<LeafModifications<L>>();
8584

8685
let filled_tree =
87-
tree_computation_flow::<L, TH>(leaf_modifications, storage, root_hash, config).await;
86+
tree_computation_flow::<L, TH>(leaf_modifications, storage, root_hash, config, key_context)
87+
.await;
8888

8989
let hash_result = filled_tree.get_root_hash();
9090

@@ -93,7 +93,7 @@ pub async fn single_tree_flow_test<
9393
let json_hash = &json!(hash_result.0.to_hex_string());
9494
result_map.insert("root_hash", json_hash);
9595
// Serlialize the storage modifications.
96-
let json_storage = &json!(filled_tree.serialize(&EmptyKeyContext).unwrap());
96+
let json_storage = &json!(filled_tree.serialize(key_context).unwrap());
9797
result_map.insert("storage_changes", json_storage);
9898
serde_json::to_string(&result_map).expect("serialization failed")
9999
}

crates/starknet_committer/src/db/facts_db/create_facts_tree.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
use std::collections::HashMap;
22

33
use starknet_api::hash::HashOutput;
4-
use starknet_patricia::patricia_merkle_tree::node_data::leaf::{
5-
LeafModifications,
6-
LeafWithEmptyKeyContext,
7-
};
4+
use starknet_patricia::patricia_merkle_tree::node_data::leaf::{Leaf, LeafModifications};
85
use starknet_patricia::patricia_merkle_tree::original_skeleton_tree::tree::OriginalSkeletonTreeResult;
96
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
10-
use starknet_patricia_storage::db_object::EmptyKeyContext;
7+
use starknet_patricia_storage::db_object::HasStaticPrefix;
118
use starknet_patricia_storage::storage_trait::Storage;
129

1310
use crate::db::facts_db::db::FactsNodeLayout;
@@ -21,10 +18,11 @@ pub mod create_facts_tree_test;
2118
/// Prepares the OS inputs by fetching paths to the given leaves (i.e. their induced Skeleton tree).
2219
/// Note that ATM, the Rust committer does not manage history and is not used for storage proofs;
2320
/// Thus, this function assumes facts layout.
24-
pub async fn get_leaves<'a, L: LeafWithEmptyKeyContext>(
21+
pub async fn get_leaves<'a, L: Leaf>(
2522
storage: &mut impl Storage,
2623
root_hash: HashOutput,
2724
sorted_leaf_indices: SortedLeafIndices<'a>,
25+
key_context: &<L as HasStaticPrefix>::KeyContext,
2826
) -> OriginalSkeletonTreeResult<HashMap<NodeIndex, L>> {
2927
let config = OriginalSkeletonTrieConfig::default();
3028
let leaf_modifications = LeafModifications::new();
@@ -36,7 +34,7 @@ pub async fn get_leaves<'a, L: LeafWithEmptyKeyContext>(
3634
&config,
3735
&leaf_modifications,
3836
Some(&mut previous_leaves),
39-
&EmptyKeyContext,
37+
key_context,
4038
)
4139
.await?;
4240
Ok(previous_leaves)

crates/starknet_committer/src/db/facts_db/db.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,11 @@ use std::collections::HashMap;
33
use async_trait::async_trait;
44
use starknet_api::core::ContractAddress;
55
use starknet_api::hash::HashOutput;
6-
use starknet_patricia::db_layout::{NodeLayout, NodeLayoutFor, TrieType};
6+
use starknet_patricia::db_layout::{NodeLayout, NodeLayoutFor};
77
use starknet_patricia::patricia_merkle_tree::filled_tree::node::{FactDbFilledNode, FilledNode};
88
use starknet_patricia::patricia_merkle_tree::filled_tree::node_serde::FactNodeDeserializationContext;
99
use starknet_patricia::patricia_merkle_tree::filled_tree::tree::FilledTree;
10-
use starknet_patricia::patricia_merkle_tree::node_data::leaf::{
11-
Leaf,
12-
LeafModifications,
13-
LeafWithEmptyKeyContext,
14-
};
10+
use starknet_patricia::patricia_merkle_tree::node_data::leaf::{Leaf, LeafModifications};
1511
use starknet_patricia::patricia_merkle_tree::types::NodeIndex;
1612
use starknet_patricia_storage::db_object::{DBObject, EmptyKeyContext, HasStaticPrefix};
1713
use starknet_patricia_storage::errors::SerializationResult;
@@ -34,7 +30,7 @@ use crate::patricia_merkle_tree::types::CompiledClassHash;
3430
/// have the db keys of its children.
3531
pub struct FactsNodeLayout {}
3632

37-
impl<'a, L: LeafWithEmptyKeyContext> NodeLayout<'a, L> for FactsNodeLayout {
33+
impl<'a, L: Leaf> NodeLayout<'a, L> for FactsNodeLayout {
3834
type NodeData = HashOutput;
3935

4036
type NodeDbObject = FactDbFilledNode<L>;
@@ -43,10 +39,6 @@ impl<'a, L: LeafWithEmptyKeyContext> NodeLayout<'a, L> for FactsNodeLayout {
4339

4440
type SubTree = FactsSubTree<'a>;
4541

46-
fn generate_key_context(_trie_type: TrieType) -> <L as HasStaticPrefix>::KeyContext {
47-
EmptyKeyContext
48-
}
49-
5042
fn get_db_object<LeafBase: Leaf + Into<L>>(
5143
_node_index: NodeIndex,
5244
key_context: &<L as HasStaticPrefix>::KeyContext,
@@ -122,8 +114,8 @@ impl<S: Storage> ForestWriter for FactsDb<S> {
122114
let mut serialized_forest = DbHashMap::new();
123115

124116
// Storage tries.
125-
for tree in filled_forest.storage_tries.values() {
126-
serialized_forest.extend(tree.serialize(&EmptyKeyContext)?);
117+
for (contract_address, tree) in &filled_forest.storage_tries {
118+
serialized_forest.extend(tree.serialize(contract_address)?);
127119
}
128120

129121
// Contracts and classes tries.

crates/starknet_committer/src/db/facts_db/traversal.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ use starknet_patricia::patricia_merkle_tree::node_data::inner_node::{
66
Preimage,
77
PreimageMap,
88
};
9-
use starknet_patricia::patricia_merkle_tree::node_data::leaf::LeafWithEmptyKeyContext;
9+
use starknet_patricia::patricia_merkle_tree::node_data::leaf::Leaf;
1010
use starknet_patricia::patricia_merkle_tree::traversal::{SubTreeTrait, TraversalResult};
1111
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
12-
use starknet_patricia_storage::db_object::EmptyKeyContext;
12+
use starknet_patricia_storage::db_object::HasStaticPrefix;
1313
use starknet_patricia_storage::storage_trait::Storage;
1414

1515
use crate::db::facts_db::db::FactsNodeLayout;
@@ -24,11 +24,12 @@ pub mod traversal_test;
2424
/// given tree according to the `root_hash`.
2525
/// If `leaves` is not `None`, it also fetches the modified leaves and inserts them into the
2626
/// provided map.
27-
pub async fn fetch_patricia_paths<L: LeafWithEmptyKeyContext>(
27+
pub async fn fetch_patricia_paths<L: Leaf>(
2828
storage: &mut impl Storage,
2929
root_hash: HashOutput,
3030
sorted_leaf_indices: SortedLeafIndices<'_>,
3131
leaves: Option<&mut HashMap<NodeIndex, L>>,
32+
key_context: &<L as HasStaticPrefix>::KeyContext,
3233
) -> TraversalResult<PreimageMap> {
3334
let mut witnesses = PreimageMap::new();
3435

@@ -38,7 +39,14 @@ pub async fn fetch_patricia_paths<L: LeafWithEmptyKeyContext>(
3839

3940
let main_subtree = FactsSubTree::create(sorted_leaf_indices, NodeIndex::ROOT, root_hash);
4041

41-
fetch_patricia_paths_inner::<L>(storage, vec![main_subtree], &mut witnesses, leaves).await?;
42+
fetch_patricia_paths_inner::<L>(
43+
storage,
44+
vec![main_subtree],
45+
&mut witnesses,
46+
leaves,
47+
key_context,
48+
)
49+
.await?;
4250
Ok(witnesses)
4351
}
4452

@@ -51,21 +59,19 @@ pub async fn fetch_patricia_paths<L: LeafWithEmptyKeyContext>(
5159
/// inner nodes in their paths and their siblings.
5260
/// If `leaves` is not `None`, it also fetches the modified leaves and inserts them into the
5361
/// provided map.
54-
pub(crate) async fn fetch_patricia_paths_inner<'a, L: LeafWithEmptyKeyContext>(
62+
pub(crate) async fn fetch_patricia_paths_inner<'a, L: Leaf>(
5563
storage: &mut impl Storage,
5664
subtrees: Vec<FactsSubTree<'a>>,
5765
witnesses: &mut PreimageMap,
5866
mut leaves: Option<&mut HashMap<NodeIndex, L>>,
67+
key_context: &<L as HasStaticPrefix>::KeyContext,
5968
) -> TraversalResult<()> {
6069
let mut current_subtrees = subtrees;
6170
let mut next_subtrees = Vec::new();
6271
while !current_subtrees.is_empty() {
63-
let filled_roots = get_roots_from_storage::<L, FactsNodeLayout>(
64-
&current_subtrees,
65-
storage,
66-
&EmptyKeyContext,
67-
)
68-
.await?;
72+
let filled_roots =
73+
get_roots_from_storage::<L, FactsNodeLayout>(&current_subtrees, storage, key_context)
74+
.await?;
6975
for (filled_root, subtree) in filled_roots.into_iter().zip(current_subtrees.iter()) {
7076
match filled_root.data {
7177
// Binary node.

crates/starknet_committer/src/db/facts_db/traversal_test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ use starknet_patricia::patricia_merkle_tree::node_data::inner_node::{
2727
};
2828
use starknet_patricia::patricia_merkle_tree::traversal::SubTreeTrait;
2929
use starknet_patricia::patricia_merkle_tree::types::{SortedLeafIndices, SubTreeHeight};
30+
use starknet_patricia_storage::db_object::EmptyKeyContext;
3031
use starknet_patricia_storage::map_storage::MapStorage;
3132
use starknet_patricia_storage::storage_trait::{DbHashMap, DbKey, DbValue};
3233
use starknet_types_core::felt::Felt;
@@ -87,6 +88,7 @@ async fn test_fetch_patricia_paths_inner_impl(
8788
vec![main_subtree],
8889
&mut nodes,
8990
Some(&mut fetched_leaves),
91+
&EmptyKeyContext,
9092
)
9193
.await
9294
.unwrap();

crates/starknet_committer/src/db/forest_trait.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use starknet_api::core::ContractAddress;
66
use starknet_patricia::db_layout::NodeLayoutFor;
77
use starknet_patricia::patricia_merkle_tree::node_data::leaf::LeafModifications;
88
use starknet_patricia::patricia_merkle_tree::types::NodeIndex;
9+
use starknet_patricia_storage::db_object::{EmptyKeyContext, HasStaticPrefix};
910
use starknet_patricia_storage::errors::SerializationResult;
1011
use starknet_patricia_storage::storage_trait::{DbHashMap, DbKey, DbValue, Storage};
1112

@@ -82,6 +83,11 @@ where
8283
Layout: NodeLayoutFor<StarknetStorageValue>
8384
+ NodeLayoutFor<ContractState>
8485
+ NodeLayoutFor<CompiledClassHash>,
86+
<Layout as NodeLayoutFor<StarknetStorageValue>>::DbLeaf:
87+
HasStaticPrefix<KeyContext = ContractAddress>,
88+
<Layout as NodeLayoutFor<ContractState>>::DbLeaf: HasStaticPrefix<KeyContext = EmptyKeyContext>,
89+
<Layout as NodeLayoutFor<CompiledClassHash>>::DbLeaf:
90+
HasStaticPrefix<KeyContext = EmptyKeyContext>,
8591
{
8692
let (contracts_trie, original_contracts_trie_leaves) = create_contracts_trie::<Layout>(
8793
storage,

crates/starknet_committer/src/db/index_db/db.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::HashMap;
33
use async_trait::async_trait;
44
use starknet_api::core::ContractAddress;
55
use starknet_api::hash::HashOutput;
6-
use starknet_patricia::db_layout::{NodeLayout, NodeLayoutFor, TrieType};
6+
use starknet_patricia::db_layout::{NodeLayout, NodeLayoutFor};
77
use starknet_patricia::patricia_merkle_tree::filled_tree::node::FilledNode;
88
use starknet_patricia::patricia_merkle_tree::filled_tree::tree::FilledTree;
99
use starknet_patricia::patricia_merkle_tree::node_data::leaf::{Leaf, LeafModifications};
@@ -48,18 +48,14 @@ pub struct IndexNodeLayout {}
4848

4949
impl<'a, L> NodeLayout<'a, L> for IndexNodeLayout
5050
where
51-
L: Leaf + HasStaticPrefix<KeyContext = TrieType>,
51+
L: Leaf,
5252
TreeHashFunctionImpl: TreeHashFunction<L>,
5353
{
5454
type NodeData = EmptyNodeData;
5555
type NodeDbObject = IndexFilledNode<L>;
5656
type DeserializationContext = IndexNodeContext;
5757
type SubTree = IndexLayoutSubTree<'a>;
5858

59-
fn generate_key_context(trie_type: TrieType) -> <L as HasStaticPrefix>::KeyContext {
60-
trie_type
61-
}
62-
6359
fn get_db_object<LeafBase: Leaf + Into<L>>(
6460
node_index: NodeIndex,
6561
key_context: &<L as HasStaticPrefix>::KeyContext,
@@ -120,9 +116,8 @@ impl<S: Storage> ForestWriter for IndexDb<S> {
120116
fn serialize_forest(filled_forest: &FilledForest) -> SerializationResult<DbHashMap> {
121117
let mut serialized_forest = DbHashMap::new();
122118

123-
// TODO(Ariel): use a different key context when FilledForest is generic over leaf types.
124-
for tree in filled_forest.storage_tries.values() {
125-
serialized_forest.extend(tree.serialize(&EmptyKeyContext)?);
119+
for (contract_address, tree) in &filled_forest.storage_tries {
120+
serialized_forest.extend(tree.serialize(contract_address)?);
126121
}
127122

128123
// Contracts and classes tries.

crates/starknet_committer/src/db/index_db/leaves.rs

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
use std::sync::LazyLock;
22

3-
use starknet_api::core::{ClassHash, Nonce, PATRICIA_KEY_UPPER_BOUND};
3+
use starknet_api::core::{ClassHash, ContractAddress, Nonce, PATRICIA_KEY_UPPER_BOUND};
44
use starknet_api::hash::HashOutput;
5-
use starknet_patricia::db_layout::TrieType;
65
use starknet_patricia::patricia_merkle_tree::node_data::errors::LeafResult;
76
use starknet_patricia::patricia_merkle_tree::node_data::leaf::Leaf;
87
use starknet_patricia_storage::db_object::{
98
DBObject,
109
EmptyDeserializationContext,
10+
EmptyKeyContext,
1111
HasStaticPrefix,
1212
};
1313
use starknet_patricia_storage::errors::{DeserializationError, SerializationError};
@@ -48,34 +48,32 @@ static CONTRACTS_TREE_PREFIX: LazyLock<[u8; 32]> =
4848
static CLASSES_TREE_PREFIX: LazyLock<[u8; 32]> =
4949
LazyLock::new(|| (*FIRST_AVAILABLE_PREFIX_FELT + Felt::ONE).to_bytes_be());
5050

51-
fn trie_type_db_prefix(trie_type: &TrieType) -> DbKeyPrefix {
52-
match trie_type {
53-
TrieType::ContractsTrie => DbKeyPrefix::new((&CONTRACTS_TREE_PREFIX[..]).into()),
54-
TrieType::ClassesTrie => DbKeyPrefix::new((&CLASSES_TREE_PREFIX[..]).into()),
55-
TrieType::StorageTrie(contract_address) => {
56-
let prefix = contract_address.to_bytes_be().to_vec();
57-
DbKeyPrefix::new(prefix.into())
58-
}
59-
}
60-
}
61-
62-
macro_rules! impl_has_static_prefix_for_index_layouts {
63-
($($ty:ty),* $(,)?) => {
51+
macro_rules! impl_has_static_prefix_empty_context {
52+
($($ty:ty => $prefix:expr),* $(,)?) => {
6453
$(
6554
impl HasStaticPrefix for $ty {
66-
type KeyContext = TrieType;
67-
fn get_static_prefix(key_context: &Self::KeyContext) -> DbKeyPrefix {
68-
trie_type_db_prefix(key_context)
55+
type KeyContext = EmptyKeyContext;
56+
fn get_static_prefix(_key_context: &Self::KeyContext) -> DbKeyPrefix {
57+
DbKeyPrefix::new((&$prefix[..]).into())
6958
}
7059
}
7160
)*
7261
};
7362
}
7463

75-
impl_has_static_prefix_for_index_layouts! {
76-
IndexLayoutContractState,
77-
IndexLayoutCompiledClassHash,
78-
IndexLayoutStarknetStorageValue,
64+
impl_has_static_prefix_empty_context! {
65+
IndexLayoutContractState => CONTRACTS_TREE_PREFIX,
66+
IndexLayoutCompiledClassHash => CLASSES_TREE_PREFIX,
67+
}
68+
69+
impl HasStaticPrefix for IndexLayoutStarknetStorageValue {
70+
type KeyContext = ContractAddress;
71+
72+
/// Returns the contract address, which is the storage trie prefix in index layout.
73+
fn get_static_prefix(key_context: &Self::KeyContext) -> DbKeyPrefix {
74+
let prefix = key_context.to_bytes_be().to_vec();
75+
DbKeyPrefix::new(prefix.into())
76+
}
7977
}
8078

8179
macro_rules! impl_leaf_for_wrappers {

0 commit comments

Comments
 (0)