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
12 changes: 9 additions & 3 deletions crates/starknet_committer/src/db/external_test_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ use starknet_patricia::patricia_merkle_tree::updated_skeleton_tree::tree::{
UpdatedSkeletonTree,
UpdatedSkeletonTreeImpl,
};
use starknet_patricia_storage::db_object::{EmptyKeyContext, HasStaticPrefix};
use starknet_patricia_storage::map_storage::MapStorage;

use crate::db::facts_db::create_facts_tree::create_original_skeleton_tree;

// TODO(Ariel, 14/12/2025): make this generic over the layout.
pub async fn tree_computation_flow<L, TH>(
leaf_modifications: LeafModifications<L>,
storage: &mut MapStorage,
Expand All @@ -27,7 +29,7 @@ pub async fn tree_computation_flow<L, TH>(
) -> FilledTreeImpl<L>
where
TH: TreeHashFunction<L> + 'static,
L: Leaf + 'static,
L: Leaf + HasStaticPrefix<KeyContext = EmptyKeyContext> + 'static,
{
let mut sorted_leaf_indices: Vec<NodeIndex> = leaf_modifications.keys().copied().collect();
let sorted_leaf_indices = SortedLeafIndices::new(&mut sorted_leaf_indices);
Expand All @@ -37,6 +39,7 @@ where
sorted_leaf_indices,
&config,
&leaf_modifications,
&EmptyKeyContext,
)
.await
.expect("Failed to create the original skeleton tree");
Expand All @@ -63,7 +66,10 @@ where
.expect("Failed to create the filled tree")
}

pub async fn single_tree_flow_test<L: Leaf + 'static, TH: TreeHashFunction<L> + 'static>(
pub async fn single_tree_flow_test<
L: Leaf + HasStaticPrefix<KeyContext = EmptyKeyContext> + 'static,
TH: TreeHashFunction<L> + 'static,
>(
leaf_modifications: LeafModifications<L>,
storage: &mut MapStorage,
root_hash: HashOutput,
Expand All @@ -85,7 +91,7 @@ pub async fn single_tree_flow_test<L: Leaf + 'static, TH: TreeHashFunction<L> +
let json_hash = &json!(hash_result.0.to_hex_string());
result_map.insert("root_hash", json_hash);
// Serlialize the storage modifications.
let json_storage = &json!(filled_tree.serialize());
let json_storage = &json!(filled_tree.serialize(&EmptyKeyContext));
result_map.insert("storage_changes", json_storage);
serde_json::to_string(&result_map).expect("serialization failed")
}
14 changes: 13 additions & 1 deletion crates/starknet_committer/src/db/facts_db/create_facts_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use starknet_patricia::patricia_merkle_tree::original_skeleton_tree::tree::{
};
use starknet_patricia::patricia_merkle_tree::traversal::SubTreeTrait;
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
use starknet_patricia_storage::db_object::HasStaticPrefix;
use starknet_patricia_storage::storage_trait::Storage;
use tracing::warn;

Expand Down Expand Up @@ -48,13 +49,15 @@ async fn fetch_nodes<'a, L: Leaf>(
leaf_modifications: &LeafModifications<L>,
config: &impl OriginalSkeletonTreeConfig<L>,
mut previous_leaves: Option<&mut HashMap<NodeIndex, L>>,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> OriginalSkeletonTreeResult<()> {
let mut current_subtrees = subtrees;
let mut next_subtrees = Vec::new();
while !current_subtrees.is_empty() {
let should_fetch_modified_leaves =
config.compare_modified_leaves() || previous_leaves.is_some();
let filled_roots = calculate_subtrees_roots::<L>(&current_subtrees, storage).await?;
let filled_roots =
calculate_subtrees_roots::<L>(&current_subtrees, storage, key_context).await?;
for (filled_root, subtree) in filled_roots.into_iter().zip(current_subtrees.iter()) {
match filled_root.data {
// Binary node.
Expand Down Expand Up @@ -150,6 +153,7 @@ pub async fn create_original_skeleton_tree<'a, L: Leaf>(
sorted_leaf_indices: SortedLeafIndices<'a>,
config: &impl OriginalSkeletonTreeConfig<L>,
leaf_modifications: &LeafModifications<L>,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> OriginalSkeletonTreeResult<OriginalSkeletonTreeImpl<'a>> {
if sorted_leaf_indices.is_empty() {
return Ok(OriginalSkeletonTreeImpl::create_unmodified(root_hash));
Expand All @@ -171,6 +175,7 @@ pub async fn create_original_skeleton_tree<'a, L: Leaf>(
leaf_modifications,
config,
None,
key_context,
)
.await?;
Ok(skeleton_tree)
Expand All @@ -182,6 +187,7 @@ pub async fn create_original_skeleton_tree_and_get_previous_leaves<'a, L: Leaf>(
sorted_leaf_indices: SortedLeafIndices<'a>,
leaf_modifications: &LeafModifications<L>,
config: &impl OriginalSkeletonTreeConfig<L>,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> OriginalSkeletonTreeResult<(OriginalSkeletonTreeImpl<'a>, HashMap<NodeIndex, L>)> {
if sorted_leaf_indices.is_empty() {
let unmodified = OriginalSkeletonTreeImpl::create_unmodified(root_hash);
Expand All @@ -203,15 +209,20 @@ pub async fn create_original_skeleton_tree_and_get_previous_leaves<'a, L: Leaf>(
leaf_modifications,
config,
Some(&mut leaves),
key_context,
)
.await?;
Ok((skeleton_tree, leaves))
}

/// Prepares the OS inputs by fetching paths to the given leaves (i.e. their induced Skeleton tree).
/// Note that ATM, the Rust committer does not manage history and is not used for storage proofs;
/// Thus, this function assumes facts layout.
pub async fn get_leaves<'a, L: Leaf>(
storage: &mut impl Storage,
root_hash: HashOutput,
sorted_leaf_indices: SortedLeafIndices<'a>,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> OriginalSkeletonTreeResult<HashMap<NodeIndex, L>> {
let config = NoCompareOriginalSkeletonTrieConfig::default();
let leaf_modifications = LeafModifications::new();
Expand All @@ -221,6 +232,7 @@ pub async fn get_leaves<'a, L: Leaf>(
sorted_leaf_indices,
&leaf_modifications,
&config,
key_context,
)
.await?;
Ok(previous_leaves)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use starknet_patricia::patricia_merkle_tree::external_test_utils::{
use starknet_patricia::patricia_merkle_tree::node_data::leaf::LeafModifications;
use starknet_patricia::patricia_merkle_tree::original_skeleton_tree::node::OriginalSkeletonNode;
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices, SubTreeHeight};
use starknet_patricia_storage::db_object::DBObject;
use starknet_patricia_storage::db_object::{DBObject, EmptyKeyContext};
use starknet_patricia_storage::map_storage::MapStorage;
use starknet_patricia_storage::storage_trait::{DbHashMap, DbKey, DbValue};
use starknet_types_core::felt::Felt;
Expand Down Expand Up @@ -217,6 +217,7 @@ async fn test_create_tree(
sorted_leaf_indices,
&config,
&leaf_modifications,
&EmptyKeyContext,
)
.await
.unwrap();
Expand All @@ -225,7 +226,7 @@ async fn test_create_tree(

pub(crate) fn create_mock_leaf_entry(val: u128) -> (DbKey, DbValue) {
let leaf = MockLeaf(Felt::from(val));
(leaf.get_db_key(&leaf.0.to_bytes_be()), leaf.serialize())
(leaf.get_db_key(&EmptyKeyContext, &leaf.0.to_bytes_be()), leaf.serialize())
}

fn create_mock_leaf_modifications(
Expand Down
10 changes: 7 additions & 3 deletions crates/starknet_committer/src/db/facts_db/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use starknet_patricia::patricia_merkle_tree::filled_tree::tree::FilledTree;
use starknet_patricia::patricia_merkle_tree::node_data::leaf::LeafModifications;
use starknet_patricia::patricia_merkle_tree::original_skeleton_tree::tree::OriginalSkeletonTreeImpl;
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
use starknet_patricia_storage::db_object::EmptyKeyContext;
use starknet_patricia_storage::map_storage::MapStorage;
use starknet_patricia_storage::storage_trait::{
create_db_key,
Expand Down Expand Up @@ -65,6 +66,7 @@ impl<S: Storage> FactsDb<S> {
contracts_trie_sorted_indices,
&HashMap::new(),
&OriginalSkeletonContractsTrieConfig::new(),
&EmptyKeyContext,
)
.await?)
}
Expand Down Expand Up @@ -93,6 +95,7 @@ impl<S: Storage> FactsDb<S> {
*sorted_leaf_indices,
&config,
updates,
&EmptyKeyContext,
)
.await?;
storage_tries.insert(*address, original_skeleton);
Expand All @@ -115,6 +118,7 @@ impl<S: Storage> FactsDb<S> {
contracts_trie_sorted_indices,
&config,
actual_classes_updates,
&EmptyKeyContext,
)
.await?)
}
Expand Down Expand Up @@ -175,9 +179,9 @@ impl<S: Storage> ForestWriter for FactsDb<S> {
filled_forest
.storage_tries
.values()
.flat_map(|tree| tree.serialize().into_iter())
.chain(filled_forest.contracts_trie.serialize())
.chain(filled_forest.classes_trie.serialize())
.flat_map(|tree| tree.serialize(&EmptyKeyContext).into_iter())
.chain(filled_forest.contracts_trie.serialize(&EmptyKeyContext))
.chain(filled_forest.classes_trie.serialize(&EmptyKeyContext))
.collect()
}

Expand Down
21 changes: 18 additions & 3 deletions crates/starknet_committer/src/db/facts_db/traversal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use starknet_patricia::patricia_merkle_tree::node_data::inner_node::{
use starknet_patricia::patricia_merkle_tree::node_data::leaf::Leaf;
use starknet_patricia::patricia_merkle_tree::traversal::{SubTreeTrait, TraversalResult};
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
use starknet_patricia_storage::db_object::HasStaticPrefix;
use starknet_patricia_storage::errors::StorageError;
use starknet_patricia_storage::storage_trait::{create_db_key, DbKey, Storage};

Expand All @@ -23,12 +24,16 @@ pub mod traversal_test;
pub async fn calculate_subtrees_roots<'a, L: Leaf>(
subtrees: &[FactsSubTree<'a>],
storage: &mut impl Storage,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> TraversalResult<Vec<FilledNode<L>>> {
let mut subtrees_roots = vec![];
let db_keys: Vec<DbKey> = subtrees
.iter()
.map(|subtree| {
create_db_key(subtree.get_root_prefix::<L>(), &subtree.root_hash.0.to_bytes_be())
create_db_key(
subtree.get_root_prefix::<L>(key_context),
&subtree.root_hash.0.to_bytes_be(),
)
})
.collect();

Expand All @@ -49,6 +54,7 @@ pub async fn fetch_patricia_paths<L: Leaf>(
root_hash: HashOutput,
sorted_leaf_indices: SortedLeafIndices<'_>,
leaves: Option<&mut HashMap<NodeIndex, L>>,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> TraversalResult<PreimageMap> {
let mut witnesses = PreimageMap::new();

Expand All @@ -58,7 +64,14 @@ pub async fn fetch_patricia_paths<L: Leaf>(

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

fetch_patricia_paths_inner::<L>(storage, vec![main_subtree], &mut witnesses, leaves).await?;
fetch_patricia_paths_inner::<L>(
storage,
vec![main_subtree],
&mut witnesses,
leaves,
key_context,
)
.await?;
Ok(witnesses)
}

Expand All @@ -74,11 +87,13 @@ pub(crate) async fn fetch_patricia_paths_inner<'a, L: Leaf>(
subtrees: Vec<FactsSubTree<'a>>,
witnesses: &mut PreimageMap,
mut leaves: Option<&mut HashMap<NodeIndex, L>>,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> TraversalResult<()> {
let mut current_subtrees = subtrees;
let mut next_subtrees = Vec::new();
while !current_subtrees.is_empty() {
let filled_roots = calculate_subtrees_roots::<L>(&current_subtrees, storage).await?;
let filled_roots =
calculate_subtrees_roots::<L>(&current_subtrees, storage, key_context).await?;
for (filled_root, subtree) in filled_roots.into_iter().zip(current_subtrees.iter()) {
// Always insert root.
// No need to insert an unmodified node (which is not the root), because its parent is
Expand Down
2 changes: 2 additions & 0 deletions crates/starknet_committer/src/db/facts_db/traversal_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use starknet_patricia::patricia_merkle_tree::node_data::inner_node::{
};
use starknet_patricia::patricia_merkle_tree::traversal::SubTreeTrait;
use starknet_patricia::patricia_merkle_tree::types::{SortedLeafIndices, SubTreeHeight};
use starknet_patricia_storage::db_object::EmptyKeyContext;
use starknet_patricia_storage::map_storage::MapStorage;
use starknet_patricia_storage::storage_trait::{DbHashMap, DbKey, DbValue};
use starknet_types_core::felt::Felt;
Expand Down Expand Up @@ -87,6 +88,7 @@ async fn test_fetch_patricia_paths_inner_impl(
vec![main_subtree],
&mut nodes,
Some(&mut fetched_leaves),
&EmptyKeyContext,
)
.await
.unwrap();
Expand Down
8 changes: 6 additions & 2 deletions crates/starknet_committer/src/db/facts_db/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use starknet_patricia::patricia_merkle_tree::filled_tree::node_serde::PatriciaPr
use starknet_patricia::patricia_merkle_tree::node_data::leaf::Leaf;
use starknet_patricia::patricia_merkle_tree::traversal::SubTreeTrait;
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
use starknet_patricia_storage::db_object::HasStaticPrefix;
use starknet_patricia_storage::storage_trait::DbKeyPrefix;

#[derive(Debug, PartialEq)]
Expand Down Expand Up @@ -35,9 +36,12 @@ impl<'a> SubTreeTrait<'a> for FactsSubTree<'a> {
false
}

fn get_root_prefix<L: Leaf>(&self) -> DbKeyPrefix {
fn get_root_prefix<L: Leaf>(
&self,
key_context: &<L as HasStaticPrefix>::KeyContext,
) -> DbKeyPrefix {
if self.is_leaf() {
PatriciaPrefix::Leaf(L::get_static_prefix()).into()
PatriciaPrefix::Leaf(L::get_static_prefix(key_context)).into()
} else {
PatriciaPrefix::InnerNode.into()
}
Expand Down
4 changes: 2 additions & 2 deletions crates/starknet_committer/src/forest/filled_forest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ impl FilledForest {
contract_address_to_storage_skeleton.len(),
contract_address_to_storage_updates.len()
);
// `contract_address_to_storage_updates` includes all modified contracts, even those with
// unmodified storage, see StateDiff::actual_storage_updates().
// `contract_address_to_storage_updates` includes all modified contracts, even those
// with unmodified storage, see StateDiff::actual_storage_updates().
for (contract_address, storage_updates) in contract_address_to_storage_updates {
let node_index = contract_address_into_node_index(&contract_address);
let original_contract_state = original_contracts_trie_leaves
Expand Down
8 changes: 4 additions & 4 deletions crates/starknet_committer/src/forest/skeleton_forest_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use starknet_patricia::patricia_merkle_tree::external_test_utils::{
};
use starknet_patricia::patricia_merkle_tree::original_skeleton_tree::tree::OriginalSkeletonTreeImpl;
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices, SubTreeHeight};
use starknet_patricia_storage::db_object::DBObject;
use starknet_patricia_storage::db_object::{DBObject, EmptyKeyContext};
use starknet_patricia_storage::map_storage::MapStorage;
use starknet_patricia_storage::storage_trait::{DbHashMap, DbKey, DbValue};
use starknet_types_core::felt::Felt;
Expand Down Expand Up @@ -50,12 +50,12 @@ macro_rules! compare_skeleton_tree {

pub(crate) fn create_storage_leaf_entry(val: u128) -> (DbKey, DbValue) {
let leaf = StarknetStorageValue(Felt::from(val));
(leaf.get_db_key(&leaf.0.to_bytes_be()), leaf.serialize())
(leaf.get_db_key(&EmptyKeyContext, &leaf.0.to_bytes_be()), leaf.serialize())
}

pub(crate) fn create_compiled_class_leaf_entry(val: u128) -> (DbKey, DbValue) {
let leaf = CompiledClassHash(Felt::from(val));
(leaf.get_db_key(&leaf.0.to_bytes_be()), leaf.serialize())
(leaf.get_db_key(&EmptyKeyContext, &leaf.0.to_bytes_be()), leaf.serialize())
}

pub(crate) fn create_contract_state_leaf_entry(val: u128) -> (DbKey, DbValue) {
Expand All @@ -65,7 +65,7 @@ pub(crate) fn create_contract_state_leaf_entry(val: u128) -> (DbKey, DbValue) {
storage_root_hash: HashOutput(felt),
class_hash: ClassHash(felt),
};
(leaf.get_db_key(&felt.to_bytes_be()), leaf.serialize())
(leaf.get_db_key(&EmptyKeyContext, &felt.to_bytes_be()), leaf.serialize())
}

// This test uses addition hash for simplicity (i.e hash(a,b) = a + b).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use starknet_patricia::patricia_merkle_tree::node_data::errors::{LeafError, Leaf
use starknet_patricia::patricia_merkle_tree::node_data::leaf::{Leaf, LeafModifications};
use starknet_patricia::patricia_merkle_tree::types::NodeIndex;
use starknet_patricia::patricia_merkle_tree::updated_skeleton_tree::tree::UpdatedSkeletonTreeImpl;
use starknet_patricia_storage::db_object::HasStaticPrefix;
use starknet_patricia_storage::db_object::{EmptyKeyContext, HasStaticPrefix};
use starknet_patricia_storage::storage_trait::DbKeyPrefix;
use starknet_types_core::felt::Felt;

Expand All @@ -22,7 +22,8 @@ pub struct ContractState {
}

impl HasStaticPrefix for StarknetStorageValue {
fn get_static_prefix() -> DbKeyPrefix {
type KeyContext = EmptyKeyContext;
fn get_static_prefix(_key_context: &Self::KeyContext) -> DbKeyPrefix {
CommitterLeafPrefix::StorageLeaf.into()
}
}
Expand All @@ -41,7 +42,8 @@ impl Leaf for StarknetStorageValue {
}

impl HasStaticPrefix for CompiledClassHash {
fn get_static_prefix() -> DbKeyPrefix {
type KeyContext = EmptyKeyContext;
fn get_static_prefix(_key_context: &Self::KeyContext) -> DbKeyPrefix {
CommitterLeafPrefix::CompiledClassLeaf.into()
}
}
Expand All @@ -60,7 +62,8 @@ impl Leaf for CompiledClassHash {
}

impl HasStaticPrefix for ContractState {
fn get_static_prefix() -> DbKeyPrefix {
type KeyContext = EmptyKeyContext;
fn get_static_prefix(_key_context: &Self::KeyContext) -> DbKeyPrefix {
CommitterLeafPrefix::StateTreeLeaf.into()
}
}
Expand Down
Loading
Loading