qt: move P2MR fee bump signing off the GUI thread - #146
Conversation
1c10c16 to
34a1562
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9723919. Configure here.
PR ReviewFindings
No blocking correctness findings from this review pass. Consensus Impact
The PR does not change block or transaction validity, but it changes P2MR counter-reservation/signing flow in Review ScopeReviewed issue #142 as the contract, all eight commits and 22 changed files against the actual Deep Checks PerformedTraced preparation, unlock, signing, counter reservation, commit, cancellation, shutdown, wallet unload, and QObject destruction paths. Checked serial and parallel P2MR signing, external-signer PSBT replacement, PQC usage propagation, replacement ancestry, external inputs, competing wallet spends, fee/policy revalidation, and the fixes for every earlier inline finding. Issue FitThe implementation substantially matches #142:
PQC usage presentation remains correctly outside scope. No unrelated consensus or public RPC behavior was added. qbit-Specific ChecksReviewed P2MR serial/parallel counter durability, cancellation after reservation, provider snapshot lifetime, wallet relocking, external-signer command boundaries, replacement-chain metadata, and worker teardown during shutdown/unload. AuxPoW, ASERT, PHOTON, and release-signing surfaces are untouched. Validation ReviewedCurrent CI is green at The author additionally reports focused wallet/Qt tests, Residual Risk
|

Summary
Fixes #142.
Fee-bump preparation, signing, and commit previously ran synchronously on the Qt GUI thread, while
feebumper::SignTransaction()heldcs_walletacross the complete signing operation. P2MR cryptographic signing could therefore freeze the GUI and prevent other wallet work from acquiring the wallet lock.This change:
Structured PQC usage data is preserved through the worker result, but user-facing usage presentation remains out of scope for #141.
Testing
Commands and results:
cmake --build build -j6 --target bitcoin_wallet bitcoinqt test_bitcoin test_bitcoin-qt— passed.feebumper_tests/p2mr_signing_releases_wallet_lock— passed with a deterministic post-reservation/pre-crypto latch proving another thread can acquirecs_wallet.feebumper_tests/commit_revalidates_fee_after_signing— passed.feebumper_tests/commit_revalidates_competing_wallet_spend— passed.wallet_tests/sign_transaction_*— four signing progress/cancellation tests passed.wallet_p2mr_batch_reservation_tests— three tests passed.feebumper_tests/external_max_weight_test— passed.ulimit -n 1024 && build/test/functional/test_runner.py --jobs=2 wallet_bumpfee.py feature_rbf.py— both passed.ulimit -n 1024 && QT_QPA_PLATFORM=cocoa QTEST_FUNCTION_TIMEOUT=600000 build/bin/test_qbit-qt— all wallet and application lifecycle suites passed; the binary still reports the unrelated existingRPCNestedTests::rpcNestedTestsexpected-hash mismatch in unchanged code.git diff --check origin/1.x.x...HEAD— passed.Target Branch
mainor a maintainer-requested release branch such as0.1.x.Target:
1.x.x.Risk / Review Notes
Notes:
cs_walletlock held.FillPSBTpath may retaincs_walletwhile an external command runs.bumpfeeretains its existing caller-side wallet lock; this PR targets the Qt lifecycle from Move P2MR fee-bump signing off the qbit-qt GUI thread #142.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.Note
High Risk
Touches wallet fee-bump signing, PQC counter reservation, and commit-time replacement checks—areas where races or missed revalidation could leak counters or broadcast invalid replacements; scope is large but heavily tested.
Overview
Moves Qt fee bump off the GUI thread:
WalletModel::bumpFeenow clones the wallet interface, runs preparation and signing/commit on a worker thread, shows a modal progress dialog, and emitsfeeBumpedwhen done.TransactionViewno longer blocks on bump completion; it listens for that signal to refresh the table.Cancellation is cooperative via
SigningProgressCallbackon create/sign bump APIs. After durable PQC counter reservation (or the external-signer command boundary), bumps become irreversible—cancel is ignored and shutdown still waits for commit. Signing paths gainpqc_counter_reservation_guardso reservation can abort before counters are consumed.Fee bumper gains preparation-time cancel checks, richer signing progress (including PQC usage on sign), a check that signing only changes input witnesses/signatures, and
RevalidateReplacementat commit (inputs, competing wallet spends, fees, relay/mempool policy, weight, chain limits).GetWalletSpenderssupports that revalidation;CommitTransactionskips notify for non-wallet prevouts.Extensive Qt synthetic wallet and
TestAsyncFeeBumpLifecyclecoverage exercises cancel races, shutdown, and model teardown; functionalwallet_signerbump uses in-PSBT signing for integrity.Reviewed by Cursor Bugbot for commit 7485c3f. Bugbot is set up for automated code reviews on this repo. Configure here.
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.