fix: skip collecting block txids during IBD to prevent unbounded memory growth#7208
Conversation
…ounded memory growth ChainLockSigner::BlockConnected unconditionally stores all non-coinbase txids for every connected block, but Cleanup() skips pruning while !IsBlockchainSynced(). This causes the blockTxs map to grow with the entire chain's transaction IDs during initial block download or reindex. Since TrySignChainTip() already returns early when !IsBlockchainSynced(), the collected txids are never used during IBD. Add the same guard to BlockConnected to prevent the unnecessary memory accumulation.
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
✅ No Merge Conflicts DetectedThis PR currently has no conflicts with other open PRs. |
WalkthroughA guard clause was added to the Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…event unbounded memory growth c3a552a fix(chainlock): skip collecting block txids during IBD to prevent unbounded memory growth (PastaClaw) Pull request description: ## Motivation `ChainLockSigner` is registered as a `CValidationInterface` and receives `BlockConnected` events during initial block download. It stores all non-coinbase txids for every connected block in `blockTxs`, but `Cleanup()` skips pruning while `!IsBlockchainSynced()`. This causes `blockTxs` to grow with the entire chain's transaction IDs during IBD/reindex, leading to unbounded memory growth. Since `TrySignChainTip()` already returns early when `!IsBlockchainSynced()`, the collected txids are never used during IBD — they just accumulate until sync completes. ## Fix Add the same `!IsBlockchainSynced()` guard to `BlockConnected()` that already exists in `TrySignChainTip()` and `Cleanup()`, skipping txid collection entirely during IBD. ## Validation - Traced `TrySignChainTip()` — confirms it early-returns when not synced, so txids collected during IBD are never consumed - Traced `Cleanup()` — confirms it also early-returns when not synced, so no pruning happens during IBD - Traced `GetBlockTxs()` — has a fallback path that reads from disk when txids aren't in `blockTxs`, so post-sync tip signing still works for blocks connected during IBD - `BlockDisconnected` only handles reorgs (erases single entry), not bulk cleanup ## Checklist - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [ ] I have assigned this pull request to a milestone ACKs for top commit: UdjinM6: utACK c3a552a Tree-SHA512: d395d33ff8c9d4f2539b8ab3fb14adafc732ff7b3a5cccc83efa390615926ea920e7d50490080ace39812960f04439b4387784a0ffa1d7c12f1e69434b3f336c
- Bump version: 23.1.1 → 23.1.2 (configure.ac) - Update flatpak metainfo with v23.1.2 release entry - Update release notes: include all v23.1.1 notes plus dashpay#7208 and dashpay#7209 - Update set-of-changes comparison link - Add PastaPastaPasta to credits v23.1.1 was scrubbed; releasing as v23.1.2 instead.
…event unbounded memory growth c3a552a fix(chainlock): skip collecting block txids during IBD to prevent unbounded memory growth (PastaClaw) Pull request description: ## Motivation `ChainLockSigner` is registered as a `CValidationInterface` and receives `BlockConnected` events during initial block download. It stores all non-coinbase txids for every connected block in `blockTxs`, but `Cleanup()` skips pruning while `!IsBlockchainSynced()`. This causes `blockTxs` to grow with the entire chain's transaction IDs during IBD/reindex, leading to unbounded memory growth. Since `TrySignChainTip()` already returns early when `!IsBlockchainSynced()`, the collected txids are never used during IBD — they just accumulate until sync completes. ## Fix Add the same `!IsBlockchainSynced()` guard to `BlockConnected()` that already exists in `TrySignChainTip()` and `Cleanup()`, skipping txid collection entirely during IBD. ## Validation - Traced `TrySignChainTip()` — confirms it early-returns when not synced, so txids collected during IBD are never consumed - Traced `Cleanup()` — confirms it also early-returns when not synced, so no pruning happens during IBD - Traced `GetBlockTxs()` — has a fallback path that reads from disk when txids aren't in `blockTxs`, so post-sync tip signing still works for blocks connected during IBD - `BlockDisconnected` only handles reorgs (erases single entry), not bulk cleanup ## Checklist - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [ ] I have assigned this pull request to a milestone ACKs for top commit: UdjinM6: utACK c3a552a Tree-SHA512: d395d33ff8c9d4f2539b8ab3fb14adafc732ff7b3a5cccc83efa390615926ea920e7d50490080ace39812960f04439b4387784a0ffa1d7c12f1e69434b3f336c
into v23.1.x da16809 docs: add #7221 and #7222 to v23.1.2 release notes (PastaClaw) 8a93926 Merge #7222: fix: properly skip evodb repair on reindex (pasta) b74b549 Merge #7221: refactor: rename bitcoin-util manpage and test references to dash-util (pasta) 81464ac Merge #7211: fix: qt info tab layout (pasta) 7c27c2f Merge #7209: fix: serialize TrySignChainTip to prevent concurrent signing race (pasta) 81d5eb2 Merge #7208: fix: skip collecting block txids during IBD to prevent unbounded memory growth (pasta) Pull request description: ## Backport Cherry-picks of #7208, #7209, #7211, #7221, and #7222 into `v23.1.x` for v23.1.2. ### Included - #7208 — `fix: skip collecting block txids during IBD to prevent unbounded memory growth` - #7209 — `fix: serialize TrySignChainTip to prevent concurrent signing race` - #7211 — `fix: qt info tab layout` - #7221 — `refactor: rename bitcoin-util manpage and test references to dash-util` - #7222 — `fix: properly skip evodb repair on reindex` ACKs for top commit: UdjinM6: utACK da16809 Tree-SHA512: bbe74a62fd34bdcaece22100050072706774854db47d61af644700ca063e2a3cdfd474fa451681861bf1a6e91436ebd3715838640fc992fbba7c2b57b4f02760
da16809 docs: add #7221 and #7222 to v23.1.2 release notes (PastaClaw) 8a93926 Merge #7222: fix: properly skip evodb repair on reindex (pasta) b74b549 Merge #7221: refactor: rename bitcoin-util manpage and test references to dash-util (pasta) 81464ac Merge #7211: fix: qt info tab layout (pasta) 7c27c2f Merge #7209: fix: serialize TrySignChainTip to prevent concurrent signing race (pasta) 81d5eb2 Merge #7208: fix: skip collecting block txids during IBD to prevent unbounded memory growth (pasta) d02243c ci: run check-skip on blacksmith with GitHub-hosted fallback (PastaClaw) 033b3fe chore: regenerate manpages for v23.1.2 (PastaClaw) ff965b5 chore: v23.1.2 release preparation (PastaClaw) 8d5936d chore: add #7191 and #7193 to v23.1.1 release notes (PastaClaw) 9f3662b chore: v23.1.1 release preparation (PastaClaw) 5dbfa98 chore: v23.1.1 release preparation (PastaClaw) 240a95f Merge #7193: fix: reject identity elements in deserialization and key generation (pasta) 444cbf2 Merge #7191: fix(qt): reseat quorum labels when new types are inserted (pasta) 00f590d Merge #7180: qt: add Tahoe styled icons for macOS, runtime styling for each network type, update bundle icon, add mask-based tray icon, generation scripts (pasta) 60dda51 Merge #7176: perf: do linear lookup instead building 2 heavy Hash-Maps (pasta) df1ca87 Merge #7159: feat(qt): UI refresh (5/n, add proposal information widget to information, donut chart for proposal allocation) (pasta) 9061ad0 Merge #7118: feat(qt): UI refresh (4/n, introduce distinct widgets for Dash-specific reporting in debug window) (pasta) 64cc4f2 Merge #7160: feat(interfaces): consolidate masternode counts into one struct, expose chainlock, instantsend, credit pool, quorum statistics (pasta) 5d28a69 Merge #7157: fix(qt): prevent banned masternodes from returning status=0 (pasta) e0b7386 Merge #7146: feat(qt): introduce framework for sourcing and applying data, use for `{Masternode,Proposal}List`s (pasta) 8fd53cd Merge #7144: feat(qt): add support for reporting `OP_RETURN` payloads as Data Transactions (pasta) cc6f0bb Merge #7154: fix: MN update notifications had old_list/new_list swapped (pasta) 33f0138 Merge #7145: fix(qt): move labelError styling from proposalcreate.ui into general.css (pasta) 1bdbde6 Merge #7148: feat(qt): persist filter preferences in masternode list (pasta) 96bb601 Merge #7147: fix(qt): prevent overview page font double scaling, recalculate minimum width correctly, `SERVICE` and `STATUS` sorting, fix common types filtering (pasta) da1e336 build: expand minimum Darwin version to macOS 11 (Big Sur) (Kittywhiskers Van Gogh) Pull request description: ## Issue being fixed or feature implemented Note: Skipping changes from #7149 which was for the v23.1.x only. ## What was done? ## How Has This Been Tested? ## Breaking Changes ## Checklist: - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [ ] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_ ACKs for top commit: kwvg: utACK 36988f9 Tree-SHA512: f5bf8f0af11379bbcea606108ee90af08c16f588ebdbfac1fdd567adfcad14926b9c797c8fa6b398fb65fc3210c5f2c084015ea07718371df04e2412625f42d4
Motivation
ChainLockSigneris registered as aCValidationInterfaceand receivesBlockConnectedevents during initial block download. It stores all non-coinbase txids for every connected block inblockTxs, butCleanup()skips pruning while!IsBlockchainSynced(). This causesblockTxsto grow with the entire chain's transaction IDs during IBD/reindex, leading to unbounded memory growth.Since
TrySignChainTip()already returns early when!IsBlockchainSynced(), the collected txids are never used during IBD — they just accumulate until sync completes.Fix
Add the same
!IsBlockchainSynced()guard toBlockConnected()that already exists inTrySignChainTip()andCleanup(), skipping txid collection entirely during IBD.Validation
TrySignChainTip()— confirms it early-returns when not synced, so txids collected during IBD are never consumedCleanup()— confirms it also early-returns when not synced, so no pruning happens during IBDGetBlockTxs()— has a fallback path that reads from disk when txids aren't inblockTxs, so post-sync tip signing still works for blocks connected during IBDBlockDisconnectedonly handles reorgs (erases single entry), not bulk cleanupChecklist