@@ -12,9 +12,11 @@ use reth_stages_api::{
1212 BlockErrorKind , ExecInput , ExecOutput , Stage , StageCheckpoint , StageError , StageId ,
1313 UnwindInput , UnwindOutput ,
1414} ;
15- use reth_trie:: { updates:: TrieUpdates , HashedPostState , KeccakKeyHasher , StateRoot , TrieInput } ;
15+ use reth_trie:: {
16+ updates:: TrieUpdates , HashedPostStateSorted , KeccakKeyHasher , StateRoot , TrieInputSorted ,
17+ } ;
1618use reth_trie_db:: { DatabaseHashedPostState , DatabaseStateRoot } ;
17- use std:: ops:: Range ;
19+ use std:: { ops:: Range , sync :: Arc } ;
1820use tracing:: { debug, error} ;
1921
2022/// The `MerkleChangeSets` stage.
@@ -105,12 +107,12 @@ impl MerkleChangeSets {
105107 Ok ( target_start..target_end)
106108 }
107109
108- /// Calculates the trie updates given a [`TrieInput `], asserting that the resulting state root
109- /// matches the expected one for the block.
110+ /// Calculates the trie updates given a [`TrieInputSorted `], asserting that the resulting state
111+ /// root matches the expected one for the block.
110112 fn calculate_block_trie_updates < Provider : DBProvider + HeaderProvider > (
111113 provider : & Provider ,
112114 block_number : BlockNumber ,
113- input : TrieInput ,
115+ input : TrieInputSorted ,
114116 ) -> Result < TrieUpdates , StageError > {
115117 let ( root, trie_updates) =
116118 StateRoot :: overlay_root_from_nodes_with_updates ( provider. tx_ref ( ) , input) . map_err (
@@ -192,21 +194,21 @@ impl MerkleChangeSets {
192194 ) ;
193195 let mut per_block_state_reverts = Vec :: new ( ) ;
194196 for block_number in target_range. clone ( ) {
195- per_block_state_reverts. push ( HashedPostState :: from_reverts :: < KeccakKeyHasher > (
197+ per_block_state_reverts. push ( HashedPostStateSorted :: from_reverts :: < KeccakKeyHasher > (
196198 provider. tx_ref ( ) ,
197199 block_number..=block_number,
198200 ) ?) ;
199201 }
200202
201203 // Helper to retrieve state revert data for a specific block from the pre-computed array
202- let get_block_state_revert = |block_number : BlockNumber | -> & HashedPostState {
204+ let get_block_state_revert = |block_number : BlockNumber | -> & HashedPostStateSorted {
203205 let index = ( block_number - target_start) as usize ;
204206 & per_block_state_reverts[ index]
205207 } ;
206208
207209 // Helper to accumulate state reverts from a given block to the target end
208- let compute_cumulative_state_revert = |block_number : BlockNumber | -> HashedPostState {
209- let mut cumulative_revert = HashedPostState :: default ( ) ;
210+ let compute_cumulative_state_revert = |block_number : BlockNumber | -> HashedPostStateSorted {
211+ let mut cumulative_revert = HashedPostStateSorted :: default ( ) ;
210212 for n in ( block_number..target_end) . rev ( ) {
211213 cumulative_revert. extend_ref ( get_block_state_revert ( n) )
212214 }
@@ -216,7 +218,7 @@ impl MerkleChangeSets {
216218 // To calculate the changeset for a block, we first need the TrieUpdates which are
217219 // generated as a result of processing the block. To get these we need:
218220 // 1) The TrieUpdates which revert the db's trie to _prior_ to the block
219- // 2) The HashedPostState to revert the db's state to _after_ the block
221+ // 2) The HashedPostStateSorted to revert the db's state to _after_ the block
220222 //
221223 // To get (1) for `target_start` we need to do a big state root calculation which takes
222224 // into account all changes between that block and db tip. For each block after the
@@ -227,12 +229,15 @@ impl MerkleChangeSets {
227229 ?target_start,
228230 "Computing trie state at starting block" ,
229231 ) ;
230- let mut input = TrieInput :: default ( ) ;
231- input. state = compute_cumulative_state_revert ( target_start) ;
232- input. prefix_sets = input. state . construct_prefix_sets ( ) ;
232+ let initial_state = compute_cumulative_state_revert ( target_start) ;
233+ let initial_prefix_sets = initial_state. construct_prefix_sets ( ) ;
234+ let initial_input =
235+ TrieInputSorted :: new ( Arc :: default ( ) , Arc :: new ( initial_state) , initial_prefix_sets) ;
233236 // target_start will be >= 1, see `determine_target_range`.
234- input. nodes =
235- Self :: calculate_block_trie_updates ( provider, target_start - 1 , input. clone ( ) ) ?;
237+ let mut nodes = Arc :: new (
238+ Self :: calculate_block_trie_updates ( provider, target_start - 1 , initial_input) ?
239+ . into_sorted ( ) ,
240+ ) ;
236241
237242 for block_number in target_range {
238243 debug ! (
@@ -242,21 +247,24 @@ impl MerkleChangeSets {
242247 ) ;
243248 // Revert the state so that this block has been just processed, meaning we take the
244249 // cumulative revert of the subsequent block.
245- input. state = compute_cumulative_state_revert ( block_number + 1 ) ;
250+ let state = Arc :: new ( compute_cumulative_state_revert ( block_number + 1 ) ) ;
251+
252+ // Construct prefix sets from only this block's `HashedPostStateSorted`, because we only
253+ // care about trie updates which occurred as a result of this block being processed.
254+ let prefix_sets = get_block_state_revert ( block_number) . construct_prefix_sets ( ) ;
246255
247- // Construct prefix sets from only this block's `HashedPostState`, because we only care
248- // about trie updates which occurred as a result of this block being processed.
249- input. prefix_sets = get_block_state_revert ( block_number) . construct_prefix_sets ( ) ;
256+ let input = TrieInputSorted :: new ( Arc :: clone ( & nodes) , state, prefix_sets) ;
250257
251258 // Calculate the trie updates for this block, then apply those updates to the reverts.
252259 // We calculate the overlay which will be passed into the next step using the trie
253260 // reverts prior to them being updated.
254261 let this_trie_updates =
255- Self :: calculate_block_trie_updates ( provider, block_number, input. clone ( ) ) ? ;
262+ Self :: calculate_block_trie_updates ( provider, block_number, input) ? . into_sorted ( ) ;
256263
257- let trie_overlay = input. nodes . clone ( ) . into_sorted ( ) ;
258- input. nodes . extend_ref ( & this_trie_updates) ;
259- let this_trie_updates = this_trie_updates. into_sorted ( ) ;
264+ let trie_overlay = Arc :: clone ( & nodes) ;
265+ let mut nodes_mut = Arc :: unwrap_or_clone ( nodes) ;
266+ nodes_mut. extend_ref ( & this_trie_updates) ;
267+ nodes = Arc :: new ( nodes_mut) ;
260268
261269 // Write the changesets to the DB using the trie updates produced by the block, and the
262270 // trie reverts as the overlay.
0 commit comments