fix: remove redundant cs_wallet lock around requestMempoolTransactions#7230
fix: remove redundant cs_wallet lock around requestMempoolTransactions#7230thepastaclaw wants to merge 1 commit intodashpay:developfrom
Conversation
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
This pull request has conflicts, please rebase. |
✅ No Merge Conflicts DetectedThis PR currently has no conflicts with other open PRs. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughA single line in Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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 Tip CodeRabbit can suggest fixes for GitHub Check annotations.Configure the |
The WITH_LOCK(cs_wallet, ...) wrapper around chain().requestMempoolTransactions() creates a cs_wallet → cs_main lock ordering: requestMempoolTransactions acquires LOCK2(cs_main, mempool->cs), then calls transactionAddedToMempool which does LOCK(cs_wallet). This is inconsistent with the typical cs_main → cs_wallet ordering and would trigger DEBUG_LOCKORDER assertions. The wrapper is unnecessary since transactionAddedToMempool acquires cs_wallet internally per-transaction. Remove it. Closes dashpay#7226
ea1e8fe to
e7a422b
Compare
thepastaclaw
left a comment
There was a problem hiding this comment.
Code Review
The PR correctly fixes the cs_wallet → cs_main lock ordering violation in ScanForWalletTransactions and soundly refactors requestMempoolTransactions to snapshot under lock then notify outside lock. However, the identical lock ordering violation remains in postInitProcess, which is reachable from multi-threaded RPC handlers (CreateWallet, LoadWallet). The PR description's claim that RecursiveMutex makes this safe is incorrect — RecursiveMutex only prevents self-deadlock on re-entrant acquisition by the same thread, not cross-thread deadlock from lock ordering inversion.
Reviewed commit: e7a422b
🟡 1 suggestion(s)
1 additional finding(s) omitted (not in diff).
🤖 Prompt for all review comments with AI agents
These findings are from an automated code review. Verify each finding against the current code and only fix it if needed.
In `src/wallet/wallet.cpp`:
- [SUGGESTION] lines 3463-3473: postInitProcess() still holds cs_wallet across requestMempoolTransactions — same lock ordering violation this PR fixes elsewhere
postInitProcess() acquires `LOCK(cs_wallet)` at line 3465, then calls `chain().requestMempoolTransactions(*this)` at line 3472, which acquires `LOCK2(::cs_main, m_node.mempool->cs)` in interfaces.cpp. This is the same cs_wallet → cs_main ordering violation that the PR correctly fixes in ScanForWalletTransactions.
The PR description states no change is needed here because cs_wallet is a RecursiveMutex. This reasoning is incorrect: RecursiveMutex only prevents self-deadlock when the *same thread* re-acquires cs_wallet (which happens when transactionAddedToMempool re-enters cs_wallet). It does NOT prevent cross-thread deadlock from the cs_wallet → cs_main ordering inversion.
Deadlock scenario: Thread A (postInitProcess via CreateWallet/LoadWallet RPC) holds cs_wallet, waits for cs_main. Thread B (block validation) holds cs_main, waits for cs_wallet via a ValidationInterface callback.
This is pre-existing and not introduced by this PR, but since the same pattern is being addressed, it would be natural to fix it here. The fix is identical: release cs_wallet before calling requestMempoolTransactions.
bc7484c to
e7a422b
Compare
|
The p2p_node_network_limited TSAN failure is a known flaky test — it's the same issue tracked in #7228 (the test tries to use node 0 after it's been stopped for a Dash-specific governance stderr check). That's been fixed on the backport branch and will land separately. Removed the empty retrigger commit and force-pushed to keep history clean. CI will re-run on the force push. |
fix: remove redundant cs_wallet lock around requestMempoolTransactions
Summary
The
WITH_LOCK(cs_wallet, ...)wrapper aroundchain().requestMempoolTransactions(*this)inScanForWalletTransactionscreates an inconsistent lock ordering:
Lock order: cs_wallet → cs_main, which conflicts with the standard
cs_main → cs_wallet ordering and would trigger
DEBUG_LOCKORDERassertions.Fix
Remove the outer
WITH_LOCK(cs_wallet, ...)wrapper.transactionAddedToMempoolacquirescs_walletinternally per-transaction,so the outer lock is redundant.
ScanForWalletTransactionsdoes not holdcs_walletat this point in thefunction — all prior
LOCK(cs_wallet)scopes have been released.Notes
requestMempoolTransactionscall inLoadWallet(line 3472) is alreadycalled while
cs_walletis held viaRecursiveMutex— no change needed thereValidation
1-line removal of a redundant lock wrapper. No behavioral change;
cs_walletis re-acquired per-transaction inside
transactionAddedToMempool.Verified by code inspection.