@@ -23,7 +23,7 @@ use starknet_patricia::patricia_merkle_tree::traversal::{
2323 UnmodifiedChildTraversal ,
2424} ;
2525use starknet_patricia:: patricia_merkle_tree:: types:: { NodeIndex , SortedLeafIndices } ;
26- use starknet_patricia_storage:: db_object:: { DBObject , EmptyKeyContext , HasStaticPrefix } ;
26+ use starknet_patricia_storage:: db_object:: { DBObject , HasStaticPrefix } ;
2727use starknet_patricia_storage:: errors:: StorageError ;
2828use starknet_patricia_storage:: storage_trait:: { create_db_key, DbKey , Storage } ;
2929use tracing:: warn;
@@ -34,9 +34,7 @@ use crate::block_committer::input::{
3434 StarknetStorageValue ,
3535} ;
3636use crate :: db:: db_layout:: NodeLayout ;
37- use crate :: db:: facts_db:: create_facts_tree:: create_original_skeleton_tree_and_get_previous_leaves;
38- use crate :: db:: facts_db:: db:: FactsNodeLayout ;
39- use crate :: db:: facts_db:: types:: FactsSubTree ;
37+ use crate :: db:: index_db:: leaves:: TrieType ;
4038use crate :: forest:: forest_errors:: { ForestError , ForestResult } ;
4139use crate :: patricia_merkle_tree:: leaf:: leaf_impl:: ContractState ;
4240use crate :: patricia_merkle_tree:: tree:: OriginalSkeletonTrieConfig ;
@@ -57,7 +55,7 @@ macro_rules! log_trivial_modification {
5755///
5856/// The function is generic over the DB layout (`Layout`), which controls the concrete node data
5957/// (`Layout::NodeData`) and traversal strategy (via `Layout::SubTree`).
60- pub async fn fetch_nodes < ' a , L , Layout > (
58+ pub ( crate ) async fn fetch_nodes < ' a , L , Layout > (
6159 skeleton_tree : & mut OriginalSkeletonTreeImpl < ' a > ,
6260 subtrees : Vec < Layout :: SubTree > ,
6361 storage : & mut impl Storage ,
@@ -69,7 +67,6 @@ pub async fn fetch_nodes<'a, L, Layout>(
6967where
7068 L : Leaf ,
7169 Layout : NodeLayout < ' a , L > ,
72- FilledNode < L , Layout :: NodeData > : DBObject < DeserializeContext = Layout :: DeserializationContext > ,
7370{
7471 let mut current_subtrees = subtrees;
7572 let mut next_subtrees = Vec :: new ( ) ;
@@ -247,10 +244,7 @@ pub async fn get_roots_from_storage<'a, L: Leaf, Layout: NodeLayout<'a, L>>(
247244 subtrees : & [ Layout :: SubTree ] ,
248245 storage : & mut impl Storage ,
249246 key_context : & <L as HasStaticPrefix >:: KeyContext ,
250- ) -> TraversalResult < Vec < FilledNode < L , Layout :: NodeData > > >
251- where
252- FilledNode < L , Layout :: NodeData > : DBObject < DeserializeContext = Layout :: DeserializationContext > ,
253- {
247+ ) -> TraversalResult < Vec < FilledNode < L , Layout :: NodeData > > > {
254248 let mut subtrees_roots = vec ! [ ] ;
255249 let db_keys: Vec < DbKey > = subtrees
256250 . iter ( )
@@ -262,7 +256,10 @@ where
262256 let db_vals = storage. mget ( & db_keys. iter ( ) . collect :: < Vec < & DbKey > > ( ) ) . await ?;
263257 for ( ( subtree, optional_val) , db_key) in subtrees. iter ( ) . zip ( db_vals. iter ( ) ) . zip ( db_keys) {
264258 let Some ( val) = optional_val else { Err ( StorageError :: MissingKey ( db_key) ) ? } ;
265- let filled_node = FilledNode :: deserialize ( val, & subtree. get_root_context ( ) ) ?;
259+ let filled_node = Layout :: get_filled_node ( Layout :: NodeDbObject :: deserialize (
260+ val,
261+ & subtree. get_root_context ( ) ,
262+ ) ?) ;
266263 subtrees_roots. push ( filled_node) ;
267264 }
268265 Ok ( subtrees_roots)
@@ -288,10 +285,7 @@ pub(crate) fn log_warning_for_empty_leaves<L: Leaf, T: Borrow<NodeIndex> + Debug
288285 Ok ( ( ) )
289286}
290287
291- pub async fn create_original_skeleton_tree <
292- ' a ,
293- L : Leaf + HasStaticPrefix < KeyContext = EmptyKeyContext > ,
294- > (
288+ pub async fn create_original_skeleton_tree < ' a , L : Leaf , Layout : NodeLayout < ' a , L > > (
295289 storage : & mut impl Storage ,
296290 root_hash : HashOutput ,
297291 sorted_leaf_indices : SortedLeafIndices < ' a > ,
@@ -308,11 +302,12 @@ pub async fn create_original_skeleton_tree<
308302 leaf_modifications,
309303 config,
310304 ) ?;
311- return Ok ( OriginalSkeletonTreeImpl :: create_empty ( sorted_leaf_indices) ) ;
305+ return Ok ( handle_empty_subtree :: < L > ( sorted_leaf_indices) . 0 ) ;
312306 }
313- let main_subtree = FactsSubTree :: create ( sorted_leaf_indices, NodeIndex :: ROOT , root_hash) ;
307+ let main_subtree =
308+ Layout :: SubTree :: create ( sorted_leaf_indices, NodeIndex :: ROOT , root_hash. into ( ) ) ;
314309 let mut skeleton_tree = OriginalSkeletonTreeImpl { nodes : HashMap :: new ( ) , sorted_leaf_indices } ;
315- fetch_nodes :: < L , FactsNodeLayout > (
310+ fetch_nodes :: < L , Layout > (
316311 & mut skeleton_tree,
317312 vec ! [ main_subtree] ,
318313 storage,
@@ -325,7 +320,11 @@ pub async fn create_original_skeleton_tree<
325320 Ok ( skeleton_tree)
326321}
327322
328- pub async fn create_storage_tries < ' a > (
323+ pub async fn create_storage_tries <
324+ ' a ,
325+ L : Leaf + From < StarknetStorageValue > ,
326+ Layout : NodeLayout < ' a , L > ,
327+ > (
329328 storage : & mut impl Storage ,
330329 actual_storage_updates : & HashMap < ContractAddress , LeafModifications < StarknetStorageValue > > ,
331330 original_contracts_trie_leaves : & HashMap < NodeIndex , ContractState > ,
@@ -344,13 +343,13 @@ pub async fn create_storage_tries<'a>(
344343 config. warn_on_trivial_modifications ( ) ,
345344 ) ;
346345
347- let original_skeleton = create_original_skeleton_tree (
346+ let original_skeleton = create_original_skeleton_tree :: < L , Layout > (
348347 storage,
349348 contract_state. storage_root_hash ,
350349 * sorted_leaf_indices,
351350 & config,
352- updates,
353- & EmptyKeyContext ,
351+ & updates. iter ( ) . map ( | ( idx , value ) | ( * idx , L :: from ( * value ) ) ) . collect ( ) ,
352+ & Layout :: generate_key_context ( TrieType :: StorageTrie ( * address ) ) ,
354353 )
355354 . await ?;
356355 storage_tries. insert ( * address, original_skeleton) ;
@@ -360,22 +359,50 @@ pub async fn create_storage_tries<'a>(
360359
361360/// Creates the contracts trie original skeleton.
362361/// Also returns the previous contracts state of the modified contracts.
363- pub async fn create_contracts_trie < ' a > (
362+ pub async fn create_contracts_trie < ' a , L : Leaf + Into < ContractState > , Layout : NodeLayout < ' a , L > > (
364363 storage : & mut impl Storage ,
365364 contracts_trie_root_hash : HashOutput ,
366365 contracts_trie_sorted_indices : SortedLeafIndices < ' a > ,
367366) -> ForestResult < ( OriginalSkeletonTreeImpl < ' a > , HashMap < NodeIndex , ContractState > ) > {
368- Ok ( create_original_skeleton_tree_and_get_previous_leaves (
369- storage,
370- contracts_trie_root_hash,
367+ if contracts_trie_sorted_indices. is_empty ( ) {
368+ let unmodified = OriginalSkeletonTreeImpl :: create_unmodified ( contracts_trie_root_hash) ;
369+ return Ok ( ( unmodified, HashMap :: new ( ) ) ) ;
370+ }
371+ if contracts_trie_root_hash == HashOutput :: ROOT_OF_EMPTY_TREE {
372+ return Ok ( handle_empty_subtree ( contracts_trie_sorted_indices) ) ;
373+ }
374+ let main_subtree = Layout :: SubTree :: create (
371375 contracts_trie_sorted_indices,
376+ NodeIndex :: ROOT ,
377+ contracts_trie_root_hash. into ( ) ,
378+ ) ;
379+ let mut skeleton_tree = OriginalSkeletonTreeImpl {
380+ nodes : HashMap :: new ( ) ,
381+ sorted_leaf_indices : contracts_trie_sorted_indices,
382+ } ;
383+ let mut leaves = HashMap :: new ( ) ;
384+ fetch_nodes :: < L , Layout > (
385+ & mut skeleton_tree,
386+ vec ! [ main_subtree] ,
387+ storage,
372388 & HashMap :: new ( ) ,
373389 & OriginalSkeletonTrieConfig :: new_for_contracts_trie ( ) ,
390+ Some ( & mut leaves) ,
391+ & Layout :: generate_key_context ( TrieType :: ContractsTrie ) ,
374392 )
375- . await ?)
393+ . await ?;
394+
395+ let leaves: HashMap < NodeIndex , ContractState > =
396+ leaves. into_iter ( ) . map ( |( idx, leaf) | ( idx, leaf. into ( ) ) ) . collect ( ) ;
397+
398+ Ok ( ( skeleton_tree, leaves) )
376399}
377400
378- pub async fn create_classes_trie < ' a > (
401+ pub async fn create_classes_trie <
402+ ' a ,
403+ L : Leaf + From < CompiledClassHash > ,
404+ Layout : NodeLayout < ' a , L > ,
405+ > (
379406 storage : & mut impl Storage ,
380407 actual_classes_updates : & LeafModifications < CompiledClassHash > ,
381408 classes_trie_root_hash : HashOutput ,
@@ -386,13 +413,22 @@ pub async fn create_classes_trie<'a>(
386413 config. warn_on_trivial_modifications ( ) ,
387414 ) ;
388415
389- Ok ( create_original_skeleton_tree (
416+ Ok ( create_original_skeleton_tree :: < L , Layout > (
390417 storage,
391418 classes_trie_root_hash,
392419 contracts_trie_sorted_indices,
393420 & config,
394- actual_classes_updates,
395- & EmptyKeyContext ,
421+ & actual_classes_updates. iter ( ) . map ( | ( idx , value ) | ( * idx , L :: from ( * value ) ) ) . collect ( ) ,
422+ & Layout :: generate_key_context ( TrieType :: ClassesTrie ) ,
396423 )
397424 . await ?)
398425}
426+
427+ pub ( crate ) fn handle_empty_subtree < ' a , L : Leaf > (
428+ sorted_leaf_indices : SortedLeafIndices < ' a > ,
429+ ) -> ( OriginalSkeletonTreeImpl < ' a > , HashMap < NodeIndex , L > ) {
430+ (
431+ OriginalSkeletonTreeImpl :: create_empty ( sorted_leaf_indices) ,
432+ sorted_leaf_indices. get_indices ( ) . iter ( ) . map ( |idx| ( * idx, L :: default ( ) ) ) . collect ( ) ,
433+ )
434+ }
0 commit comments