@@ -2,6 +2,7 @@ use std::borrow::Borrow;
22use std:: collections:: HashMap ;
33use std:: fmt:: Debug ;
44
5+ use futures:: stream:: { FuturesUnordered , StreamExt } ;
56use starknet_api:: core:: ContractAddress ;
67use starknet_api:: hash:: HashOutput ;
78use starknet_patricia:: db_layout:: { NodeLayout , NodeLayoutFor } ;
@@ -459,3 +460,65 @@ where
459460 }
460461 Ok ( storage_tries)
461462}
463+
464+ // TODO(Nimrod): Remove the `allow(dead_code)` once we use this function.
465+ #[ allow( dead_code) ]
466+ async fn create_storage_tries_concurrently < ' a , Layout : NodeLayoutFor < StarknetStorageValue > > (
467+ storage : & impl Storage ,
468+ actual_storage_updates : & HashMap < ContractAddress , LeafModifications < StarknetStorageValue > > ,
469+ original_contracts_trie_leaves : & HashMap < NodeIndex , ContractState > ,
470+ config : & ReaderConfig ,
471+ storage_tries_sorted_indices : & HashMap < ContractAddress , SortedLeafIndices < ' a > > ,
472+ ) -> ForestResult < HashMap < ContractAddress , OriginalSkeletonTreeImpl < ' a > > >
473+ where
474+ <Layout as NodeLayoutFor < StarknetStorageValue > >:: DbLeaf :
475+ HasStaticPrefix < KeyContext = ContractAddress > ,
476+ {
477+ let mut futures = FuturesUnordered :: new ( ) ;
478+ let mut storage_tries = HashMap :: new ( ) ;
479+
480+ let trie_config = OriginalSkeletonTrieConfig :: new_for_classes_or_storage_trie (
481+ config. warn_on_trivial_modifications ( ) ,
482+ ) ;
483+ for ( address, updates) in actual_storage_updates {
484+ // Extract data needed for this contract.
485+ let sorted_leaf_indices = * storage_tries_sorted_indices
486+ . get ( address)
487+ . ok_or ( ForestError :: MissingSortedLeafIndices ( * address) ) ?;
488+ let contract_state = original_contracts_trie_leaves
489+ . get ( & contract_address_into_node_index ( address) )
490+ . ok_or ( ForestError :: MissingContractCurrentState ( * address) ) ?;
491+ let cloned_trie_config = trie_config. clone ( ) ;
492+
493+ // TODO(Ariel): Change `LeafModifications` in `actual_storage_updates` to be an
494+ // iterator over borrowed data so that the conversion below is costless.
495+ let leaf_modifications: HashMap <
496+ NodeIndex ,
497+ <Layout as NodeLayoutFor < StarknetStorageValue > >:: DbLeaf ,
498+ > = updates. iter ( ) . map ( |( idx, value) | ( * idx, Layout :: DbLeaf :: from ( * value) ) ) . collect ( ) ;
499+
500+ // Create the future - tokio will poll all futures concurrently.
501+ futures. push ( async move {
502+ let prevoius_leaves = None ;
503+ let original_skeleton = create_original_skeleton_tree :: < Layout :: DbLeaf , Layout > (
504+ storage,
505+ contract_state. storage_root_hash ,
506+ sorted_leaf_indices,
507+ & cloned_trie_config,
508+ & leaf_modifications,
509+ prevoius_leaves,
510+ address,
511+ )
512+ . await ?;
513+ Ok :: < _ , ForestError > ( ( address, original_skeleton) )
514+ } ) ;
515+ }
516+
517+ // Collect all results as they complete.
518+ while let Some ( result) = futures. next ( ) . await {
519+ let ( address, original_skeleton) = result?;
520+ storage_tries. insert ( * address, original_skeleton) ;
521+ }
522+
523+ Ok ( storage_tries)
524+ }
0 commit comments