Skip to content

Commit 4e2cfa8

Browse files
committed
starknet_committer,starknet_patricia: generalize dbkey separator
1 parent 1d8c609 commit 4e2cfa8

File tree

12 files changed

+81
-60
lines changed

12 files changed

+81
-60
lines changed

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

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ use starknet_api::hash::{HashOutput, StateRoots};
22
use starknet_patricia::patricia_merkle_tree::filled_tree::node_serde::{
33
FactNodeDeserializationContext,
44
PatriciaPrefix,
5+
FACT_LAYOUT_DB_KEY_SEPARATOR,
56
};
67
use starknet_patricia::patricia_merkle_tree::node_data::leaf::Leaf;
78
use starknet_patricia::patricia_merkle_tree::traversal::{SubTreeTrait, UnmodifiedChildTraversal};
89
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
910
use starknet_patricia_storage::db_object::HasStaticPrefix;
10-
use starknet_patricia_storage::storage_trait::DbKeyPrefix;
11+
use starknet_patricia_storage::storage_trait::{create_db_key, DbKey, DbKeyPrefix};
1112

1213
use crate::block_committer::input::InputContext;
1314

@@ -46,19 +47,14 @@ impl<'a> SubTreeTrait<'a> for FactsSubTree<'a> {
4647
Self::NodeDeserializeContext { is_leaf: self.is_leaf(), node_hash: self.root_hash }
4748
}
4849

49-
fn get_root_prefix<L: Leaf>(
50-
&self,
51-
key_context: &<L as HasStaticPrefix>::KeyContext,
52-
) -> DbKeyPrefix {
53-
if self.is_leaf() {
50+
fn get_root_db_key<L: Leaf>(&self, key_context: &<L as HasStaticPrefix>::KeyContext) -> DbKey {
51+
let prefix: DbKeyPrefix = if self.is_leaf() {
5452
PatriciaPrefix::Leaf(L::get_static_prefix(key_context)).into()
5553
} else {
5654
PatriciaPrefix::InnerNode.into()
57-
}
58-
}
59-
60-
fn get_root_suffix(&self) -> Vec<u8> {
61-
self.root_hash.0.to_bytes_be().to_vec()
55+
};
56+
let suffix = self.root_hash.0.to_bytes_be();
57+
create_db_key(prefix, FACT_LAYOUT_DB_KEY_SEPARATOR, &suffix)
6258
}
6359
}
6460
/// Used for reading the roots in facts layout case.

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,12 @@ use starknet_patricia_storage::storage_trait::{DbKeyPrefix, DbValue};
1515
use starknet_types_core::felt::Felt;
1616

1717
use crate::block_committer::input::StarknetStorageValue;
18+
use crate::db::mock_forest_storage::EMPTY_DB_KEY_SEPARATOR;
1819
use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState;
1920
use crate::patricia_merkle_tree::types::CompiledClassHash;
21+
22+
pub const INDEX_LAYOUT_DB_KEY_SEPARATOR: &[u8] = EMPTY_DB_KEY_SEPARATOR;
23+
2024
// Wrap the leaves types so that we can implement the [DBObject] trait differently in index
2125
// layout.
2226
#[derive(
@@ -106,7 +110,10 @@ impl_leaf_for_wrappers!(
106110
);
107111

108112
impl DBObject for IndexLayoutContractState {
113+
const DB_KEY_SEPARATOR: &[u8] = INDEX_LAYOUT_DB_KEY_SEPARATOR;
114+
109115
type DeserializeContext = EmptyDeserializationContext;
116+
110117
fn serialize(&self) -> Result<DbValue, SerializationError> {
111118
serialize_felts(&[self.0.class_hash.0, self.0.storage_root_hash.0, self.0.nonce.0])
112119
}
@@ -131,6 +138,8 @@ impl DBObject for IndexLayoutContractState {
131138
}
132139

133140
impl DBObject for IndexLayoutCompiledClassHash {
141+
const DB_KEY_SEPARATOR: &[u8] = INDEX_LAYOUT_DB_KEY_SEPARATOR;
142+
134143
type DeserializeContext = EmptyDeserializationContext;
135144

136145
fn serialize(&self) -> Result<DbValue, SerializationError> {
@@ -148,6 +157,8 @@ impl DBObject for IndexLayoutCompiledClassHash {
148157
}
149158

150159
impl DBObject for IndexLayoutStarknetStorageValue {
160+
const DB_KEY_SEPARATOR: &[u8] = INDEX_LAYOUT_DB_KEY_SEPARATOR;
161+
151162
type DeserializeContext = EmptyDeserializationContext;
152163

153164
fn serialize(&self) -> Result<DbValue, SerializationError> {

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

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@ use starknet_patricia_storage::db_object::{
2020
HasStaticPrefix,
2121
};
2222
use starknet_patricia_storage::errors::{DeserializationError, SerializationResult};
23-
use starknet_patricia_storage::storage_trait::{DbKeyPrefix, DbValue};
23+
use starknet_patricia_storage::storage_trait::{create_db_key, DbKey, DbKeyPrefix, DbValue};
2424
use starknet_types_core::felt::Felt;
2525

26+
use crate::db::index_db::leaves::INDEX_LAYOUT_DB_KEY_SEPARATOR;
2627
use crate::hash_function::hash::TreeHashFunctionImpl;
2728

2829
// In index layout, for binary nodes, only the hash is stored.
@@ -56,6 +57,8 @@ where
5657
L: Leaf,
5758
TreeHashFunctionImpl: TreeHashFunction<L>,
5859
{
60+
const DB_KEY_SEPARATOR: &[u8] = INDEX_LAYOUT_DB_KEY_SEPARATOR;
61+
5962
type DeserializeContext = IndexNodeContext;
6063

6164
fn serialize(&self) -> SerializationResult<DbValue> {
@@ -178,14 +181,9 @@ impl<'a> SubTreeTrait<'a> for IndexLayoutSubTree<'a> {
178181
Self::NodeDeserializeContext { is_leaf: self.is_leaf() }
179182
}
180183

181-
fn get_root_prefix<L: Leaf>(
182-
&self,
183-
key_context: &<L as HasStaticPrefix>::KeyContext,
184-
) -> DbKeyPrefix {
185-
L::get_static_prefix(key_context)
186-
}
187-
188-
fn get_root_suffix(&self) -> Vec<u8> {
189-
self.root_index.0.to_be_bytes().to_vec()
184+
fn get_root_db_key<L: Leaf>(&self, key_context: &<L as HasStaticPrefix>::KeyContext) -> DbKey {
185+
let prefix = L::get_static_prefix(key_context);
186+
let suffix = self.root_index.0.to_be_bytes();
187+
create_db_key(prefix, INDEX_LAYOUT_DB_KEY_SEPARATOR, &suffix)
190188
}
191189
}

crates/starknet_committer/src/db/mock_forest_storage.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use crate::forest::original_skeleton_forest::{ForestSortedIndices, OriginalSkele
2323
use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState;
2424
use crate::patricia_merkle_tree::types::CompiledClassHash;
2525

26+
pub const EMPTY_DB_KEY_SEPARATOR: &[u8] = b"";
27+
2628
#[derive(Clone)]
2729
pub struct MockIndexInitialRead {}
2830

@@ -40,11 +42,14 @@ impl<S: Storage> ForestMetadata for MockForestStorage<S> {
4042
ForestMetadataType::CommitmentOffset => DbKey("commitment_offset".into()),
4143
ForestMetadataType::StateDiffHash(block_number) => create_db_key(
4244
DbKeyPrefix::new(b"state_diff_hash".into()),
45+
EMPTY_DB_KEY_SEPARATOR,
46+
&block_number.serialize(),
47+
),
48+
ForestMetadataType::StateRoot(block_number) => create_db_key(
49+
DbKeyPrefix::new(b"state_root".into()),
50+
EMPTY_DB_KEY_SEPARATOR,
4351
&block_number.serialize(),
4452
),
45-
ForestMetadataType::StateRoot(block_number) => {
46-
create_db_key(DbKeyPrefix::new(b"state_root".into()), &block_number.serialize())
47-
}
4853
}
4954
}
5055

crates/starknet_committer/src/db/trie_traversal.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use starknet_patricia::patricia_merkle_tree::traversal::{
2626
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
2727
use starknet_patricia_storage::db_object::{DBObject, EmptyKeyContext, HasStaticPrefix};
2828
use starknet_patricia_storage::errors::StorageError;
29-
use starknet_patricia_storage::storage_trait::{create_db_key, DbKey, Storage};
29+
use starknet_patricia_storage::storage_trait::{DbKey, Storage};
3030
use tracing::warn;
3131

3232
use crate::block_committer::input::{
@@ -245,12 +245,8 @@ pub async fn get_roots_from_storage<'a, L: Leaf, Layout: NodeLayout<'a, L>>(
245245
key_context: &<L as HasStaticPrefix>::KeyContext,
246246
) -> TraversalResult<Vec<FilledNode<L, Layout::NodeData>>> {
247247
let mut subtrees_roots = vec![];
248-
let db_keys: Vec<DbKey> = subtrees
249-
.iter()
250-
.map(|subtree| {
251-
create_db_key(subtree.get_root_prefix::<L>(key_context), &subtree.get_root_suffix())
252-
})
253-
.collect();
248+
let db_keys: Vec<DbKey> =
249+
subtrees.iter().map(|subtree| subtree.get_root_db_key::<L>(key_context)).collect();
254250

255251
let db_vals = storage.mget(&db_keys.iter().collect::<Vec<&DbKey>>()).await?;
256252
for ((subtree, optional_val), db_key) in subtrees.iter().zip(db_vals.iter()).zip(db_keys) {

crates/starknet_committer/src/patricia_merkle_tree/leaf/leaf_serde.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::collections::HashMap;
33
use serde_json::Value;
44
use starknet_api::core::{ClassHash, Nonce};
55
use starknet_api::hash::HashOutput;
6+
use starknet_patricia::patricia_merkle_tree::filled_tree::node_serde::FACT_LAYOUT_DB_KEY_SEPARATOR;
67
use starknet_patricia::patricia_merkle_tree::types::SubTreeHeight;
78
use starknet_patricia_storage::db_object::{DBObject, EmptyDeserializationContext};
89
use starknet_patricia_storage::errors::{DeserializationError, SerializationResult};
@@ -32,6 +33,8 @@ impl From<CommitterLeafPrefix> for DbKeyPrefix {
3233
}
3334

3435
impl DBObject for StarknetStorageValue {
36+
const DB_KEY_SEPARATOR: &[u8] = FACT_LAYOUT_DB_KEY_SEPARATOR;
37+
3538
type DeserializeContext = EmptyDeserializationContext;
3639

3740
/// Serializes the value into a 32-byte vector.
@@ -48,6 +51,8 @@ impl DBObject for StarknetStorageValue {
4851
}
4952

5053
impl DBObject for CompiledClassHash {
54+
const DB_KEY_SEPARATOR: &[u8] = FACT_LAYOUT_DB_KEY_SEPARATOR;
55+
5156
type DeserializeContext = EmptyDeserializationContext;
5257

5358
/// Creates a json string describing the leaf and casts it into a byte vector.
@@ -70,6 +75,8 @@ impl DBObject for CompiledClassHash {
7075
}
7176

7277
impl DBObject for ContractState {
78+
const DB_KEY_SEPARATOR: &[u8] = FACT_LAYOUT_DB_KEY_SEPARATOR;
79+
7380
type DeserializeContext = EmptyDeserializationContext;
7481

7582
/// Creates a json string describing the leaf and casts it into a byte vector.

crates/starknet_patricia/src/patricia_merkle_tree/external_test_utils.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ use super::original_skeleton_tree::node::OriginalSkeletonNode;
2222
use super::types::{NodeIndex, SubTreeHeight};
2323
use crate::felt::u256_from_felt;
2424
use crate::patricia_merkle_tree::errors::TypesError;
25+
use crate::patricia_merkle_tree::filled_tree::node_serde::FACT_LAYOUT_DB_KEY_SEPARATOR;
2526
use crate::patricia_merkle_tree::node_data::errors::{LeafError, LeafResult};
2627
use crate::patricia_merkle_tree::node_data::leaf::LeafWithEmptyKeyContext;
2728

28-
pub(crate) const TEST_PREFIX: &[u8] = &[0];
29+
const TEST_PREFIX: &[u8] = &[0];
2930

3031
#[derive(Debug, PartialEq, Clone, Copy, Default, Eq)]
3132
pub struct MockLeaf(pub Felt);
@@ -38,6 +39,8 @@ impl HasStaticPrefix for MockLeaf {
3839
}
3940

4041
impl DBObject for MockLeaf {
42+
const DB_KEY_SEPARATOR: &[u8] = FACT_LAYOUT_DB_KEY_SEPARATOR;
43+
4144
type DeserializeContext = EmptyDeserializationContext;
4245

4346
fn serialize(&self) -> SerializationResult<DbValue> {
@@ -117,11 +120,19 @@ pub fn create_32_bytes_entry(simple_val: u128) -> [u8; 32] {
117120
}
118121

119122
fn create_inner_node_patricia_key(val: Felt) -> DbKey {
120-
create_db_key(PatriciaPrefix::InnerNode.into(), &val.to_bytes_be())
123+
create_db_key(
124+
PatriciaPrefix::InnerNode.into(),
125+
FACT_LAYOUT_DB_KEY_SEPARATOR,
126+
&val.to_bytes_be(),
127+
)
121128
}
122129

123130
pub fn create_leaf_patricia_key<L: LeafWithEmptyKeyContext>(val: u128) -> DbKey {
124-
create_db_key(L::get_static_prefix(&EmptyKeyContext), &U256::from(val).to_be_bytes())
131+
create_db_key(
132+
L::get_static_prefix(&EmptyKeyContext),
133+
FACT_LAYOUT_DB_KEY_SEPARATOR,
134+
&U256::from(val).to_be_bytes(),
135+
)
125136
}
126137

127138
fn create_binary_val(left: Felt, right: Felt) -> DbValue {
@@ -196,7 +207,11 @@ pub fn create_root_edge_entry(old_root: u128, subtree_height: SubTreeHeight) ->
196207
// Assumes path is 0.
197208
let length = SubTreeHeight::ACTUAL_HEIGHT.0 - subtree_height.0;
198209
let new_root = old_root + u128::from(length);
199-
let key = create_db_key(PatriciaPrefix::InnerNode.into(), &Felt::from(new_root).to_bytes_be());
210+
let key = create_db_key(
211+
PatriciaPrefix::InnerNode.into(),
212+
FACT_LAYOUT_DB_KEY_SEPARATOR,
213+
&Felt::from(new_root).to_bytes_be(),
214+
);
200215
let value = DbValue(
201216
Felt::from(old_root)
202217
.to_bytes_be()

crates/starknet_patricia/src/patricia_merkle_tree/filled_tree/node_serde.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ pub(crate) const EDGE_BYTES: usize = SERIALIZE_HASH_BYTES + EDGE_PATH_BYTES + ED
2929
#[allow(dead_code)]
3030
pub(crate) const STORAGE_LEAF_SIZE: usize = SERIALIZE_HASH_BYTES;
3131

32+
pub const FACT_LAYOUT_DB_KEY_SEPARATOR: &[u8] = b":";
33+
3234
#[derive(Debug)]
3335
pub enum PatriciaPrefix {
3436
InnerNode,
@@ -65,6 +67,8 @@ pub struct FactNodeDeserializationContext {
6567
}
6668

6769
impl<L: Leaf> DBObject for FactDbFilledNode<L> {
70+
const DB_KEY_SEPARATOR: &[u8] = FACT_LAYOUT_DB_KEY_SEPARATOR;
71+
6872
type DeserializeContext = FactNodeDeserializationContext;
6973
/// This method serializes the filled node into a byte vector, where:
7074
/// - For binary nodes: Concatenates left and right hashes.

crates/starknet_patricia/src/patricia_merkle_tree/traversal.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use starknet_api::hash::HashOutput;
22
use starknet_patricia_storage::db_object::HasStaticPrefix;
33
use starknet_patricia_storage::errors::{DeserializationError, StorageError};
4-
use starknet_patricia_storage::storage_trait::{DbKeyPrefix, PatriciaStorageError};
4+
use starknet_patricia_storage::storage_trait::{DbKey, PatriciaStorageError};
55
use thiserror::Error;
66

77
use crate::patricia_merkle_tree::node_data::inner_node::PathToBottom;
@@ -116,14 +116,8 @@ pub trait SubTreeTrait<'a>: Sized {
116116
/// [crate::patricia_merkle_tree::original_skeleton_tree::tree::OriginalSkeletonTree].
117117
fn should_traverse_unmodified_child(data: Self::NodeData) -> UnmodifiedChildTraversal;
118118

119-
/// Returns the [DbKeyPrefix] of the root node.
120-
fn get_root_prefix<L: Leaf>(
121-
&self,
122-
key_context: &<L as HasStaticPrefix>::KeyContext,
123-
) -> DbKeyPrefix;
124-
125-
/// Returns the suffix of the root's db key.
126-
fn get_root_suffix(&self) -> Vec<u8>;
119+
/// Returns the full [DbKey] of the root node.
120+
fn get_root_db_key<L: Leaf>(&self, key_context: &<L as HasStaticPrefix>::KeyContext) -> DbKey;
127121

128122
/// Returns the `Self::NodeDeserializeContext` that's needed to deserialize the root node from a
129123
/// raw `DbValue`.

crates/starknet_patricia/src/patricia_merkle_tree/traversal_test.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ use ethnum::U256;
22
use pretty_assertions::assert_eq;
33
use rstest::rstest;
44
use starknet_patricia_storage::db_object::HasStaticPrefix;
5-
use starknet_patricia_storage::storage_trait::DbKeyPrefix;
5+
use starknet_patricia_storage::storage_trait::DbKey;
66

7-
use crate::patricia_merkle_tree::external_test_utils::{small_tree_index_to_full, TEST_PREFIX};
7+
use crate::patricia_merkle_tree::external_test_utils::small_tree_index_to_full;
88
use crate::patricia_merkle_tree::node_data::inner_node::{EdgePath, EdgePathLength, PathToBottom};
99
use crate::patricia_merkle_tree::node_data::leaf::Leaf;
1010
use crate::patricia_merkle_tree::traversal::{SubTreeTrait, UnmodifiedChildTraversal};
@@ -44,16 +44,8 @@ impl<'a> SubTreeTrait<'a> for TestSubTree<'a> {
4444

4545
fn get_root_context(&self) -> Self::NodeDeserializeContext {}
4646

47-
fn get_root_prefix<L: Leaf>(
48-
&self,
49-
_key_context: &<L as HasStaticPrefix>::KeyContext,
50-
) -> DbKeyPrefix {
51-
// Dummy prefix for testing purposes (we only need a prefix when interacting with storage).
52-
DbKeyPrefix::new(TEST_PREFIX.into())
53-
}
54-
55-
fn get_root_suffix(&self) -> Vec<u8> {
56-
vec![]
47+
fn get_root_db_key<L: Leaf>(&self, _key_context: &<L as HasStaticPrefix>::KeyContext) -> DbKey {
48+
DbKey(vec![])
5749
}
5850
}
5951

0 commit comments

Comments
 (0)