@@ -274,8 +274,54 @@ impl DeferredTrieData {
274274 /// In normal operation, the parent always has a cached overlay and this
275275 /// function is never called.
276276 ///
277- /// Iterates ancestors oldest -> newest, then extends with current block's data,
278- /// so later state takes precedence.
277+ /// When the `rayon` feature is enabled:
278+ /// 1. Collects ancestor data (states and updates)
279+ /// 2. Merges states and trie updates in parallel using k-way merge
280+ #[ cfg( feature = "rayon" ) ]
281+ fn merge_ancestors_into_overlay (
282+ ancestors : & [ Self ] ,
283+ sorted_hashed_state : & HashedPostStateSorted ,
284+ sorted_trie_updates : & TrieUpdatesSorted ,
285+ ) -> TrieInputSorted {
286+ // Early exit: no ancestors means just wrap current block's data
287+ if ancestors. is_empty ( ) {
288+ return TrieInputSorted :: new (
289+ Arc :: new ( sorted_trie_updates. clone ( ) ) ,
290+ Arc :: new ( sorted_hashed_state. clone ( ) ) ,
291+ Default :: default ( ) ,
292+ ) ;
293+ }
294+
295+ // Collect ancestor data in reverse (newest to oldest) for merge_slice
296+ let ( states, updates) : ( Vec < _ > , Vec < _ > ) = ancestors
297+ . iter ( )
298+ . rev ( )
299+ . map ( |a| {
300+ // Note: we can assume that this trie data has already been computed
301+ let data = a. wait_cloned ( ) ;
302+ ( data. hashed_state , data. trie_updates )
303+ } )
304+ . unzip ( ) ;
305+
306+ // Merge state and nodes in parallel using k-way merge
307+ let ( state, nodes) = rayon:: join (
308+ || {
309+ let mut merged = HashedPostStateSorted :: merge_slice ( & states) ;
310+ merged. extend_ref_and_sort ( sorted_hashed_state) ;
311+ merged
312+ } ,
313+ || {
314+ let mut merged = TrieUpdatesSorted :: merge_slice ( & updates) ;
315+ merged. extend_ref_and_sort ( sorted_trie_updates) ;
316+ merged
317+ } ,
318+ ) ;
319+
320+ TrieInputSorted :: new ( Arc :: new ( nodes) , Arc :: new ( state) , Default :: default ( ) )
321+ }
322+
323+ /// Sequential fallback when rayon is not available.
324+ #[ cfg( not( feature = "rayon" ) ) ]
279325 fn merge_ancestors_into_overlay (
280326 ancestors : & [ Self ] ,
281327 sorted_hashed_state : & HashedPostStateSorted ,
@@ -293,18 +339,8 @@ impl DeferredTrieData {
293339 nodes_mut. extend_ref_and_sort ( ancestor_data. trie_updates . as_ref ( ) ) ;
294340 }
295341
296- // Extend with current block's sorted data last (takes precedence)
297- #[ cfg( feature = "rayon" ) ]
298- rayon:: join (
299- || state_mut. extend_ref_and_sort ( sorted_hashed_state) ,
300- || nodes_mut. extend_ref_and_sort ( sorted_trie_updates) ,
301- ) ;
302-
303- #[ cfg( not( feature = "rayon" ) ) ]
304- {
305- state_mut. extend_ref_and_sort ( sorted_hashed_state) ;
306- nodes_mut. extend_ref_and_sort ( sorted_trie_updates) ;
307- }
342+ state_mut. extend_ref_and_sort ( sorted_hashed_state) ;
343+ nodes_mut. extend_ref_and_sort ( sorted_trie_updates) ;
308344
309345 overlay
310346 }
0 commit comments