Skip to content

Commit 5e94496

Browse files
committed
starknet_committer: add index db
1 parent 758fa5e commit 5e94496

File tree

3 files changed

+149
-1
lines changed

3 files changed

+149
-1
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
use std::collections::HashMap;
2+
3+
use async_trait::async_trait;
4+
use starknet_api::core::ContractAddress;
5+
use starknet_api::hash::HashOutput;
6+
use starknet_patricia::patricia_merkle_tree::filled_tree::node::FilledNode;
7+
use starknet_patricia::patricia_merkle_tree::filled_tree::tree::FilledTree;
8+
use starknet_patricia::patricia_merkle_tree::node_data::leaf::{Leaf, LeafModifications};
9+
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
10+
use starknet_patricia::patricia_merkle_tree::updated_skeleton_tree::hash_function::TreeHashFunction;
11+
use starknet_patricia_storage::db_object::{EmptyKeyContext, HasStaticPrefix};
12+
use starknet_patricia_storage::errors::SerializationResult;
13+
use starknet_patricia_storage::storage_trait::{DbHashMap, Storage};
14+
15+
use crate::block_committer::input::{ReaderConfig, StarknetStorageValue};
16+
use crate::db::db_layout::NodeLayout;
17+
use crate::db::facts_db::types::FactsDbInitialRead;
18+
use crate::db::forest_trait::{ForestReader, ForestWriter};
19+
use crate::db::index_db::leaves::{
20+
IndexLayoutCompiledClassHash,
21+
IndexLayoutContractState,
22+
IndexLayoutStarknetStorageValue,
23+
TrieType,
24+
};
25+
use crate::db::index_db::types::{IndexFilledNode, IndexLayoutSubTree, IndexNodeContext};
26+
use crate::db::trie_traversal::{create_classes_trie, create_contracts_trie, create_storage_tries};
27+
use crate::forest::filled_forest::FilledForest;
28+
use crate::forest::forest_errors::ForestResult;
29+
use crate::forest::original_skeleton_forest::{ForestSortedIndices, OriginalSkeletonForest};
30+
use crate::hash_function::hash::TreeHashFunctionImpl;
31+
use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState;
32+
use crate::patricia_merkle_tree::types::CompiledClassHash;
33+
34+
pub struct IndexDb<S: Storage> {
35+
pub storage: S,
36+
}
37+
38+
impl<S: Storage> IndexDb<S> {
39+
pub fn new(storage: S) -> Self {
40+
Self { storage }
41+
}
42+
}
43+
44+
pub struct IndexNodeLayout {}
45+
46+
impl<'a, L: Leaf> NodeLayout<'a, L> for IndexNodeLayout
47+
where
48+
L: HasStaticPrefix<KeyContext = TrieType>,
49+
TreeHashFunctionImpl: TreeHashFunction<L>,
50+
{
51+
type NodeData = ();
52+
type NodeDbObject = IndexFilledNode<L>;
53+
type DeserializationContext = IndexNodeContext;
54+
type SubTree = IndexLayoutSubTree<'a>;
55+
56+
fn create_subtree(
57+
sorted_leaf_indices: SortedLeafIndices<'a>,
58+
root_index: NodeIndex,
59+
_root_hash: HashOutput,
60+
) -> Self::SubTree {
61+
IndexLayoutSubTree { sorted_leaf_indices, root_index }
62+
}
63+
64+
fn generate_key_context(trie_type: TrieType) -> <L as HasStaticPrefix>::KeyContext {
65+
trie_type
66+
}
67+
68+
fn get_filled_node(node_db_object: Self::NodeDbObject) -> FilledNode<L, Self::NodeData> {
69+
node_db_object.0
70+
}
71+
}
72+
73+
// TODO(Ariel): define an IndexDbInitialRead empty type, and check whether each tree is empty inside
74+
// create_xxx_trie.
75+
#[async_trait]
76+
impl<S: Storage> ForestReader<FactsDbInitialRead> for IndexDb<S> {
77+
/// Creates an original skeleton forest that includes the storage tries of the modified
78+
/// contracts, the classes trie and the contracts trie. Additionally, returns the original
79+
/// contract states that are needed to compute the contract state tree.
80+
async fn read<'a>(
81+
&mut self,
82+
context: FactsDbInitialRead,
83+
storage_updates: &'a HashMap<ContractAddress, LeafModifications<StarknetStorageValue>>,
84+
classes_updates: &'a LeafModifications<CompiledClassHash>,
85+
forest_sorted_indices: &'a ForestSortedIndices<'a>,
86+
config: ReaderConfig,
87+
) -> ForestResult<(OriginalSkeletonForest<'a>, HashMap<NodeIndex, ContractState>)> {
88+
let (contracts_trie, original_contracts_trie_leaves) =
89+
create_contracts_trie::<IndexLayoutContractState, IndexNodeLayout>(
90+
&mut self.storage,
91+
context.0.contracts_trie_root_hash,
92+
forest_sorted_indices.contracts_trie_sorted_indices,
93+
)
94+
.await?;
95+
let storage_tries =
96+
create_storage_tries::<IndexLayoutStarknetStorageValue, IndexNodeLayout>(
97+
&mut self.storage,
98+
storage_updates,
99+
&original_contracts_trie_leaves,
100+
&config,
101+
&forest_sorted_indices.storage_tries_sorted_indices,
102+
)
103+
.await?;
104+
let classes_trie = create_classes_trie::<IndexLayoutCompiledClassHash, IndexNodeLayout>(
105+
&mut self.storage,
106+
classes_updates,
107+
context.0.classes_trie_root_hash,
108+
&config,
109+
forest_sorted_indices.classes_trie_sorted_indices,
110+
)
111+
.await?;
112+
113+
Ok((
114+
OriginalSkeletonForest { classes_trie, contracts_trie, storage_tries },
115+
original_contracts_trie_leaves,
116+
))
117+
}
118+
}
119+
120+
#[async_trait]
121+
impl<S: Storage> ForestWriter for IndexDb<S> {
122+
fn serialize_forest(filled_forest: &FilledForest) -> SerializationResult<DbHashMap> {
123+
let mut serialized_forest = DbHashMap::new();
124+
125+
// TODO(Ariel): use a different key context when FilledForest is generic over leaf types.
126+
for tree in filled_forest.storage_tries.values() {
127+
serialized_forest.extend(tree.serialize(&EmptyKeyContext)?);
128+
}
129+
130+
// Contracts and classes tries.
131+
serialized_forest.extend(filled_forest.contracts_trie.serialize(&EmptyKeyContext)?);
132+
serialized_forest.extend(filled_forest.classes_trie.serialize(&EmptyKeyContext)?);
133+
134+
Ok(serialized_forest)
135+
}
136+
137+
async fn write_updates(&mut self, updates: DbHashMap) -> usize {
138+
let n_updates = updates.len();
139+
self.storage
140+
.mset(updates)
141+
.await
142+
.unwrap_or_else(|_| panic!("Write of {n_updates} new updates to storage failed"));
143+
n_updates
144+
}
145+
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ use crate::patricia_merkle_tree::types::CompiledClassHash;
1919

2020
// Wrap the leaves types so that we can implement the [DBObject] trait differently in index
2121
// layout.
22-
#[derive(Clone, Debug, Default, Eq, PartialEq, derive_more::AsRef, derive_more::From)]
22+
#[derive(
23+
Clone, Debug, Default, Eq, PartialEq, derive_more::AsRef, derive_more::From, derive_more::Into,
24+
)]
2325
pub struct IndexLayoutContractState(pub ContractState);
2426

2527
#[derive(Clone, Debug, Default, Eq, PartialEq, derive_more::AsRef, derive_more::From)]

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod db;
12
pub mod leaves;
23
#[cfg(test)]
34
pub mod serde_tests;

0 commit comments

Comments
 (0)