Skip to content

Commit cc643da

Browse files
committed
feat: add construct_prefix_sets methods for sorted state types
Add construct_prefix_sets() to HashedPostStateSorted and construct_prefix_set() to HashedStorageSorted to support the append_ref method on TrieInputSorted. These methods efficiently iterate over already-sorted data to build prefix sets needed for trie computation, without requiring any sorting operations. Also fix BuiltPayloadExecutedBlock conversion to correctly use Either::Right for sorted variants and convert unsorted to sorted when needed.
1 parent 39ac52d commit cc643da

File tree

3 files changed

+58
-8
lines changed

3 files changed

+58
-8
lines changed

crates/optimism/payload/src/builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,8 @@ impl<Txs> OpBuilder<'_, Txs> {
386386
let executed: BuiltPayloadExecutedBlock<N> = BuiltPayloadExecutedBlock {
387387
recovered_block: Arc::new(block),
388388
execution_output: Arc::new(execution_outcome),
389-
hashed_state: either::Either::Left(Arc::new(hashed_state.into_sorted())),
390-
trie_updates: either::Either::Left(Arc::new(trie_updates.into_sorted())),
389+
hashed_state: either::Either::Right(Arc::new(hashed_state.into_sorted())),
390+
trie_updates: either::Either::Right(Arc::new(trie_updates.into_sorted())),
391391
};
392392

393393
let no_tx_pool = ctx.attributes().no_tx_pool();

crates/payload/primitives/src/traits.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,17 @@ pub struct BuiltPayloadExecutedBlock<N: NodePrimitives> {
4242
impl<N: NodePrimitives> BuiltPayloadExecutedBlock<N> {
4343
/// Converts this into an [`reth_chain_state::ExecutedBlock`].
4444
///
45-
/// If the hashed state or trie updates are in sorted form, they will be converted
46-
/// back to their unsorted representations.
45+
/// If the hashed state or trie updates are in unsorted form, they will be converted
46+
/// to their sorted representations.
4747
pub fn into_executed_payload(self) -> reth_chain_state::ExecutedBlock<N> {
4848
let hashed_state = match self.hashed_state {
49-
Either::Left(unsorted) => unsorted,
50-
Either::Right(sorted) => Arc::new(Arc::unwrap_or_clone(sorted).into()),
49+
Either::Left(unsorted) => Arc::new(Arc::unwrap_or_clone(unsorted).into_sorted()),
50+
Either::Right(sorted) => sorted,
5151
};
5252

5353
let trie_updates = match self.trie_updates {
54-
Either::Left(unsorted) => unsorted,
55-
Either::Right(sorted) => Arc::new(Arc::unwrap_or_clone(sorted).into()),
54+
Either::Left(unsorted) => Arc::new(Arc::unwrap_or_clone(unsorted).into_sorted()),
55+
Either::Right(sorted) => sorted,
5656
};
5757

5858
reth_chain_state::ExecutedBlock {

crates/trie/common/src/hashed_state.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,38 @@ impl HashedPostStateSorted {
560560
self.accounts.destroyed_accounts.clear();
561561
self.storages.clear();
562562
}
563+
564+
/// Construct [`TriePrefixSetsMut`] from sorted hashed post state.
565+
/// The prefix sets contain the hashed account and storage keys that have been changed in the
566+
/// post state.
567+
pub fn construct_prefix_sets(&self) -> TriePrefixSetsMut {
568+
// Populate account prefix set from both live and destroyed accounts.
569+
let mut account_prefix_set = PrefixSetMut::with_capacity(
570+
self.accounts.accounts.len() + self.accounts.destroyed_accounts.len(),
571+
);
572+
573+
for (hashed_address, _) in &self.accounts.accounts {
574+
account_prefix_set.insert(Nibbles::unpack(hashed_address));
575+
}
576+
577+
for hashed_address in &self.accounts.destroyed_accounts {
578+
account_prefix_set.insert(Nibbles::unpack(hashed_address));
579+
}
580+
581+
// Populate storage prefix sets.
582+
let mut storage_prefix_sets =
583+
HashMap::with_capacity_and_hasher(self.storages.len(), Default::default());
584+
for (hashed_address, hashed_storage) in &self.storages {
585+
account_prefix_set.insert(Nibbles::unpack(hashed_address));
586+
storage_prefix_sets.insert(*hashed_address, hashed_storage.construct_prefix_set());
587+
}
588+
589+
TriePrefixSetsMut {
590+
account_prefix_set,
591+
storage_prefix_sets,
592+
destroyed_accounts: self.accounts.destroyed_accounts.clone(),
593+
}
594+
}
563595
}
564596

565597
impl AsRef<Self> for HashedPostStateSorted {
@@ -659,6 +691,24 @@ impl HashedStorageSorted {
659691
// Merge zero valued slots sets
660692
self.zero_valued_slots.extend(&other.zero_valued_slots);
661693
}
694+
695+
/// Construct [`PrefixSetMut`] from sorted hashed storage.
696+
pub fn construct_prefix_set(&self) -> PrefixSetMut {
697+
if self.wiped {
698+
PrefixSetMut::all()
699+
} else {
700+
let mut prefix_set = PrefixSetMut::with_capacity(
701+
self.non_zero_valued_slots.len() + self.zero_valued_slots.len(),
702+
);
703+
for (hashed_slot, _) in &self.non_zero_valued_slots {
704+
prefix_set.insert(Nibbles::unpack(hashed_slot));
705+
}
706+
for hashed_slot in &self.zero_valued_slots {
707+
prefix_set.insert(Nibbles::unpack(hashed_slot));
708+
}
709+
prefix_set
710+
}
711+
}
662712
}
663713

664714
impl From<HashedStorageSorted> for HashedStorage {

0 commit comments

Comments
 (0)