mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-09 15:28:01 -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.
|
/// Merge all ancestors into a single overlay.
|
||||||
///
|
///
|
||||||
/// This is the slow path used when the parent's overlay cannot be reused
|
/// 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
|
/// Note: We intentionally do NOT reuse ancestor cached overlays here because
|
||||||
/// Instead of iterating all ancestors from scratch, we find the most recent
|
/// those overlays were built with a different anchor_hash. The slow path is
|
||||||
/// ancestor that has a cached `anchored_trie_input` and use that as the base.
|
/// triggered precisely because the anchor changed, so we must rebuild from
|
||||||
/// This reduces O(N) work to O(N - M) work where M is the cached depth.
|
/// each ancestor's per-block state changes.
|
||||||
fn merge_ancestors_into_overlay(ancestors: &[Self]) -> TrieInputSorted {
|
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();
|
let mut overlay = TrieInputSorted::default();
|
||||||
|
for ancestor in ancestors {
|
||||||
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..] {
|
|
||||||
let ancestor_data = ancestor.wait_cloned();
|
let ancestor_data = ancestor.wait_cloned();
|
||||||
{
|
{
|
||||||
let will_clone = Arc::strong_count(&overlay.state) > 1;
|
let will_clone = Arc::strong_count(&overlay.state) > 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user