Skip to content

Commit d5e2d5f

Browse files
committed
starknet_committer,starknet_patricia: enrich subtree trait to support fetch nodes
1 parent a33b741 commit d5e2d5f

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

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

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use starknet_api::hash::HashOutput;
2-
use starknet_patricia::patricia_merkle_tree::filled_tree::node_serde::PatriciaPrefix;
2+
use starknet_patricia::patricia_merkle_tree::filled_tree::node_serde::{
3+
FactNodeDeserializationContext,
4+
PatriciaPrefix,
5+
};
36
use starknet_patricia::patricia_merkle_tree::node_data::leaf::Leaf;
4-
use starknet_patricia::patricia_merkle_tree::traversal::SubTreeTrait;
7+
use starknet_patricia::patricia_merkle_tree::traversal::{SubTreeTrait, UnmodifiedChildTraversal};
58
use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices};
69
use starknet_patricia_storage::db_object::HasStaticPrefix;
710
use starknet_patricia_storage::storage_trait::DbKeyPrefix;
@@ -15,6 +18,7 @@ pub struct FactsSubTree<'a> {
1518

1619
impl<'a> SubTreeTrait<'a> for FactsSubTree<'a> {
1720
type NodeData = HashOutput;
21+
type NodeDeserializeContext = FactNodeDeserializationContext;
1822

1923
fn create(
2024
sorted_leaf_indices: SortedLeafIndices<'a>,
@@ -32,8 +36,12 @@ impl<'a> SubTreeTrait<'a> for FactsSubTree<'a> {
3236
&self.sorted_leaf_indices
3337
}
3438

35-
fn should_traverse_unmodified_children() -> bool {
36-
false
39+
fn should_traverse_unmodified_child(data: Self::NodeData) -> UnmodifiedChildTraversal {
40+
UnmodifiedChildTraversal::Skip(data)
41+
}
42+
43+
fn get_root_context(&self) -> Self::NodeDeserializeContext {
44+
Self::NodeDeserializeContext { is_leaf: self.is_leaf(), node_hash: self.root_hash }
3745
}
3846

3947
fn get_root_prefix<L: Leaf>(
@@ -46,4 +54,8 @@ impl<'a> SubTreeTrait<'a> for FactsSubTree<'a> {
4654
PatriciaPrefix::InnerNode.into()
4755
}
4856
}
57+
58+
fn get_root_suffix(&self) -> Vec<u8> {
59+
self.root_hash.0.to_bytes_be().to_vec()
60+
}
4961
}

crates/starknet_patricia/src/patricia_merkle_tree/traversal.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use starknet_api::hash::HashOutput;
12
use starknet_patricia_storage::db_object::HasStaticPrefix;
23
use starknet_patricia_storage::errors::{DeserializationError, StorageError};
34
use starknet_patricia_storage::storage_trait::{DbKeyPrefix, PatriciaStorageError};
@@ -22,6 +23,16 @@ pub enum TraversalError {
2223
PatriciaStorage(#[from] PatriciaStorageError),
2324
}
2425

26+
/// An enum that specifies how to treat unmodified children during the construction of the
27+
/// [OriginalSkeletonTree].
28+
pub enum UnmodifiedChildTraversal {
29+
// Indicates that the child must be read since we don't have the data to create an original
30+
// tree node.
31+
Traverse,
32+
// Indicates that the child should be skipped as its unmodified and we have its hash.
33+
Skip(HashOutput),
34+
}
35+
2536
pub type TraversalResult<T> = Result<T, TraversalError>;
2637

2738
/// A trait that allows traversing a trie without knowledge of the concrete node types and data or
@@ -30,6 +41,10 @@ pub trait SubTreeTrait<'a>: Sized {
3041
/// Extra data a node can carry (e.g. its hash).
3142
type NodeData;
3243

44+
/// Extra context needed to deserialize a node from a raw DbValue. For more info, see
45+
/// `DeserializeContext` in the `DBObject` trait.
46+
type NodeDeserializeContext;
47+
3348
/// Creates a concrete child node given its index and data.
3449
fn create(
3550
sorted_leaf_indices: SortedLeafIndices<'a>,
@@ -97,13 +112,20 @@ pub trait SubTreeTrait<'a>: Sized {
97112
self.get_root_index().is_leaf()
98113
}
99114

100-
/// Indicates whether unmodified children should be traversed during the construction of the
101-
/// original skeleton tree.
102-
fn should_traverse_unmodified_children() -> bool;
115+
/// Decide whether to traverse an unmodified child during the construction of the
116+
/// `OriginalSkeletonTree`.
117+
fn should_traverse_unmodified_child(data: Self::NodeData) -> UnmodifiedChildTraversal;
103118

104119
/// Returns the [DbKeyPrefix] of the root node.
105120
fn get_root_prefix<L: Leaf>(
106121
&self,
107122
key_context: &<L as HasStaticPrefix>::KeyContext,
108123
) -> DbKeyPrefix;
124+
125+
/// Returns the suffix of the root's db key.
126+
fn get_root_suffix(&self) -> Vec<u8>;
127+
128+
/// Returns the `Self::NodeDeserializeContext` that's needed to deserialize the root node from a
129+
/// raw `DbValue`.
130+
fn get_root_context(&self) -> Self::NodeDeserializeContext;
109131
}

crates/starknet_patricia/src/patricia_merkle_tree/traversal_test.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use starknet_patricia_storage::storage_trait::DbKeyPrefix;
77
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;
10-
use crate::patricia_merkle_tree::traversal::SubTreeTrait;
10+
use crate::patricia_merkle_tree::traversal::{SubTreeTrait, UnmodifiedChildTraversal};
1111
use crate::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices, SubTreeHeight};
1212

1313
/// Test implementation for [SubTreeTrait]. It should only be used for child creation purposes,
@@ -20,6 +20,7 @@ struct TestSubTree<'a> {
2020

2121
impl<'a> SubTreeTrait<'a> for TestSubTree<'a> {
2222
type NodeData = ();
23+
type NodeDeserializeContext = ();
2324

2425
fn create(
2526
sorted_leaf_indices: SortedLeafIndices<'a>,
@@ -37,17 +38,23 @@ impl<'a> SubTreeTrait<'a> for TestSubTree<'a> {
3738
&self.sorted_leaf_indices
3839
}
3940

40-
fn should_traverse_unmodified_children() -> bool {
41-
false
41+
fn should_traverse_unmodified_child(_child_data: Self::NodeData) -> UnmodifiedChildTraversal {
42+
UnmodifiedChildTraversal::Traverse
4243
}
4344

45+
fn get_root_context(&self) -> Self::NodeDeserializeContext {}
46+
4447
fn get_root_prefix<L: Leaf>(
4548
&self,
4649
_key_context: &<L as HasStaticPrefix>::KeyContext,
4750
) -> DbKeyPrefix {
4851
// Dummy prefix for testing purposes (we only need a prefix when interacting with storage).
4952
DbKeyPrefix::new(&[0])
5053
}
54+
55+
fn get_root_suffix(&self) -> Vec<u8> {
56+
vec![]
57+
}
5158
}
5259

5360
/// case::single_right_child

0 commit comments

Comments
 (0)