Skip to content

Commit bfbb61b

Browse files
committed
starknet_committer,starknet_patricia: add layout for base trait
1 parent 0a4c103 commit bfbb61b

File tree

6 files changed

+72
-47
lines changed

6 files changed

+72
-47
lines changed

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::HashMap;
33
use async_trait::async_trait;
44
use starknet_api::core::ContractAddress;
55
use starknet_api::hash::HashOutput;
6-
use starknet_patricia::db_layout::{NodeLayout, TrieType};
6+
use starknet_patricia::db_layout::{NodeLayout, NodeLayoutFor, TrieType};
77
use starknet_patricia::patricia_merkle_tree::filled_tree::node::{FactDbFilledNode, FilledNode};
88
use starknet_patricia::patricia_merkle_tree::filled_tree::node_serde::FactNodeDeserializationContext;
99
use starknet_patricia::patricia_merkle_tree::filled_tree::tree::FilledTree;
@@ -61,6 +61,18 @@ impl<'a, L: LeafWithEmptyKeyContext> NodeLayout<'a, L> for FactsNodeLayout {
6161
}
6262
}
6363

64+
impl NodeLayoutFor<StarknetStorageValue> for FactsNodeLayout {
65+
type DbLeaf = StarknetStorageValue;
66+
}
67+
68+
impl NodeLayoutFor<ContractState> for FactsNodeLayout {
69+
type DbLeaf = ContractState;
70+
}
71+
72+
impl NodeLayoutFor<CompiledClassHash> for FactsNodeLayout {
73+
type DbLeaf = CompiledClassHash;
74+
}
75+
6476
pub struct FactsDb<S: Storage> {
6577
// TODO(Yoav): Define StorageStats trait and impl it here. Then, make the storage field
6678
// private.
@@ -92,7 +104,7 @@ impl<S: Storage> ForestReader<FactsDbInitialRead> for FactsDb<S> {
92104
forest_sorted_indices: &'a ForestSortedIndices<'a>,
93105
config: ReaderConfig,
94106
) -> ForestResult<(OriginalSkeletonForest<'a>, HashMap<NodeIndex, ContractState>)> {
95-
read_forest::<S, StarknetStorageValue, ContractState, CompiledClassHash, FactsNodeLayout>(
107+
read_forest::<S, FactsNodeLayout>(
96108
&mut self.storage,
97109
context,
98110
storage_updates,

crates/starknet_committer/src/db/forest_trait.rs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use std::collections::HashMap;
33
use async_trait::async_trait;
44
use serde::{Deserialize, Serialize};
55
use starknet_api::core::ContractAddress;
6-
use starknet_patricia::db_layout::NodeLayout;
7-
use starknet_patricia::patricia_merkle_tree::node_data::leaf::{Leaf, LeafModifications};
6+
use starknet_patricia::db_layout::NodeLayoutFor;
7+
use starknet_patricia::patricia_merkle_tree::node_data::leaf::LeafModifications;
88
use starknet_patricia::patricia_merkle_tree::types::NodeIndex;
99
use starknet_patricia_storage::errors::SerializationResult;
1010
use starknet_patricia_storage::storage_trait::{DbHashMap, DbKey, DbValue, Storage};
@@ -69,7 +69,7 @@ pub trait ForestReader<I: InputContext> {
6969
}
7070

7171
/// Helper function containing layout-common read logic.
72-
pub(crate) async fn read_forest<'a, S, StorageLeaf, ContractStateLeaf, ClassesLeaf, Layout>(
72+
pub(crate) async fn read_forest<'a, S, Layout>(
7373
storage: &mut S,
7474
context: FactsDbInitialRead,
7575
storage_updates: &'a HashMap<ContractAddress, LeafModifications<StarknetStorageValue>>,
@@ -79,29 +79,25 @@ pub(crate) async fn read_forest<'a, S, StorageLeaf, ContractStateLeaf, ClassesLe
7979
) -> ForestResult<(OriginalSkeletonForest<'a>, HashMap<NodeIndex, ContractState>)>
8080
where
8181
S: Storage,
82-
ContractStateLeaf: Leaf + Into<ContractState>,
83-
StorageLeaf: Leaf + From<StarknetStorageValue>,
84-
ClassesLeaf: Leaf + From<CompiledClassHash>,
85-
Layout: NodeLayout<'a, StorageLeaf>
86-
+ NodeLayout<'a, ContractStateLeaf>
87-
+ NodeLayout<'a, ClassesLeaf>,
82+
Layout: NodeLayoutFor<StarknetStorageValue>
83+
+ NodeLayoutFor<ContractState>
84+
+ NodeLayoutFor<CompiledClassHash>,
8885
{
89-
let (contracts_trie, original_contracts_trie_leaves) =
90-
create_contracts_trie::<ContractStateLeaf, Layout>(
91-
storage,
92-
context.0.contracts_trie_root_hash,
93-
forest_sorted_indices.contracts_trie_sorted_indices,
94-
)
95-
.await?;
96-
let storage_tries = create_storage_tries::<StorageLeaf, Layout>(
86+
let (contracts_trie, original_contracts_trie_leaves) = create_contracts_trie::<Layout>(
87+
storage,
88+
context.0.contracts_trie_root_hash,
89+
forest_sorted_indices.contracts_trie_sorted_indices,
90+
)
91+
.await?;
92+
let storage_tries = create_storage_tries::<Layout>(
9793
storage,
9894
storage_updates,
9995
&original_contracts_trie_leaves,
10096
&config,
10197
&forest_sorted_indices.storage_tries_sorted_indices,
10298
)
10399
.await?;
104-
let classes_trie = create_classes_trie::<ClassesLeaf, Layout>(
100+
let classes_trie = create_classes_trie::<Layout>(
105101
storage,
106102
classes_updates,
107103
context.0.classes_trie_root_hash,

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::collections::HashMap;
33
use async_trait::async_trait;
44
use starknet_api::core::ContractAddress;
55
use starknet_api::hash::HashOutput;
6-
use starknet_patricia::db_layout::{NodeLayout, TrieType};
6+
use starknet_patricia::db_layout::{NodeLayout, NodeLayoutFor, TrieType};
77
use starknet_patricia::patricia_merkle_tree::filled_tree::node::FilledNode;
88
use starknet_patricia::patricia_merkle_tree::filled_tree::tree::FilledTree;
99
use starknet_patricia::patricia_merkle_tree::node_data::leaf::{Leaf, LeafModifications};
@@ -76,6 +76,18 @@ where
7676
}
7777
}
7878

79+
impl NodeLayoutFor<StarknetStorageValue> for IndexNodeLayout {
80+
type DbLeaf = IndexLayoutStarknetStorageValue;
81+
}
82+
83+
impl NodeLayoutFor<ContractState> for IndexNodeLayout {
84+
type DbLeaf = IndexLayoutContractState;
85+
}
86+
87+
impl NodeLayoutFor<CompiledClassHash> for IndexNodeLayout {
88+
type DbLeaf = IndexLayoutCompiledClassHash;
89+
}
90+
7991
// TODO(Ariel): define an IndexDbInitialRead empty type, and check whether each tree is empty inside
8092
// create_xxx_trie.
8193
#[async_trait]
@@ -91,13 +103,7 @@ impl<S: Storage> ForestReader<FactsDbInitialRead> for IndexDb<S> {
91103
forest_sorted_indices: &'a ForestSortedIndices<'a>,
92104
config: ReaderConfig,
93105
) -> ForestResult<(OriginalSkeletonForest<'a>, HashMap<NodeIndex, ContractState>)> {
94-
read_forest::<
95-
S,
96-
IndexLayoutStarknetStorageValue,
97-
IndexLayoutContractState,
98-
IndexLayoutCompiledClassHash,
99-
IndexNodeLayout,
100-
>(
106+
read_forest::<S, IndexNodeLayout>(
101107
&mut self.storage,
102108
context,
103109
storage_updates,

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ use crate::patricia_merkle_tree::types::CompiledClassHash;
2424
)]
2525
pub struct IndexLayoutContractState(pub ContractState);
2626

27-
#[derive(Clone, Debug, Default, Eq, PartialEq, derive_more::AsRef, derive_more::From)]
27+
#[derive(
28+
Clone, Debug, Default, Eq, PartialEq, derive_more::AsRef, derive_more::From, derive_more::Into,
29+
)]
2830
pub struct IndexLayoutCompiledClassHash(pub CompiledClassHash);
2931

30-
#[derive(Clone, Debug, Default, Eq, PartialEq, derive_more::From)]
32+
#[derive(Clone, Debug, Default, Eq, PartialEq, derive_more::From, derive_more::Into)]
3133
pub struct IndexLayoutStarknetStorageValue(pub StarknetStorageValue);
3234

3335
/// Set to 2^251 + 1 to avoid collisions with contract addresses prefixes.

crates/starknet_committer/src/db/trie_traversal.rs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::fmt::Debug;
44

55
use starknet_api::core::ContractAddress;
66
use starknet_api::hash::HashOutput;
7-
use starknet_patricia::db_layout::{NodeLayout, TrieType};
7+
use starknet_patricia::db_layout::{NodeLayout, NodeLayoutFor, TrieType};
88
use starknet_patricia::patricia_merkle_tree::filled_tree::node::FilledNode;
99
use starknet_patricia::patricia_merkle_tree::node_data::inner_node::{
1010
BinaryData,
@@ -341,11 +341,7 @@ pub async fn create_original_skeleton_tree<'a, L: Leaf, Layout: NodeLayout<'a, L
341341
Ok(skeleton_tree)
342342
}
343343

344-
pub async fn create_storage_tries<
345-
'a,
346-
L: Leaf + From<StarknetStorageValue>,
347-
Layout: NodeLayout<'a, L>,
348-
>(
344+
pub async fn create_storage_tries<'a, Layout: NodeLayoutFor<StarknetStorageValue>>(
349345
storage: &mut impl Storage,
350346
actual_storage_updates: &HashMap<ContractAddress, LeafModifications<StarknetStorageValue>>,
351347
original_contracts_trie_leaves: &HashMap<NodeIndex, ContractState>,
@@ -364,14 +360,14 @@ pub async fn create_storage_tries<
364360
config.warn_on_trivial_modifications(),
365361
);
366362

367-
let original_skeleton = create_original_skeleton_tree::<L, Layout>(
363+
let original_skeleton = create_original_skeleton_tree::<Layout::DbLeaf, Layout>(
368364
storage,
369365
contract_state.storage_root_hash,
370366
*sorted_leaf_indices,
371367
&config,
372368
// TODO(Ariel): Change `LeafModifications` in `actual_storage_updates` to be an
373369
// iterator over borrowed data so that the conversion below is costless.
374-
&updates.iter().map(|(idx, value)| (*idx, L::from(*value))).collect(),
370+
&updates.iter().map(|(idx, value)| (*idx, Layout::DbLeaf::from(*value))).collect(),
375371
None,
376372
&Layout::generate_key_context(TrieType::StorageTrie(*address)),
377373
)
@@ -383,15 +379,15 @@ pub async fn create_storage_tries<
383379

384380
/// Creates the contracts trie original skeleton.
385381
/// Also returns the previous contracts state of the modified contracts.
386-
pub async fn create_contracts_trie<'a, L: Leaf + Into<ContractState>, Layout: NodeLayout<'a, L>>(
382+
pub async fn create_contracts_trie<'a, Layout: NodeLayoutFor<ContractState>>(
387383
storage: &mut impl Storage,
388384
contracts_trie_root_hash: HashOutput,
389385
contracts_trie_sorted_indices: SortedLeafIndices<'a>,
390386
) -> ForestResult<(OriginalSkeletonTreeImpl<'a>, HashMap<NodeIndex, ContractState>)> {
391387
let config = OriginalSkeletonTrieConfig::new_for_contracts_trie();
392388

393389
let mut leaves = HashMap::new();
394-
let skeleton_tree = create_original_skeleton_tree::<L, Layout>(
390+
let skeleton_tree = create_original_skeleton_tree::<Layout::DbLeaf, Layout>(
395391
storage,
396392
contracts_trie_root_hash,
397393
contracts_trie_sorted_indices,
@@ -408,11 +404,7 @@ pub async fn create_contracts_trie<'a, L: Leaf + Into<ContractState>, Layout: No
408404
Ok((skeleton_tree, leaves))
409405
}
410406

411-
pub async fn create_classes_trie<
412-
'a,
413-
L: Leaf + From<CompiledClassHash>,
414-
Layout: NodeLayout<'a, L>,
415-
>(
407+
pub async fn create_classes_trie<'a, Layout: NodeLayoutFor<CompiledClassHash>>(
416408
storage: &mut impl Storage,
417409
actual_classes_updates: &LeafModifications<CompiledClassHash>,
418410
classes_trie_root_hash: HashOutput,
@@ -423,14 +415,17 @@ pub async fn create_classes_trie<
423415
config.warn_on_trivial_modifications(),
424416
);
425417

426-
Ok(create_original_skeleton_tree::<L, Layout>(
418+
Ok(create_original_skeleton_tree::<Layout::DbLeaf, Layout>(
427419
storage,
428420
classes_trie_root_hash,
429421
contracts_trie_sorted_indices,
430422
&config,
431423
// TODO(Ariel): Change `actual_classes_updates` to be an iterator over borrowed data so
432424
// that the conversion below is costless.
433-
&actual_classes_updates.iter().map(|(idx, value)| (*idx, L::from(*value))).collect(),
425+
&actual_classes_updates
426+
.iter()
427+
.map(|(idx, value)| (*idx, Layout::DbLeaf::from(*value)))
428+
.collect(),
434429
None,
435430
&Layout::generate_key_context(TrieType::ClassesTrie),
436431
)

crates/starknet_patricia/src/db_layout.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,17 @@ pub trait NodeLayout<'a, L: Leaf> {
8383
FilledNode { hash: filled_node.hash, data: node_data }
8484
}
8585
}
86+
87+
/// A layout trait for one of the base leaf types: StarknetStorageValue, ContractState, or
88+
/// CompiledClassHash. Use `NodeLayout<DbLeaf>` when you only deal with the DB representation, use
89+
/// `NodeLayoutFor<BaseLeaf>` when you need to refer to both the logical type and the DB type.
90+
///
91+
/// We require that the BaseLeaf type and its DB representation `NodeLayout::DbLeaf` are isomorphic.
92+
/// The `From<BaseLeaf>` conversions are needed to convert incoming modifications, and the
93+
/// `Into<BaseLeaf>` conversions are used in the `ContractState` case where we need to return the
94+
/// leaves. For more details see `create_contracts_trie`, `create_classes_trie`, and
95+
/// `create_storage_tries` in `starknet_committer`.
96+
pub trait NodeLayoutFor<BaseLeaf>: for<'a> NodeLayout<'a, Self::DbLeaf> {
97+
/// This layout's DB representation of BaseLeaf.
98+
type DbLeaf: Leaf + From<BaseLeaf> + Into<BaseLeaf>;
99+
}

0 commit comments

Comments
 (0)