fix(node): evict imported blocks' transactions from mempool + periodic expiry#136
Merged
Conversation
…135) Mempool eviction only ran at self-production (producer.rs); blocks imported from other validators never evicted their txs, and select_with_nonce skips stale-nonce txs without removing them, so every tx mined by another node became an immortal zombie: oldest-tx-age SLI climbed monotonically (45+ min observed on testnet), depth stepped up, and the 15m T2 alert was permanently red. - SyncManager::evict_imported_txs: on every successful import (gossip, fetched, pending-drain, range-sync — all 4 sites) remove the block's txs by blake3(to_bytes_without_signature), the pool's own key space. - Catch-up tick now calls remove_expired() as a backstop (previously zero callers — even the 1h tx_lifetime never ran). - pool.rs test pins the recomputed-hash key-space contract. Tests: qfc-mempool 7/7, qfc-node unit 18/18, integration 6/6 (release). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #135.
Problem
Mempool eviction only happened at self-production (
producer.rs:457). Blocks imported from other validators never evicted their txs, andselect_with_nonceskips stale-nonce txs without removing them — so with 3 validators in round-robin, ~2/3 of every node's pool became immortal zombies. Observed on the post-reset testnet:oldest_tx_ageclimbing linearly past 45 min (T2 alert at 15m permanently red), node-3 depth stepping up monotonically.Fix
SyncManager::evict_imported_txs— on every successfulimport_block(all 4 sites: gossiphandle_block, fetched-block task, pending-blocks drain, range-sync catch-up) remove the block's txs from the local pool, keyed byblake3(tx.to_bytes_without_signature())— the same key space the pool uses at insert and producer.rs uses at production.remove_expired()in the catch-up tick (5s) as a backstop for txs that will never be mined under their exact hash (e.g. superseded duplicates). Previously the pool's 1htx_lifetimehad zero callers.Verification
cargo test -p qfc-mempool7/7 (incl. new test)cargo test -p qfc-nodeunit 18/18, integration 6/6 (release binary)oldest pending tx ageshould saturate and reset instead of climbing forever; node-3 depth should drain. Will verify on the next image rollout during the soak.🤖 Generated with Claude Code