Skip to content

Commit 54c6d2f

Browse files
committed
starknet_committer: add index layout leaves
1 parent e744065 commit 54c6d2f

File tree

8 files changed

+185
-7
lines changed

8 files changed

+185
-7
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/starknet_committer/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@ rand_distr.workspace = true
2020
rstest.workspace = true
2121
serde = { workspace = true, features = ["derive"] }
2222
serde_json.workspace = true
23-
starknet-types-core = { workspace = true, features = ["hash"] }
23+
starknet-types-core = { workspace = true, features = ["papyrus-serialization","hash"] }
2424
starknet_api.workspace = true
2525
starknet_patricia.workspace = true
2626
starknet_patricia_storage.workspace = true
2727
strum.workspace = true
2828
thiserror.workspace = true
2929
tokio = { workspace = true, features = ["rt"] }
3030
tracing.workspace = true
31+
derive_more.workspace = true
3132

3233
[dev-dependencies]
3334
starknet_api = { workspace = true, features = ["testing"] }

crates/starknet_committer/src/db.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ mod db_layout;
33
pub mod external_test_utils;
44
pub mod facts_db;
55
pub mod forest_trait;
6+
pub mod index_db;
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
use starknet_api::core::{ClassHash, ContractAddress, Nonce};
2+
use starknet_api::hash::HashOutput;
3+
use starknet_patricia::patricia_merkle_tree::node_data::errors::LeafResult;
4+
use starknet_patricia::patricia_merkle_tree::node_data::leaf::Leaf;
5+
use starknet_patricia_storage::db_object::{
6+
DBObject,
7+
EmptyDeserializationContext,
8+
HasStaticPrefix,
9+
};
10+
use starknet_patricia_storage::errors::{DeserializationError, SerializationError};
11+
use starknet_patricia_storage::storage_trait::{DbKeyPrefix, DbValue};
12+
use starknet_types_core::felt::Felt;
13+
14+
use crate::block_committer::input::StarknetStorageValue;
15+
use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState;
16+
use crate::patricia_merkle_tree::types::CompiledClassHash;
17+
18+
// Wrap the leaves types so that we can implement the [DBObject] trait differently in index
19+
// layout.
20+
#[derive(Clone, Debug, Default, Eq, PartialEq, derive_more::AsRef, derive_more::From)]
21+
pub struct IndexLayoutContractState(pub ContractState);
22+
23+
#[derive(Clone, Debug, Default, Eq, PartialEq, derive_more::AsRef, derive_more::From)]
24+
pub struct IndexLayoutCompiledClassHash(pub CompiledClassHash);
25+
26+
#[derive(Clone, Debug, Default, Eq, PartialEq, derive_more::From)]
27+
pub struct IndexLayoutStarknetStorageValue(pub StarknetStorageValue);
28+
29+
// TODO(Ariel): Delete this enum and use `CommitmentType` instead.
30+
#[derive(Debug, PartialEq)]
31+
pub enum TrieType {
32+
ContractsTrie,
33+
ClassesTrie,
34+
StorageTrie(ContractAddress),
35+
}
36+
37+
impl TrieType {
38+
fn db_prefix(&self) -> DbKeyPrefix {
39+
match self {
40+
TrieType::ContractsTrie => DbKeyPrefix::new(b"CONTRACTS_TREE_PREFIX"),
41+
TrieType::ClassesTrie => DbKeyPrefix::new(b"CLASSES_TREE_PREFIX"),
42+
TrieType::StorageTrie(contract_address) => {
43+
DbKeyPrefix::new(&(contract_address).to_bytes_be())
44+
}
45+
}
46+
}
47+
}
48+
49+
// TODO(Ariel): Remove this macro when HasStaticPrefix is a local trait. Replace with a blanket
50+
// impl for any type that implements some dummy IndexLayoutStaticPrefix trait.
51+
macro_rules! impl_has_static_prefix_for_index_layouts {
52+
($($ty:ty),* $(,)?) => {
53+
$(
54+
impl HasStaticPrefix for $ty {
55+
type KeyContext = TrieType;
56+
fn get_static_prefix(key_context: &Self::KeyContext) -> DbKeyPrefix {
57+
key_context.db_prefix()
58+
}
59+
}
60+
)*
61+
};
62+
}
63+
64+
impl_has_static_prefix_for_index_layouts! {
65+
IndexLayoutContractState,
66+
IndexLayoutCompiledClassHash,
67+
IndexLayoutStarknetStorageValue,
68+
}
69+
70+
macro_rules! impl_leaf_for_wrappers {
71+
($($wrapper:ty => $inner:ty),+ $(,)?) => {
72+
$(
73+
impl Leaf for $wrapper {
74+
type Input = <$inner as Leaf>::Input;
75+
type Output = <$inner as Leaf>::Output;
76+
77+
fn is_empty(&self) -> bool {
78+
// assumes `pub struct Wrapper(pub Inner);`
79+
self.0.is_empty()
80+
}
81+
82+
async fn create(
83+
input: Self::Input,
84+
) -> LeafResult<(Self, Self::Output)> {
85+
let (inner, output) = <$inner as Leaf>::create(input).await?;
86+
Ok((Self(inner), output))
87+
}
88+
}
89+
)+
90+
};
91+
}
92+
93+
impl_leaf_for_wrappers!(
94+
IndexLayoutContractState => ContractState,
95+
IndexLayoutStarknetStorageValue => StarknetStorageValue,
96+
IndexLayoutCompiledClassHash => CompiledClassHash,
97+
);
98+
99+
impl DBObject for IndexLayoutContractState {
100+
type DeserializeContext = EmptyDeserializationContext;
101+
fn serialize(&self) -> Result<DbValue, SerializationError> {
102+
let mut buffer = Vec::new();
103+
self.0.class_hash.0.serialize(&mut buffer)?;
104+
self.0.storage_root_hash.0.serialize(&mut buffer)?;
105+
self.0.nonce.0.serialize(&mut buffer)?;
106+
Ok(DbValue(buffer))
107+
}
108+
109+
fn deserialize(
110+
value: &DbValue,
111+
_deserialize_context: &Self::DeserializeContext,
112+
) -> Result<Self, DeserializationError> {
113+
let mut cursor: &[u8] = &value.0;
114+
let class_hash = Felt::deserialize(&mut cursor)
115+
.ok_or(DeserializationError::FeltDeserializationError(value.clone()))?;
116+
let storage_root_hash = Felt::deserialize(&mut cursor)
117+
.ok_or(DeserializationError::FeltDeserializationError(value.clone()))?;
118+
let nonce = Felt::deserialize(&mut cursor)
119+
.ok_or(DeserializationError::FeltDeserializationError(value.clone()))?;
120+
Ok(IndexLayoutContractState(ContractState {
121+
class_hash: ClassHash(class_hash),
122+
storage_root_hash: HashOutput(storage_root_hash),
123+
nonce: Nonce(nonce),
124+
}))
125+
}
126+
}
127+
128+
impl DBObject for IndexLayoutCompiledClassHash {
129+
type DeserializeContext = EmptyDeserializationContext;
130+
fn serialize(&self) -> Result<DbValue, SerializationError> {
131+
let mut buffer = Vec::new();
132+
self.0.0.serialize(&mut buffer)?;
133+
Ok(DbValue(buffer))
134+
}
135+
fn deserialize(
136+
value: &DbValue,
137+
_deserialize_context: &Self::DeserializeContext,
138+
) -> Result<Self, DeserializationError> {
139+
Ok(CompiledClassHash(
140+
Felt::deserialize(&mut &value.0[..])
141+
.ok_or(DeserializationError::FeltDeserializationError(value.clone()))?,
142+
)
143+
.into())
144+
}
145+
}
146+
147+
impl DBObject for IndexLayoutStarknetStorageValue {
148+
type DeserializeContext = EmptyDeserializationContext;
149+
fn serialize(&self) -> Result<DbValue, SerializationError> {
150+
let mut buffer = Vec::new();
151+
self.0.0.serialize(&mut buffer)?;
152+
Ok(DbValue(buffer))
153+
}
154+
fn deserialize(
155+
value: &DbValue,
156+
_deserialize_context: &Self::DeserializeContext,
157+
) -> Result<Self, DeserializationError> {
158+
Ok(IndexLayoutStarknetStorageValue(
159+
Felt::deserialize(&mut &value.0[..])
160+
.map(StarknetStorageValue)
161+
.ok_or(DeserializationError::FeltDeserializationError(value.clone()))?,
162+
))
163+
}
164+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod leaves;

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ pub struct ContractState {
2020
pub storage_root_hash: HashOutput,
2121
pub class_hash: ClassHash,
2222
}
23-
23+
impl AsRef<ContractState> for ContractState {
24+
fn as_ref(&self) -> &ContractState {
25+
self
26+
}
27+
}
2428
impl HasStaticPrefix for StarknetStorageValue {
2529
type KeyContext = EmptyKeyContext;
2630
fn get_static_prefix(_key_context: &Self::KeyContext) -> DbKeyPrefix {

crates/starknet_committer/src/patricia_merkle_tree/types.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ pub fn class_hash_into_node_index(class_hash: &ClassHash) -> NodeIndex {
2323
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
2424
pub struct CompiledClassHash(pub Felt);
2525

26+
impl AsRef<CompiledClassHash> for CompiledClassHash {
27+
fn as_ref(&self) -> &CompiledClassHash {
28+
self
29+
}
30+
}
31+
2632
impl_from_hex_for_felt_wrapper!(CompiledClassHash);
2733

2834
pub type StorageTrie = FilledTreeImpl<StarknetStorageValue>;

crates/starknet_patricia_storage/src/storage_trait.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -172,15 +172,15 @@ impl Storage for NullStorage {
172172
}
173173

174174
#[derive(Debug)]
175-
pub struct DbKeyPrefix(&'static [u8]);
175+
pub struct DbKeyPrefix(Vec<u8>);
176176

177177
impl DbKeyPrefix {
178-
pub fn new(prefix: &'static [u8]) -> Self {
179-
Self(prefix)
178+
pub fn new(prefix: &[u8]) -> Self {
179+
Self(prefix.to_vec())
180180
}
181181

182-
pub fn to_bytes(&self) -> &'static [u8] {
183-
self.0
182+
pub fn to_bytes(&self) -> &[u8] {
183+
self.0.as_slice()
184184
}
185185
}
186186

0 commit comments

Comments
 (0)