|
| 1 | +use std::collections::HashMap; |
| 2 | + |
| 3 | +use starknet_api::core::ContractAddress; |
| 4 | +use starknet_api::hash::HashOutput; |
| 5 | +use starknet_patricia::patricia_merkle_tree::filled_tree::node::FilledNode; |
| 6 | +use starknet_patricia::patricia_merkle_tree::node_data::leaf::{Leaf, LeafModifications}; |
| 7 | +use starknet_patricia::patricia_merkle_tree::types::{NodeIndex, SortedLeafIndices}; |
| 8 | +use starknet_patricia::patricia_merkle_tree::updated_skeleton_tree::hash_function::TreeHashFunction; |
| 9 | +use starknet_patricia_storage::db_object::{DBObject, HasStaticPrefix}; |
| 10 | +use starknet_patricia_storage::errors::DeserializationError; |
| 11 | +use starknet_patricia_storage::storage_trait::{DbValue, Storage}; |
| 12 | + |
| 13 | +use crate::block_committer::input::{ConfigImpl, StarknetStorageValue}; |
| 14 | +use crate::db::db_layout::NodeLayout; |
| 15 | +use crate::db::forest_trait::{ForestReader, ForestWriter}; |
| 16 | +use crate::db::index_db::leaves::{ |
| 17 | + IndexLayoutCompiledClassHash, |
| 18 | + IndexLayoutContractState, |
| 19 | + IndexLayoutStarknetStorageValue, |
| 20 | + TrieType, |
| 21 | +}; |
| 22 | +use crate::db::index_db::types::{IndexFilledNode, IndexLayoutSubTree, IndexNodeContext}; |
| 23 | +use crate::db::trie_traversal::{create_classes_trie, create_contracts_trie, create_storage_tries}; |
| 24 | +use crate::forest::filled_forest::FilledForest; |
| 25 | +use crate::forest::forest_errors::ForestResult; |
| 26 | +use crate::forest::original_skeleton_forest::{ForestSortedIndices, OriginalSkeletonForest}; |
| 27 | +use crate::hash_function::hash::TreeHashFunctionImpl; |
| 28 | +use crate::patricia_merkle_tree::leaf::leaf_impl::ContractState; |
| 29 | +use crate::patricia_merkle_tree::types::CompiledClassHash; |
| 30 | +pub struct IndexDb<S: Storage> { |
| 31 | + pub storage: S, |
| 32 | +} |
| 33 | + |
| 34 | +impl<S: Storage> IndexDb<S> { |
| 35 | + pub fn new(storage: S) -> Self { |
| 36 | + Self { storage } |
| 37 | + } |
| 38 | +} |
| 39 | + |
| 40 | +pub struct IndexNodeLayout {} |
| 41 | + |
| 42 | +impl<'a, L: Leaf> NodeLayout<'a, L> for IndexNodeLayout |
| 43 | +where |
| 44 | + L: HasStaticPrefix<KeyContext = TrieType>, |
| 45 | + TreeHashFunctionImpl: TreeHashFunction<L>, |
| 46 | +{ |
| 47 | + type ChildData = (); |
| 48 | + type DeserializationContext = IndexNodeContext; |
| 49 | + type SubTree = IndexLayoutSubTree<'a>; |
| 50 | + fn deserialize_node( |
| 51 | + value: &DbValue, |
| 52 | + deserialize_context: &Self::DeserializationContext, |
| 53 | + ) -> Result<FilledNode<L, ()>, DeserializationError> { |
| 54 | + let filled_node: IndexFilledNode<L> = DBObject::deserialize(value, deserialize_context)?; |
| 55 | + Ok(filled_node.0) |
| 56 | + } |
| 57 | + fn create_subtree( |
| 58 | + sorted_leaf_indices: SortedLeafIndices<'a>, |
| 59 | + root_index: NodeIndex, |
| 60 | + _root_hash: HashOutput, |
| 61 | + ) -> Self::SubTree { |
| 62 | + IndexLayoutSubTree { sorted_leaf_indices, root_index } |
| 63 | + } |
| 64 | + fn generate_key_context(trie_type: TrieType) -> <L as HasStaticPrefix>::KeyContext { |
| 65 | + trie_type |
| 66 | + } |
| 67 | +} |
| 68 | + |
| 69 | +impl<'a, S: Storage> ForestReader<'a> for IndexDb<S> { |
| 70 | + /// Creates an original skeleton forest that includes the storage tries of the modified |
| 71 | + /// contracts, the classes trie and the contracts trie. Additionally, returns the original |
| 72 | + /// contract states that are needed to compute the contract state tree. |
| 73 | + async fn read( |
| 74 | + &mut self, |
| 75 | + contracts_trie_root_hash: HashOutput, |
| 76 | + classes_trie_root_hash: HashOutput, |
| 77 | + storage_updates: &'a HashMap<ContractAddress, LeafModifications<StarknetStorageValue>>, |
| 78 | + classes_updates: &'a LeafModifications<CompiledClassHash>, |
| 79 | + forest_sorted_indices: &'a ForestSortedIndices<'a>, |
| 80 | + config: ConfigImpl, |
| 81 | + ) -> ForestResult<(OriginalSkeletonForest<'a>, HashMap<NodeIndex, ContractState>)> { |
| 82 | + let (contracts_trie, original_contracts_trie_leaves) = |
| 83 | + create_contracts_trie::<IndexLayoutContractState, IndexNodeLayout>( |
| 84 | + &mut self.storage, |
| 85 | + contracts_trie_root_hash, |
| 86 | + forest_sorted_indices.contracts_trie_sorted_indices, |
| 87 | + ) |
| 88 | + .await?; |
| 89 | + let storage_tries = |
| 90 | + create_storage_tries::<IndexLayoutStarknetStorageValue, IndexNodeLayout>( |
| 91 | + &mut self.storage, |
| 92 | + storage_updates, |
| 93 | + &original_contracts_trie_leaves, |
| 94 | + &config, |
| 95 | + &forest_sorted_indices.storage_tries_sorted_indices, |
| 96 | + ) |
| 97 | + .await?; |
| 98 | + let classes_trie = create_classes_trie::<IndexLayoutCompiledClassHash, IndexNodeLayout>( |
| 99 | + &mut self.storage, |
| 100 | + classes_updates, |
| 101 | + classes_trie_root_hash, |
| 102 | + &config, |
| 103 | + forest_sorted_indices.classes_trie_sorted_indices, |
| 104 | + ) |
| 105 | + .await?; |
| 106 | + |
| 107 | + Ok(( |
| 108 | + OriginalSkeletonForest { classes_trie, contracts_trie, storage_tries }, |
| 109 | + original_contracts_trie_leaves, |
| 110 | + )) |
| 111 | + } |
| 112 | +} |
| 113 | + |
| 114 | +impl<S: Storage> ForestWriter for IndexDb<S> { |
| 115 | + async fn write(&mut self, filled_forest: &FilledForest) -> usize { |
| 116 | + filled_forest.write_to_storage(&mut self.storage).await |
| 117 | + } |
| 118 | +} |
0 commit comments