Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions crates/starknet_committer/src/db/facts_db/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ use starknet_api::hash::{HashOutput, StateRoots};
use starknet_patricia::patricia_merkle_tree::filled_tree::node_serde::{
FactNodeDeserializationContext,
PatriciaPrefix,
FACT_LAYOUT_DB_KEY_SEPARATOR,
};
use starknet_patricia::patricia_merkle_tree::node_data::leaf::Leaf;
use starknet_patricia::patricia_merkle_tree::traversal::{SubTreeTrait, UnmodifiedChildTraversal};
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
use starknet_patricia_storage::db_object::HasStaticPrefix;
use starknet_patricia_storage::storage_trait::DbKeyPrefix;
use starknet_patricia_storage::storage_trait::{create_db_key, DbKey, DbKeyPrefix};

use crate::block_committer::input::InputContext;

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

fn get_root_prefix<L: Leaf>(
&self,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> DbKeyPrefix {
if self.is_leaf() {
fn get_root_db_key<L: Leaf>(&self, key_context: &<L as HasStaticPrefix>::KeyContext) -> DbKey {
let prefix: DbKeyPrefix = if self.is_leaf() {
PatriciaPrefix::Leaf(L::get_static_prefix(key_context)).into()
} else {
PatriciaPrefix::InnerNode.into()
}
}

fn get_root_suffix(&self) -> Vec<u8> {
self.root_hash.0.to_bytes_be().to_vec()
};
let suffix = self.root_hash.0.to_bytes_be();
create_db_key(prefix, FACT_LAYOUT_DB_KEY_SEPARATOR, &suffix)
}
}
/// Used for reading the roots in facts layout case.
Expand Down
11 changes: 11 additions & 0 deletions crates/starknet_committer/src/db/index_db/leaves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ use starknet_patricia_storage::storage_trait::{DbKeyPrefix, DbValue};
use starknet_types_core::felt::Felt;

use crate::block_committer::input::StarknetStorageValue;
use crate::db::mock_forest_storage::EMPTY_DB_KEY_SEPARATOR;
use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState;
use crate::patricia_merkle_tree::types::CompiledClassHash;

pub const INDEX_LAYOUT_DB_KEY_SEPARATOR: &[u8] = EMPTY_DB_KEY_SEPARATOR;

// Wrap the leaves types so that we can implement the [DBObject] trait differently in index
// layout.
#[derive(
Expand Down Expand Up @@ -106,7 +110,10 @@ impl_leaf_for_wrappers!(
);

impl DBObject for IndexLayoutContractState {
const DB_KEY_SEPARATOR: &[u8] = INDEX_LAYOUT_DB_KEY_SEPARATOR;

type DeserializeContext = EmptyDeserializationContext;

fn serialize(&self) -> Result<DbValue, SerializationError> {
serialize_felts(&[self.0.class_hash.0, self.0.storage_root_hash.0, self.0.nonce.0])
}
Expand All @@ -131,6 +138,8 @@ impl DBObject for IndexLayoutContractState {
}

impl DBObject for IndexLayoutCompiledClassHash {
const DB_KEY_SEPARATOR: &[u8] = INDEX_LAYOUT_DB_KEY_SEPARATOR;

type DeserializeContext = EmptyDeserializationContext;

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

impl DBObject for IndexLayoutStarknetStorageValue {
const DB_KEY_SEPARATOR: &[u8] = INDEX_LAYOUT_DB_KEY_SEPARATOR;

type DeserializeContext = EmptyDeserializationContext;

fn serialize(&self) -> Result<DbValue, SerializationError> {
Expand Down
18 changes: 8 additions & 10 deletions crates/starknet_committer/src/db/index_db/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ use starknet_patricia_storage::db_object::{
HasStaticPrefix,
};
use starknet_patricia_storage::errors::{DeserializationError, SerializationResult};
use starknet_patricia_storage::storage_trait::{DbKeyPrefix, DbValue};
use starknet_patricia_storage::storage_trait::{create_db_key, DbKey, DbKeyPrefix, DbValue};
use starknet_types_core::felt::Felt;

use crate::db::index_db::leaves::INDEX_LAYOUT_DB_KEY_SEPARATOR;
use crate::hash_function::hash::TreeHashFunctionImpl;

// In index layout, for binary nodes, only the hash is stored.
Expand Down Expand Up @@ -56,6 +57,8 @@ where
L: Leaf,
TreeHashFunctionImpl: TreeHashFunction<L>,
{
const DB_KEY_SEPARATOR: &[u8] = INDEX_LAYOUT_DB_KEY_SEPARATOR;

type DeserializeContext = IndexNodeContext;

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

fn get_root_prefix<L: Leaf>(
&self,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> DbKeyPrefix {
L::get_static_prefix(key_context)
}

fn get_root_suffix(&self) -> Vec<u8> {
self.root_index.0.to_be_bytes().to_vec()
fn get_root_db_key<L: Leaf>(&self, key_context: &<L as HasStaticPrefix>::KeyContext) -> DbKey {
let prefix = L::get_static_prefix(key_context);
let suffix = self.root_index.0.to_be_bytes();
create_db_key(prefix, INDEX_LAYOUT_DB_KEY_SEPARATOR, &suffix)
}
}
11 changes: 8 additions & 3 deletions crates/starknet_committer/src/db/mock_forest_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ use crate::forest::original_skeleton_forest::{ForestSortedIndices, OriginalSkele
use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState;
use crate::patricia_merkle_tree::types::CompiledClassHash;

pub const EMPTY_DB_KEY_SEPARATOR: &[u8] = b"";

#[derive(Clone)]
pub struct MockIndexInitialRead {}

Expand All @@ -40,11 +42,14 @@ impl<S: Storage> ForestMetadata for MockForestStorage<S> {
ForestMetadataType::CommitmentOffset => DbKey("commitment_offset".into()),
ForestMetadataType::StateDiffHash(block_number) => create_db_key(
DbKeyPrefix::new(b"state_diff_hash".into()),
EMPTY_DB_KEY_SEPARATOR,
&block_number.serialize(),
),
ForestMetadataType::StateRoot(block_number) => create_db_key(
DbKeyPrefix::new(b"state_root".into()),
EMPTY_DB_KEY_SEPARATOR,
&block_number.serialize(),
),
ForestMetadataType::StateRoot(block_number) => {
create_db_key(DbKeyPrefix::new(b"state_root".into()), &block_number.serialize())
}
}
}

Expand Down
10 changes: 3 additions & 7 deletions crates/starknet_committer/src/db/trie_traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use starknet_patricia::patricia_merkle_tree::traversal::{
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
use starknet_patricia_storage::db_object::{DBObject, EmptyKeyContext, HasStaticPrefix};
use starknet_patricia_storage::errors::StorageError;
use starknet_patricia_storage::storage_trait::{create_db_key, DbKey, Storage};
use starknet_patricia_storage::storage_trait::{DbKey, Storage};
use tracing::warn;

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

let db_vals = storage.mget(&db_keys.iter().collect::<Vec<&DbKey>>()).await?;
for ((subtree, optional_val), db_key) in subtrees.iter().zip(db_vals.iter()).zip(db_keys) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::collections::HashMap;
use serde_json::Value;
use starknet_api::core::{ClassHash, Nonce};
use starknet_api::hash::HashOutput;
use starknet_patricia::patricia_merkle_tree::filled_tree::node_serde::FACT_LAYOUT_DB_KEY_SEPARATOR;
use starknet_patricia::patricia_merkle_tree::types::SubTreeHeight;
use starknet_patricia_storage::db_object::{DBObject, EmptyDeserializationContext};
use starknet_patricia_storage::errors::{DeserializationError, SerializationResult};
Expand Down Expand Up @@ -32,6 +33,8 @@ impl From<CommitterLeafPrefix> for DbKeyPrefix {
}

impl DBObject for StarknetStorageValue {
const DB_KEY_SEPARATOR: &[u8] = FACT_LAYOUT_DB_KEY_SEPARATOR;

type DeserializeContext = EmptyDeserializationContext;

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

impl DBObject for CompiledClassHash {
const DB_KEY_SEPARATOR: &[u8] = FACT_LAYOUT_DB_KEY_SEPARATOR;

type DeserializeContext = EmptyDeserializationContext;

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

impl DBObject for ContractState {
const DB_KEY_SEPARATOR: &[u8] = FACT_LAYOUT_DB_KEY_SEPARATOR;

type DeserializeContext = EmptyDeserializationContext;

/// Creates a json string describing the leaf and casts it into a byte vector.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ use super::original_skeleton_tree::node::OriginalSkeletonNode;
use super::types::{NodeIndex, SubTreeHeight};
use crate::felt::u256_from_felt;
use crate::patricia_merkle_tree::errors::TypesError;
use crate::patricia_merkle_tree::filled_tree::node_serde::FACT_LAYOUT_DB_KEY_SEPARATOR;
use crate::patricia_merkle_tree::node_data::errors::{LeafError, LeafResult};
use crate::patricia_merkle_tree::node_data::leaf::LeafWithEmptyKeyContext;

pub(crate) const TEST_PREFIX: &[u8] = &[0];
const TEST_PREFIX: &[u8] = &[0];

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

impl DBObject for MockLeaf {
const DB_KEY_SEPARATOR: &[u8] = FACT_LAYOUT_DB_KEY_SEPARATOR;

type DeserializeContext = EmptyDeserializationContext;

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

fn create_inner_node_patricia_key(val: Felt) -> DbKey {
create_db_key(PatriciaPrefix::InnerNode.into(), &val.to_bytes_be())
create_db_key(
PatriciaPrefix::InnerNode.into(),
FACT_LAYOUT_DB_KEY_SEPARATOR,
&val.to_bytes_be(),
)
}

pub fn create_leaf_patricia_key<L: LeafWithEmptyKeyContext>(val: u128) -> DbKey {
create_db_key(L::get_static_prefix(&EmptyKeyContext), &U256::from(val).to_be_bytes())
create_db_key(
L::get_static_prefix(&EmptyKeyContext),
FACT_LAYOUT_DB_KEY_SEPARATOR,
&U256::from(val).to_be_bytes(),
)
}

fn create_binary_val(left: Felt, right: Felt) -> DbValue {
Expand Down Expand Up @@ -196,7 +207,11 @@ pub fn create_root_edge_entry(old_root: u128, subtree_height: SubTreeHeight) ->
// Assumes path is 0.
let length = SubTreeHeight::ACTUAL_HEIGHT.0 - subtree_height.0;
let new_root = old_root + u128::from(length);
let key = create_db_key(PatriciaPrefix::InnerNode.into(), &Felt::from(new_root).to_bytes_be());
let key = create_db_key(
PatriciaPrefix::InnerNode.into(),
FACT_LAYOUT_DB_KEY_SEPARATOR,
&Felt::from(new_root).to_bytes_be(),
);
let value = DbValue(
Felt::from(old_root)
.to_bytes_be()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub(crate) const EDGE_BYTES: usize = SERIALIZE_HASH_BYTES + EDGE_PATH_BYTES + ED
#[allow(dead_code)]
pub(crate) const STORAGE_LEAF_SIZE: usize = SERIALIZE_HASH_BYTES;

pub const FACT_LAYOUT_DB_KEY_SEPARATOR: &[u8] = b":";

#[derive(Debug)]
pub enum PatriciaPrefix {
InnerNode,
Expand Down Expand Up @@ -65,6 +67,8 @@ pub struct FactNodeDeserializationContext {
}

impl<L: Leaf> DBObject for FactDbFilledNode<L> {
const DB_KEY_SEPARATOR: &[u8] = FACT_LAYOUT_DB_KEY_SEPARATOR;

type DeserializeContext = FactNodeDeserializationContext;
/// This method serializes the filled node into a byte vector, where:
/// - For binary nodes: Concatenates left and right hashes.
Expand Down
12 changes: 3 additions & 9 deletions crates/starknet_patricia/src/patricia_merkle_tree/traversal.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use starknet_api::hash::HashOutput;
use starknet_patricia_storage::db_object::HasStaticPrefix;
use starknet_patricia_storage::errors::{DeserializationError, StorageError};
use starknet_patricia_storage::storage_trait::{DbKeyPrefix, PatriciaStorageError};
use starknet_patricia_storage::storage_trait::{DbKey, PatriciaStorageError};
use thiserror::Error;

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

/// Returns the [DbKeyPrefix] of the root node.
fn get_root_prefix<L: Leaf>(
&self,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> DbKeyPrefix;

/// Returns the suffix of the root's db key.
fn get_root_suffix(&self) -> Vec<u8>;
/// Returns the full [DbKey] of the root node.
fn get_root_db_key<L: Leaf>(&self, key_context: &<L as HasStaticPrefix>::KeyContext) -> DbKey;

/// Returns the `Self::NodeDeserializeContext` that's needed to deserialize the root node from a
/// raw `DbValue`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use ethnum::U256;
use pretty_assertions::assert_eq;
use rstest::rstest;
use starknet_patricia_storage::db_object::HasStaticPrefix;
use starknet_patricia_storage::storage_trait::DbKeyPrefix;
use starknet_patricia_storage::storage_trait::DbKey;

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

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

fn get_root_prefix<L: Leaf>(
&self,
_key_context: &<L as HasStaticPrefix>::KeyContext,
) -> DbKeyPrefix {
// Dummy prefix for testing purposes (we only need a prefix when interacting with storage).
DbKeyPrefix::new(TEST_PREFIX.into())
}

fn get_root_suffix(&self) -> Vec<u8> {
vec![]
fn get_root_db_key<L: Leaf>(&self, _key_context: &<L as HasStaticPrefix>::KeyContext) -> DbKey {
DbKey(vec![])
}
}

Expand Down
5 changes: 4 additions & 1 deletion crates/starknet_patricia_storage/src/db_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ impl<T: HasStaticPrefix> HasDynamicPrefix for T {
pub struct EmptyDeserializationContext;

pub trait DBObject: Sized + HasDynamicPrefix {
/// The separator between the prefix and the suffix in the db key.
const DB_KEY_SEPARATOR: &[u8];

/// Extra data needed to deserialize the object. For example, facts layout nodes need the node
/// hash and an indication of whether or not it's a leaf node (index layout nodes only need the
/// latter).
Expand All @@ -49,6 +52,6 @@ pub trait DBObject: Sized + HasDynamicPrefix {

/// Returns a [DbKey] from a prefix and a suffix.
fn get_db_key(&self, key_context: &Self::KeyContext, suffix: &[u8]) -> DbKey {
create_db_key(self.get_prefix(key_context), suffix)
create_db_key(self.get_prefix(key_context), Self::DB_KEY_SEPARATOR, suffix)
}
}
6 changes: 3 additions & 3 deletions crates/starknet_patricia_storage/src/storage_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,9 @@ impl Serialize for DbKey {
}
}

/// Returns a `DbKey` from a prefix and a suffix.
pub fn create_db_key(prefix: DbKeyPrefix, suffix: &[u8]) -> DbKey {
DbKey([prefix.to_bytes().to_vec(), b":".to_vec(), suffix.to_vec()].concat())
/// Returns a `DbKey` from a prefix , separator, and suffix.
pub fn create_db_key(prefix: DbKeyPrefix, separator: &[u8], suffix: &[u8]) -> DbKey {
DbKey([prefix.to_bytes(), separator, suffix].concat().to_vec())
}

/// Extracts the suffix from a `DbKey`. If the key doesn't match the prefix, None is returned.
Expand Down
Loading