Skip to content

stagedsync: replace TxLookup prune full-table scan with block-based deletion#19975

Closed
domiwei wants to merge 2 commits intomainfrom
kewei/fix-txlookup-prune-perf
Closed

stagedsync: replace TxLookup prune full-table scan with block-based deletion#19975
domiwei wants to merge 2 commits intomainfrom
kewei/fix-txlookup-prune-perf

Conversation

@domiwei
Copy link
Copy Markdown
Member

@domiwei domiwei commented Mar 18, 2026

Summary

#19890

  • PruneTxLookup previously used TableScanningPrune which scans the entire
    TxLookup table (keyed by random tx hashes) to find entries within a txNum
    range — O(table_size). At chain tip this burned a constant ~2s per block
    even when there was nothing to prune, wasting ~17% of the 12s slot budget.
  • Replace with deleteTxLookupRange which iterates HeaderCanonical for the
    block range, looks up each block's transactions, and deletes their TxLookup
    entries directly — O(txs_to_delete). This is the same approach already used
    by UnwindTxLookup.
  • At chain tip, cap pruning to 100 blocks per cycle to bound DB transaction size.

Background

PR #19179 ("prune unification") moved TxLookup to the generic TableScanningPrune
framework. That framework works well for tables whose keys contain txNum/step
(domain, history, inverted_index), but TxLookup keys are random tx hashes with
txNum buried in the value — forcing a full table scan even when 0 entries need
deleting.

Test plan

  • make lint
  • make test-short
  • Verify on a synced mainnet node that TxLookup prune completes in
    milliseconds instead of ~2s at chain tip

domiwei and others added 2 commits March 18, 2026 09:07
…-based deletion

PruneTxLookup previously used TableScanningPrune which scans the entire
TxLookup table (keyed by random tx hashes) to find entries within a txNum
range — O(table_size). At chain tip this burned a constant ~2s per block
even when there was nothing to prune, wasting ~17% of the slot budget.

Replace with deleteTxLookupRange which iterates HeaderCanonical for the
block range, looks up each block's transactions, and deletes their
TxLookup entries directly — O(txs_to_delete). This is the same approach
already used by UnwindTxLookup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Bound the work done inside a single DB transaction to avoid occupying
too much of the 12-second slot budget when the node falls slightly
behind. During initial sync the limit is not applied.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@domiwei domiwei requested review from mh0lt and yperbasis as code owners March 18, 2026 09:45
@domiwei domiwei requested review from AskAlexSharov and JkLondon and removed request for JkLondon, mh0lt and yperbasis March 18, 2026 09:45
@JkLondon
Copy link
Copy Markdown
Member

it's not a full scan in one iteration. We have progress tracking of scan exactly because we want to avoid this. So, probably, the reason of bug is that txTo changes to often or table is just enormously large need to investigate.
I like this PR #19898, probably it will fix it

@JkLondon JkLondon closed this Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants