mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-07 22:43:56 -05:00
fix: revert slow path optimization that caused regression
The slow path optimization attempted to reuse ancestor cached overlays, but those overlays were built with a DIFFERENT anchor_hash. Since the slow path is triggered precisely because the anchor changed (after persist/reorg), reusing overlays from the old anchor produces incorrect results. Reverted to the original slow path that rebuilds from each ancestor's per-block state changes. The Arc::make_mut tracking metrics are kept.
This commit is contained in:
@@ -256,36 +256,16 @@ impl DeferredTrieData {
|
||||
/// Merge all ancestors into a single overlay.
|
||||
///
|
||||
/// This is the slow path used when the parent's overlay cannot be reused
|
||||
/// (e.g., after persist when anchor changes).
|
||||
/// (e.g., after persist when anchor changes). Iterates ancestors oldest -> newest
|
||||
/// so newer state takes precedence.
|
||||
///
|
||||
/// # Optimization
|
||||
/// Instead of iterating all ancestors from scratch, we find the most recent
|
||||
/// ancestor that has a cached `anchored_trie_input` and use that as the base.
|
||||
/// This reduces O(N) work to O(N - M) work where M is the cached depth.
|
||||
/// Note: We intentionally do NOT reuse ancestor cached overlays here because
|
||||
/// those overlays were built with a different anchor_hash. The slow path is
|
||||
/// triggered precisely because the anchor changed, so we must rebuild from
|
||||
/// each ancestor's per-block state changes.
|
||||
fn merge_ancestors_into_overlay(ancestors: &[Self]) -> TrieInputSorted {
|
||||
// Find the most recent ancestor (searching from newest to oldest) that has
|
||||
// a cached trie_input overlay. We can use that as our base and only merge
|
||||
// the remaining ancestors.
|
||||
let mut base_idx = 0;
|
||||
let mut overlay = TrieInputSorted::default();
|
||||
|
||||
for (idx, ancestor) in ancestors.iter().enumerate().rev() {
|
||||
let ancestor_data = ancestor.wait_cloned();
|
||||
if let Some(anchored) = &ancestor_data.anchored_trie_input {
|
||||
// Found a cached overlay! Use it as our base.
|
||||
// We only need to merge ancestors after this one.
|
||||
overlay = TrieInputSorted::new(
|
||||
Arc::clone(&anchored.trie_input.nodes),
|
||||
Arc::clone(&anchored.trie_input.state),
|
||||
Default::default(),
|
||||
);
|
||||
base_idx = idx + 1; // Start merging from the next ancestor
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Merge only the ancestors after the cached base (if any)
|
||||
for ancestor in &ancestors[base_idx..] {
|
||||
for ancestor in ancestors {
|
||||
let ancestor_data = ancestor.wait_cloned();
|
||||
{
|
||||
let will_clone = Arc::strong_count(&overlay.state) > 1;
|
||||
|
||||
Reference in New Issue
Block a user