#35444 wallet: make descriptor SPKM mutex non-recursive
https://github.com/bitcoin/bitcoin/pull/35444 · · +506/-213 in 8 files, 4 commits · labels: Wallet
Goal
- Prevent deadlocks and re-entrancy bugs by making descriptor script manager locking non-recursive
- Clarify wallet lock hierarchies and safely dispatch callbacks outside of lock scope
This PR converts `DescriptorScriptPubKeyMan`'s internal mutex `cs_desc_man` from a public `RecursiveMutex` to a private `Mutex` (renamed to `m_desc_mutex`). It splits internal routines into lock-held helpers and self-locking public entry points, removes external locking from caller sites, and defers address-availability callbacks until locks are released.
Problem: Recursive and externally exposed mutexes obscure locking hierarchies, making wallet components susceptible to deadlocks and re-entrancy issues as concurrency patterns evolve.
Category: Wallet (#51 of 84)
P3 · cleanup
- P3 because it is an internal concurrency cleanup that reduces deadlock risk without fixing an active bug
- Helps unblock the broader project effort to eliminate recursive mutexes
P3 because this is an internal concurrency cleanup that reduces deadlock risks rather than fixing an active regression or user-reported bug. It contributes to the project-wide effort to eliminate RecursiveMutex instances (#19303) and ensures safe callback dispatch without locks held.
Membership: Touches descriptor ScriptPubKeyMan locking and wallet synchronization in src/wallet/.
Factors: security/stability 1, bug 0, performance 0, user value 0, leverage 1
Reviewability: Ready
- Ready for review
- Cleanly rebased with passing CI and no open blockers
The PR is rebased, mergeable, and passing CI with no open blocker.
Author status: active, recently rebased the branch
Resolved concerns:
- pablomartin4btc questioned whether reading descriptor metadata and descriptor strings under separate locks in listdescriptors could introduce race conditions; w0xlt clarified that cs_wallet is held across both calls.
Agreement: Strong
- Strong support for the locking approach and clear commit structure (pablomartin4btc)
- Concept approval without stated reasons (hebasto)
- Atomicity concern regarding listdescriptors was resolved by clarifying wallet locking (pablomartin4btc)
Strong: two Concept ACKs with positive review feedback; minor questions answered and addressed
Reviewers support the approach and commit breakdown; the one atomicity concern raised was satisfactorily explained.
- pablomartin4btc: Concept ACK, praised the commit structure and internal helper separation, confirmed correctness.
- hebasto: Concept ACK.
- w0xlt addressed suggestions and rebased.
Review verdicts (DrahtBot): 0
- Concept ACK: pablomartin4btc, hebasto
Dependencies
Enables:
Files
119 lines under test/bench/ci.
- src/wallet/scriptpubkeyman.cpp +317/-143
- src/wallet/scriptpubkeyman.h +67/-52
- src/wallet/test/scriptpubkeyman_tests.cpp +118/-0
- src/wallet/external_signer_scriptpubkeyman.cpp +2/-9
- src/wallet/wallet.cpp +2/-6
- src/wallet/export.cpp +0/-1
- src/wallet/rpc/wallet.cpp +0/-1
- src/wallet/test/fuzz/scriptpubkeyman.cpp +0/-1
Card
This PR refactors DescriptorScriptPubKeyMan to make its mutex private and non-recursive, renaming it from cs_desc_man to m_desc_mutex. It internalizes locking inside public methods, replaces recursive call paths with lock-held helper functions, and defers address availability notifications outside critical sections to prevent re-entrancy deadlocks. The change advances the project-wide initiative to replace RecursiveMutex across the codebase (issue #19303). The PR has Concept ACKs from two reviewers, has resolved all review comments, and is cleanly rebased and ready for final review.