wallet: avoid deferred keypool unlock deadlock - #143
Conversation
8383851 to
a0635a8
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2220e5f. Configure here.
PR ReviewFindings
Consensus Impact
The diff changes wallet keypool maintenance, notification timing, scheduler ownership, Qt delivery, and test timing. It does not alter transaction or block validity, signature verification, activation, chain selection, or committed serialization. Review ScopeReviewed issue #138 as the backing contract, the PR body, all five commits and 14 changed files, surrounding wallet/SPKM/Qt call paths, and the current exact-head CI results. I also inspected all three review threads; all are resolved and none remain open. Deep Checks PerformedTraced deferred refill from interface unlock through scheduler execution, descriptor locking, SQLite transaction ownership, cache publication, wallet notifications, and Qt queued delivery. I checked commit-listener lifetime and write-failure behavior, lock/relock and duplicate-scheduling races, reservation/refill atomicity, and attempted to disprove the finding by inspecting cache readers/writers and the actual TSan interleavings. Issue FitThe PR otherwise matches most of issue #138: interface unlock returns without synchronous full refill, address-availability notifications are moved past descriptor locks and transaction commit, the Qt bridge is explicitly queued, and deterministic tests cover scheduler rescheduling and the original lock/SQLite notification shape. The cache-publication race means the newly asynchronous refill is not yet safe alongside the issue’s requirement that transaction preparation proceed immediately after unlock. The qbit-Specific ChecksReviewed P2MR receive/change keypool state, encrypted-wallet lock/relock behavior, deferred-state persistence, duplicate worker ownership, reservation atomicity, failed-write rollback, and notification delivery. Direct RPC unlock behavior remains synchronous. No PQC signature construction, key serialization, P2MR address encoding, consensus, mining, or networking behavior changed. Validation ReviewedFull Validation and the required merge gate passed at head The author additionally reports focused wallet suites and the keypool functional test passing locally. I did not perform a separate local build because no build tree was present and exact-head sanitizer/platform CI covered the changed suites. Residual Risk
|

Summary
Fixes #138.
This removes the wallet/SQLite lock cycle that could freeze
qbit-qtimmediately after a correct passphrase was entered.Testing
Commands/checks:
cmake --build build_dev_mode --target test_bitcoin test_bitcoin-qt qbitd qbit-cli -j8wallet_tests/DescriptorTopUp*wallet_p2mr_deferred_keypool_tests/*wallet_p2mr_receive_keypool_tests/*wallet_p2mr_change_keypool_tests/*wallet_p2mr_markunused_tests/*test/functional/wallet_keypool_topup.pyci/lint/06_script.shthrough the Ubuntu 24.04 Docker lint imageThe new Qt regression compiled successfully. It was not independently executed because the macOS Qt test runner fails in a pre-existing
AppTestscase before reachingWalletTests.Target Branch
mainor a maintainer-requested release branch such as0.1.x.Target:
1.x.x.Risk / Review Notes
Notes:
This changes wallet notification timing and the interface unlock path. Direct wallet/RPC unlock behavior remains unchanged. Review should focus on transaction-listener lifetime, scheduler deduplication/reset behavior, and lock ordering around
cs_wallet,cs_desc_man, and the SQLite writer.Docs / Process Impact
Choose exactly one:
libbitcoinpqc Subtree Checklist (if
src/libbitcoinpqcchanged)Qbit-Org/qbit-libbitcoinpqc.contrib/devtools/update-libbitcoinpqc-subtree.sh.test/lint/libbitcoinpqc-subtree-check.shpasses locally.contrib/devtools/update-libbitcoinpqc-subtree.shis intentional and matchesdoc/subtrees/libbitcoinpqc.md.Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.Note
High Risk
Changes wallet unlock scheduling, lock ordering among cs_wallet/cs_desc_man/SQLite, and when address availability is visible—core GUI wallet behavior with race/deadlock sensitivity.
Overview
Fixes a post-unlock freeze in
qbit-qtby breaking a wallet/SQLite lock cycle around descriptor keypool maintenance.Descriptor keypool top-ups no longer call
TopUpCallbackorNotifyCanGetAddressesChangedwhilecs_desc_manor an open DB transaction is held. NewPublishTopUp/*NoNotifypaths batch script publication and address-availability signals after commit (includingRegisterTxnListenerfor caller-owned transactions).m_cached_spksis updated undercs_walletviaTopUpCallback, with related lookups taking the wallet lock.Qt delivers
canGetAddressesChangedthrough an explicitQt::QueuedConnection. GUI unlock (WalletImpl::unlock) skips synchronous initial keypool work, thenMaybeSchedulePendingInitialKeyPoolTopUpruns deduplicated scheduler steps (relock/reschedule handling). Wallet create/load still defer background refill with a longer delay.Regressions cover commit/abort visibility, lock ordering, interface unlock scheduling, failed top-ups (no spurious notify), and queued Qt delivery.
Reviewed by Cursor Bugbot for commit c3eb110. Bugbot is set up for automated code reviews on this repo. Configure here.