Skip to content

Commit 398ddb7

Browse files
committed
starknet_committer: add patricia paths forest reader/writer traits
1 parent 7b294f1 commit 398ddb7

2 files changed

Lines changed: 87 additions & 0 deletions

File tree

crates/starknet_committer/src/db/forest_trait.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@ use std::collections::HashMap;
22

33
use async_trait::async_trait;
44
use serde::{Deserialize, Serialize};
5+
#[cfg(feature = "os_input")]
6+
use starknet_api::block::BlockNumber;
57
use starknet_api::core::ContractAddress;
8+
#[cfg(feature = "os_input")]
9+
use starknet_api::hash::HashOutput;
610
use starknet_api::hash::StateRoots;
711
use starknet_patricia::patricia_merkle_tree::filled_tree::tree::FilledTree;
812
use starknet_patricia::patricia_merkle_tree::node_data::leaf::LeafModifications;
13+
#[cfg(feature = "os_input")]
14+
use starknet_patricia::patricia_merkle_tree::traversal::TraversalResult;
915
use starknet_patricia::patricia_merkle_tree::types::NodeIndex;
1016
use starknet_patricia_storage::db_object::EmptyKeyContext;
1117
use starknet_patricia_storage::errors::SerializationResult;
@@ -28,13 +34,30 @@ use crate::forest::filled_forest::FilledForest;
2834
use crate::forest::forest_errors::{ForestError, ForestResult};
2935
use crate::forest::original_skeleton_forest::{ForestSortedIndices, OriginalSkeletonForest};
3036
use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState;
37+
#[cfg(feature = "os_input")]
38+
use crate::patricia_merkle_tree::tree::SortedLeafIndices;
3139
use crate::patricia_merkle_tree::types::CompiledClassHash;
40+
#[cfg(feature = "os_input")]
41+
use crate::patricia_merkle_tree::types::StarknetForestProofs;
42+
43+
/// How Patricia proofs and read-keys digest metadata are updated in the same batch as a forest
44+
/// write.
45+
#[cfg(feature = "os_input")]
46+
pub enum PatriciaProofsUpdates {
47+
/// Remove read-keys digest + Patricia proofs on revert.
48+
Delete(BlockNumber),
49+
/// Persist read-keys digest + Patricia proofs for this block.
50+
Set { height: BlockNumber, keys_digest: [u8; 32], witnesses: StarknetForestProofs },
51+
}
3252

3353
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Hash, Serialize)]
3454
pub enum ForestMetadataType {
3555
CommitmentOffset,
3656
StateDiffHash(DbBlockNumber),
3757
StateRoot(DbBlockNumber),
58+
/// BLAKE2s digest of the canonical accessed-keys set for the block.
59+
#[cfg(feature = "os_input")]
60+
AccessedKeysDigest(DbBlockNumber),
3861
}
3962

4063
#[async_trait]
@@ -87,6 +110,31 @@ pub trait ForestReader {
87110
) -> PatriciaStorageResult<StateRoots>;
88111
}
89112

113+
/// Reads committed OS-input witness payload (structured [`StarknetForestProofs`]) for a block
114+
/// height.
115+
#[cfg(feature = "os_input")]
116+
#[async_trait]
117+
pub trait ForestReaderWithWitnesses:
118+
ForestReader<InitialReadContext: EmptyInitialReadContext> + Send
119+
{
120+
async fn read_witnesses(
121+
&mut self,
122+
height: BlockNumber,
123+
) -> ForestResult<Option<StarknetForestProofs>>;
124+
125+
/// Fetches Patricia witness paths for OS input, optionally staging serialized trie node KVs on
126+
/// an in-memory overlay so reads match post-commit state before the forest is persisted.
127+
async fn fetch_patricia_witnesses(
128+
&mut self,
129+
classes_trie_root_hash: HashOutput,
130+
contracts_trie_root_hash: HashOutput,
131+
class_sorted_leaf_indices: SortedLeafIndices<'_>,
132+
contract_sorted_leaf_indices: SortedLeafIndices<'_>,
133+
contract_storage_sorted_leaf_indices: &HashMap<NodeIndex, SortedLeafIndices<'_>>,
134+
staged_serialized_forest: Option<DbHashMap>,
135+
) -> TraversalResult<StarknetForestProofs>;
136+
}
137+
90138
/// Helper function containing layout-common read logic.
91139
pub(crate) async fn read_forest<'a, S, Layout>(
92140
storage: &mut S,
@@ -219,6 +267,20 @@ pub trait ForestWriterWithMetadata: ForestWriter + ForestMetadata {
219267
}
220268
}
221269

270+
/// Writes forest + metadata + deleted nodes, and optionally applies [`PatriciaProofsUpdates`] in
271+
/// the same batch.
272+
#[cfg(feature = "os_input")]
273+
#[async_trait]
274+
pub trait ForestWriterWithMetadataAndWitnesses: ForestWriterWithMetadata + Send {
275+
async fn write_with_metadata_and_witnesses(
276+
&mut self,
277+
filled_forest: &FilledForest,
278+
metadata: HashMap<ForestMetadataType, DbValue>,
279+
deleted_nodes: DeletedNodes,
280+
patricia_proofs_updates: PatriciaProofsUpdates,
281+
) -> SerializationResult<usize>;
282+
}
283+
222284
pub trait StorageInitializer {
223285
type Storage: Storage;
224286
fn new(storage: Self::Storage) -> Self;
@@ -257,3 +319,16 @@ impl<T> ForestStorageWithEmptyReadContext for T where
257319
T: ForestReaderWithEmptyContext + ForestWriterWithMetadata + StorageInitializer
258320
{
259321
}
322+
323+
/// Forest storage with empty [`ForestReader::InitialReadContext`] plus OS-input witness read/write.
324+
#[cfg(feature = "os_input")]
325+
pub trait ForestStorageWithWitnesses:
326+
ForestReaderWithWitnesses + ForestWriterWithMetadataAndWitnesses + StorageInitializer
327+
{
328+
}
329+
330+
#[cfg(feature = "os_input")]
331+
impl<T> ForestStorageWithWitnesses for T where
332+
T: ForestReaderWithWitnesses + ForestWriterWithMetadataAndWitnesses + StorageInitializer
333+
{
334+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ static STATE_ROOT_METADATA_PREFIX: LazyLock<[u8; 32]> = LazyLock::new(|| {
8484
(Felt::from_bytes_be(&STATE_DIFF_HASH_METADATA_PREFIX) + Felt::ONE).to_bytes_be()
8585
});
8686

87+
/// Prefix for accessed-keys digest metadata (committed per block).
88+
#[cfg(feature = "os_input")]
89+
pub(crate) static ACCESSED_KEYS_DIGEST_METADATA_PREFIX: LazyLock<[u8; 32]> =
90+
LazyLock::new(|| (Felt::from_bytes_be(&STATE_ROOT_METADATA_PREFIX) + Felt::ONE).to_bytes_be());
91+
8792
pub struct IndexDb<S: Storage, H = TreeHashFunctionImpl> {
8893
storage: S,
8994
phantom: PhantomData<H>,
@@ -287,6 +292,13 @@ impl<S: Storage> ForestMetadata for IndexDb<S> {
287292
key.extend_from_slice(&block_number_bytes);
288293
key.extend_from_slice(&[0u8; 24]);
289294
}
295+
#[cfg(feature = "os_input")]
296+
ForestMetadataType::AccessedKeysDigest(block_number) => {
297+
key.extend_from_slice(&*ACCESSED_KEYS_DIGEST_METADATA_PREFIX);
298+
let block_number_bytes: [u8; 8] = block_number.serialize();
299+
key.extend_from_slice(&block_number_bytes);
300+
key.extend_from_slice(&[0u8; 24]);
301+
}
290302
}
291303
DbKey(key)
292304
}

0 commit comments

Comments
 (0)