Skip to content

Conversation

@kwvg
Copy link
Collaborator

@kwvg kwvg commented Dec 17, 2025

Motivation

bitcoin#23123 removes the -rescan startup parameter outright and users are expected to utilise the rescanblockchain RPC instead. This requires us to rework how the rescan option is implemented in Dash Qt, which uses the startup parameter.

This pull request replaces it by implementing the core rescan logic in the wallet interface (as opposed to trying to invoke an RPC call from the Qt wallet, which would violate separation of concerns) and then implementing a wallet activity to avoid blocking the main thread.

An additional benefit of this approach is that the rescan happens immediately without the overhead of a client restart.

Additional Information

  • To avoid a potential race condition where a wallet could unloaded before the rescan can be triggered, m_rescan_wallet_model is now a QPointer (which will auto-reset when the underlying entity is destroyed, source) and we do one final check in the one-shot lambda before resolving the pointer.

Breaking Changes

None expected.

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 (note: N/A)
  • I have made corresponding changes to the documentation (note: N/A)
  • I have assigned this pull request to a milestone (for repository code-owners and collaborators only)

@kwvg kwvg added this to the 23.1 milestone Dec 17, 2025
@github-actions
Copy link

github-actions bot commented Dec 17, 2025

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

@kwvg
Copy link
Collaborator Author

kwvg commented Dec 17, 2025

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

Walkthrough

Introduces wallet rescan support across interfaces, implementation, and Qt UI. Adds enum wallet::RescanStatus and Wallet::startRescan(bool from_genesis). Implements startRescan in WalletImpl mapping ScanForWalletTransactions results to the new enum. Adds RescanWalletActivity in WalletController to run rescans asynchronously and emit rescanComplete/rescanFailed. RPCConsole and RPCConsole UI wiring updated to accept a WalletController, expose rescan slots, and update wallet selection/rescan button behavior. Debug UI text and rescan labels updated and legacy RESCAN1/RESCAN2 constants removed.

Sequence Diagram

sequenceDiagram
    participant User
    participant RPCConsole
    participant WalletController
    participant RescanActivity
    participant WalletModel
    participant WalletImpl

    User->>RPCConsole: Click "Rescan" (from_genesis?)
    RPCConsole->>WalletController: request rescan(wallet_model, from_genesis)
    WalletController->>RescanActivity: create activity and call rescan(...)
    RescanActivity->>WalletModel: validate / pass request
    RescanActivity->>WalletImpl: call startRescan(from_genesis) [worker thread]
    WalletImpl-->>RescanActivity: return wallet::RescanStatus
    RescanActivity->>WalletController: emit rescanComplete or rescanFailed
    WalletController->>User: show dialogs/signals for result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Review src/wallet/interfaces.cpp startRescan() logic: time/height calculation, WalletRescanReserver usage, ScanForWalletTransactions parameter mapping, and ScanResult→RescanStatus mapping.
  • Inspect RescanWalletActivity (src/qt/walletcontroller.cpp / .h): thread scheduling, m_rescan_status lifecycle, finish() branching, and signal usage.
  • Verify RPCConsole changes (src/qt/rpcconsole.h / .cpp): new wallet controller wiring, added slots (walletRescan variants, onWalletChanged), m_wallet_controller lifetime, and UI enable/disable logic.
  • Check public API changes (src/interfaces/wallet.h, src/wallet/wallet.h) for enum definition, visibility, and ABI compatibility.
  • Confirm removal of RESCAN1/RESCAN2 constants and updated debug UI labels do not leave stale references.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main feature: introducing Wallet::startRescan() as a replacement for the append-and-restart rescan method in Qt, with the additional benefit of enabling rescan for multiple wallets.
Description check ✅ Passed The description is well-related to the changeset, explaining the motivation (upstream bitcoin changes), implementation approach (wallet interface logic + activity pattern), benefits (no restart needed), and race condition mitigation (QPointer usage).
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 80e4a33 and 931707c.

📒 Files selected for processing (6)
  • src/qt/bitcoingui.cpp (1 hunks)
  • src/qt/rpcconsole.cpp (5 hunks)
  • src/qt/rpcconsole.h (5 hunks)
  • src/qt/walletcontroller.cpp (1 hunks)
  • src/qt/walletcontroller.h (3 hunks)
  • src/wallet/interfaces.cpp (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/qt/bitcoingui.cpp
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/qt/walletcontroller.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/walletcontroller.h
  • src/qt/rpcconsole.h
  • src/wallet/interfaces.cpp
src/qt/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

GUI implementation in src/qt/ must use Qt 5

Files:

  • src/qt/walletcontroller.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/walletcontroller.h
  • src/qt/rpcconsole.h
src/wallet/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Wallet implementation must use Berkeley DB and SQLite

Files:

  • src/wallet/interfaces.cpp
🧠 Learnings (20)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:247-250
Timestamp: 2025-07-29T14:32:48.369Z
Learning: In PR #6761, kwvg acknowledged a null pointer check issue in ChainLockSigner::Cleanup() method but deferred it to follow-up, consistent with the pattern of avoiding scope creep in refactoring PRs.
Learnt from: knst
Repo: dashpay/dash PR: 6805
File: src/wallet/rpc/wallet.cpp:357-357
Timestamp: 2025-08-08T07:01:47.332Z
Learning: In src/wallet/rpc/wallet.cpp, the upgradetohd RPC now returns a UniValue string message (RPCResult::Type::STR) instead of a boolean, including guidance about mnemonic backup and null-character passphrase handling; functional tests have been updated to assert returned strings in several cases.
📚 Learning: 2025-12-17T13:58:19.813Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:19.813Z
Learning: In Dash Qt wallet code, prefer using existing Qt signals/slots (e.g., ShowProgress signals) for long-running operations instead of adding explicit QProgressDialog dialogs. This minimizes upstream deviations and simplifies backports. Apply this pattern to wallet-related Qt components (e.g., operations like rescanning) and rely on signal-based progress updates rather than bespoke dialogs.

Applied to files:

  • src/qt/walletcontroller.cpp
  • src/qt/rpcconsole.cpp
📚 Learning: 2025-10-05T20:38:28.457Z
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.

Applied to files:

  • src/qt/walletcontroller.cpp
📚 Learning: 2025-06-09T16:43:20.996Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.

Applied to files:

  • src/qt/walletcontroller.cpp
📚 Learning: 2025-02-06T14:34:30.466Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.

Applied to files:

  • src/qt/walletcontroller.cpp
📚 Learning: 2025-10-25T07:08:51.918Z
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: For backport PRs from bitcoin/bitcoin, bitcoin-core/gui, etc., backported changes should match the original upstream PRs even if they appear strange, modify vendored code, or seem to violate coding guidelines. Still flag genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures.

Applied to files:

  • src/qt/walletcontroller.cpp
📚 Learning: 2025-07-29T14:33:01.040Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/wallet/wallet.cpp:0-0
Timestamp: 2025-07-29T14:33:01.040Z
Learning: In refactoring PRs like #6761, kwvg acknowledges code safety improvements (like null pointer checks and unused parameter warnings) but prefers to defer them to follow-up PRs to maintain focus on the primary refactoring objectives, avoiding scope creep.

Applied to files:

  • src/qt/walletcontroller.cpp
📚 Learning: 2025-10-13T12:37:12.357Z
Learnt from: knst
Repo: dashpay/dash PR: 6883
File: src/rpc/rawtransaction.cpp:1088-1125
Timestamp: 2025-10-13T12:37:12.357Z
Learning: In backport pull requests (especially from Bitcoin Core), treat "moved" or refactored code as out-of-scope for content-level review. Focus validation on verifying that code is moved correctly: no fields added, no fields removed, no fields reordered, and no unexpected changes beyond whitespace adjustments. Pre-existing issues in the upstream code should be preserved to maintain fidelity to the original implementation.

Applied to files:

  • src/qt/walletcontroller.cpp
📚 Learning: 2025-08-11T17:16:36.654Z
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.

Applied to files:

  • src/qt/walletcontroller.cpp
📚 Learning: 2025-07-29T14:32:48.369Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.cpp:247-250
Timestamp: 2025-07-29T14:32:48.369Z
Learning: In PR #6761, kwvg acknowledged a null pointer check issue in ChainLockSigner::Cleanup() method but deferred it to follow-up, consistent with the pattern of avoiding scope creep in refactoring PRs.

Applied to files:

  • src/qt/walletcontroller.cpp
📚 Learning: 2025-11-04T18:24:27.241Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/llmq/utils.cpp:284-298
Timestamp: 2025-11-04T18:24:27.241Z
Learning: In consensus-critical code (such as quorum formation, block validation, or deployment activation logic), do not suggest changes to the logic itself even if the implementation appears theoretically incorrect or off-by-one. Consensus rules, once deployed on the Dash network, must be preserved exactly to avoid network forks. Refactoring PRs should maintain perfect behavioral equivalence. Only suggest logic changes if explicitly accompanied by a DIP (Dash Improvement Proposal) or if the maintainer indicates the consensus rule needs to be changed with appropriate activation logic.

Applied to files:

  • src/qt/walletcontroller.cpp
📚 Learning: 2025-08-08T07:01:47.332Z
Learnt from: knst
Repo: dashpay/dash PR: 6805
File: src/wallet/rpc/wallet.cpp:357-357
Timestamp: 2025-08-08T07:01:47.332Z
Learning: In src/wallet/rpc/wallet.cpp, the upgradetohd RPC now returns a UniValue string message (RPCResult::Type::STR) instead of a boolean, including guidance about mnemonic backup and null-character passphrase handling; functional tests have been updated to assert returned strings in several cases.

Applied to files:

  • src/qt/rpcconsole.cpp
  • src/qt/rpcconsole.h
📚 Learning: 2025-02-14T15:19:17.218Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/wallet/rpcwallet.cpp:3002-3003
Timestamp: 2025-02-14T15:19:17.218Z
Learning: The `GetWallet()` function calls in `src/wallet/rpcwallet.cpp` are properly validated with null checks that throw appropriate RPC errors, making additional validation unnecessary.

Applied to files:

  • src/qt/rpcconsole.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite

Applied to files:

  • src/qt/rpcconsole.cpp
  • src/qt/walletcontroller.h
  • src/qt/rpcconsole.h
  • src/wallet/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5

Applied to files:

  • src/qt/rpcconsole.cpp
📚 Learning: 2025-12-17T13:58:26.891Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.

Applied to files:

  • src/qt/walletcontroller.h
  • src/qt/rpcconsole.h
  • src/wallet/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay

Applied to files:

  • src/wallet/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/node/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files

Applied to files:

  • src/wallet/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs

Applied to files:

  • src/wallet/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features

Applied to files:

  • src/wallet/interfaces.cpp
🧬 Code graph analysis (4)
src/qt/walletcontroller.cpp (2)
src/qt/walletcontroller.h (2)
  • RescanWalletActivity (176-194)
  • worker (99-99)
src/wallet/interfaces.cpp (2)
  • from_genesis (177-207)
  • from_genesis (177-177)
src/qt/rpcconsole.cpp (3)
src/qt/bitcoingui.cpp (6)
  • setWalletController (920-943)
  • setWalletController (920-920)
  • addWallet (950-976)
  • addWallet (950-950)
  • removeWallet (978-996)
  • removeWallet (978-978)
src/wallet/interfaces.cpp (2)
  • from_genesis (177-207)
  • from_genesis (177-177)
src/qt/guiutil.cpp (2)
  • PathToQString (1682-1685)
  • PathToQString (1682-1682)
src/qt/walletcontroller.h (2)
src/qt/walletcontroller.cpp (16)
  • RescanWalletActivity (515-518)
  • WalletControllerActivity (189-195)
  • rescan (520-534)
  • rescan (520-520)
  • rescanComplete (548-548)
  • rescanFailed (541-541)
  • rescanFailed (545-545)
  • rescanFailed (552-552)
  • finish (280-367)
  • finish (280-280)
  • finish (408-419)
  • finish (408-408)
  • finish (497-513)
  • finish (497-497)
  • finish (536-557)
  • finish (536-536)
src/wallet/interfaces.cpp (2)
  • from_genesis (177-207)
  • from_genesis (177-177)
src/wallet/interfaces.cpp (1)
src/interfaces/chain.h (1)
  • FoundBlock (54-79)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: Lint / Run linters
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: win64-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
🔇 Additional comments (21)
src/wallet/interfaces.cpp (2)

7-7: LGTM!

The addition of chain.h is necessary for the FoundBlock type used in the startRescan implementation.


177-207: LGTM! Well-structured rescan implementation.

The implementation correctly:

  • Initializes rescan_height to 0 for genesis rescans
  • Computes starting block from time_first_key when not rescanning from genesis
  • Uses WalletRescanReserver to prevent concurrent rescans (returns BUSY if reservation fails)
  • Maps all CWallet::ScanResult values to wallet::RescanStatus
  • Includes Assume(false) for the unreachable path with a fallback return for release builds
src/qt/walletcontroller.cpp (3)

515-518: LGTM!

The constructor correctly initializes the RescanWalletActivity as a WalletControllerActivity.


520-534: LGTM! Proper async rescan with race condition mitigation.

The implementation correctly:

  • Stores wallet_model in a QPointer to handle wallet unload scenarios
  • Schedules rescan on the worker thread using QTimer::singleShot
  • Checks if m_rescan_wallet_model is still valid before starting rescan (prevents race condition)
  • Sets status to FAILURE if wallet was unloaded before rescan could start
  • Schedules finish() after rescan completes

Based on learnings, relying on the wallet's inherited ShowProgress signal mechanism (mentioned in comment line 526) is the preferred approach to minimize upstream deviation.


536-557: LGTM! Comprehensive status handling with appropriate user feedback.

The finish() method correctly:

  • Handles all four RescanStatus cases (BUSY, FAILURE, SUCCESS, USER_ABORT)
  • Provides appropriate user feedback via QMessageBox for each failure case
  • Emits rescanComplete() on success and rescanFailed() on failures
  • Always emits finished() to complete the activity lifecycle
src/qt/rpcconsole.h (5)

27-27: LGTM!

Forward declaration of WalletController is appropriate for the new wallet integration.


62-62: LGTM!

The setWalletController method is correctly placed in the public API under ENABLE_WALLET to support wallet rescan functionality.


122-127: LGTM! Proper organization of repair options.

The changes correctly:

  • Move walletReindex() outside the ENABLE_WALLET block (it's not wallet-specific)
  • Add walletRescan1() and walletRescan2() within ENABLE_WALLET (they require wallet functionality)

181-186: LGTM!

The private helper methods are appropriately placed:

  • walletRescan(bool from_genesis) provides a common implementation for the two public rescan slots
  • onWalletChanged() handles UI updates when the selected wallet changes

201-201: LGTM!

The m_wallet_controller member variable is properly initialized to nullptr and will be set via setWalletController().

src/qt/rpcconsole.cpp (8)

22-22: LGTM!

The include of walletcontroller.h is necessary for the new wallet rescan integration.


576-584: LGTM! Proper initialization of wallet-dependent UI elements.

The changes correctly:

  • Disable rescan buttons by default (no wallet loaded yet)
  • Connect rescan buttons to their respective slots
  • Connect wallet selector to onWalletChanged() for dynamic updates

825-828: LGTM!

The setWalletController implementation correctly stores the wallet controller pointer for later use in wallet rescan operations.


837-846: LGTM! Proper wallet addition flow.

The changes correctly:

  • Call onWalletChanged() after adding a wallet to update UI state
  • Show wallet selector when multiple wallets are loaded (count > 2, accounting for the "(none)" entry)

852-860: LGTM! Proper wallet removal flow.

The changes correctly:

  • Call onWalletChanged() after removing a wallet to update UI state
  • Hide wallet selector when back to single wallet (count == 2)

869-885: LGTM! Comprehensive wallet state update logic.

The onWalletChanged() implementation correctly:

  • Retrieves the currently selected wallet model
  • Updates wallet path display with the full path when a valid wallet is selected
  • Enables rescan buttons when a valid wallet is selected
  • Clears wallet path and disables rescan buttons when no wallet is selected (e.g., "(none)")

934-963: LGTM! Robust wallet rescan implementation with proper error handling.

The implementation correctly:

  • Checks for valid m_wallet_controller before proceeding
  • Checks for valid wallet_model from the selector
  • Creates RescanWalletActivity and initiates rescan with appropriate from_genesis flag
  • Provides clear error messages for missing controller or wallet
  • walletRescan1() and walletRescan2() are simple, clear wrappers

972-995: LGTM! Simplified parameter list building.

The buildParameterlist() now correctly only removes REINDEX since RESCAN1 and RESCAN2 are no longer command-line parameters (the new approach uses the wallet interface directly instead of restarting with parameters).

src/qt/walletcontroller.h (3)

8-8: LGTM!

The include of interfaces/wallet.h is necessary for the wallet::RescanStatus type used in RescanWalletActivity.


20-20: LGTM!

The include of QPointer is necessary for the m_rescan_wallet_model member, which provides protection against dangling pointers if the wallet is unloaded during rescan.


176-194: LGTM! Well-designed activity class for async wallet rescan.

The RescanWalletActivity class is properly structured:

  • Derives from WalletControllerActivity for consistent activity lifecycle
  • Public rescan(WalletModel*, bool) method initiates the operation
  • Emits rescanComplete() and rescanFailed() signals for result notification
  • Uses QPointer<WalletModel> to safely handle wallet unload scenarios (prevents dangling pointer race conditions)
  • Stores wallet::RescanStatus for result processing in finish()

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/qt/forms/debugwindow.ui (1)

82-90: Repair tab help text is now misleading relative to in‑place wallet rescans

The updated labels for:

  • btn_rescan1 → “Rescan blockchain (partial)” / “starting from wallet creation time”, and
  • btn_rescan2 → “Rescan blockchain” / “starting from genesis block”

fit the new startRescan(from_genesis) behavior well.

However, label_repair_helptext still states that “The buttons below will restart the node with command-line options…”, which is no longer true for the rescan buttons now that they run via the wallet interface without a restart. Only the reindex path still restarts.

Suggest rewording that label to distinguish between:

  • options that trigger an in‑place wallet rescan, and
  • options like “Rebuild index” that actually restart the node with extra flags.

This avoids confusing users who see a rescan complete without any restart.

Also applies to: 1729-1797

🧹 Nitpick comments (6)
src/interfaces/wallet.h (1)

40-47: RescanStatus forward‑decl and startRescan API are coherent with the wallet layer

The new wallet::RescanStatus forward declaration and startRescan(bool from_genesis) interface cleanly expose rescan status to callers and match the concrete implementation in wallet::CWallet.

You might optionally expand the comment to spell out:

  • that from_genesis == false triggers a “from earliest key time” partial rescan, and
  • that RescanStatus::BUSY specifically means another rescan or scan is already running.

Functionally this looks good.

Also applies to: 97-101

src/wallet/wallet.h (2)

237-258: RescanStatus enum cleanly mirrors ScanResult outcomes

Defining enum class RescanStatus : uint8_t { BUSY, FAILURE, SUCCESS, USER_ABORT } here is consistent with CWallet::ScanResult::status and the interface return type.

If you want to make this easier to maintain, consider adding brief comments per value (e.g., “BUSY – a rescan or scan is already in progress”) so future contributors don’t have to trace through ScanForWalletTransactions to understand them. Otherwise this looks fine.


274-279: WalletRescanReserver RAII behavior and concurrency look sound; consider unifying the time source

WalletRescanReserver::reserve() correctly:

  • prevents concurrent scans via m_wallet.fScanningWallet.exchange(true),
  • initializes m_scanning_start, m_scanning_progress, and fAbortRescan, and
  • relies on the destructor to reset fScanningWallet even on early exit.

Two small polish points to consider:

  1. You already have an injectable Clock/NowFn (now() / setNow()), but reserve() still uses SystemClock::now() directly. If tests intend to control time, it may be clearer to route the start‑time assignment through now() (or otherwise drop the injection if it isn’t actually used anywhere).

  2. If you ever extend rescan metrics, it may be worth explicitly zeroing m_scanning_progress (and related fields) also on destructor, not just on reserve(), to guarantee a clean state after any scan path.

Current behavior is correct; these are just maintainability tweaks.

Also applies to: 1090-1131

src/wallet/interfaces.cpp (1)

176-204: startRescan() wiring is correct; consider handling a couple of edge cases more explicitly

The implementation aligns well with the new interface:

  • from_genesis == false finds the earliest key time across all script‑pubkey managers and starts from the first block at (time − TIMESTAMP_WINDOW),
  • from_genesis == true starts from height 0, and
  • WalletRescanReserver enforces a single active scan, returning RescanStatus::BUSY when another rescan is in progress.

Two small robustness tweaks you might consider:

  1. findFirstBlockWithTimeAndHeight return value
    Right now, if findFirstBlockWithTimeAndHeight(...) fails (e.g. unexpected pruning/DB issue), rescan_height silently remains 0 and the “partial” option degrades into a full rescan. That’s safe but opaque. Checking the bool return and either logging or returning RescanStatus::FAILURE in that case would make behavior more intentional.

  2. Default switch branch on ScanResult
    The switch falls through to return RescanStatus::SUCCESS; for any future CWallet::ScanResult values. If ScanResult is ever extended, that would misreport unknown outcomes as success. Treating the default as a failure (or adding an assert(false) / UNREACHABLE) would be safer.

None of this blocks the current change; the core behavior looks solid.

src/qt/walletcontroller.cpp (1)

531-551: Consider more specific message box titles.

Lines 538 and 546 both use the title "Rescan wallet failed", but they represent different scenarios:

  • Line 538: Actual failure (potentially corrupted data)
  • Line 546: Wallet is busy (temporary state)

For Line 546, consider using a more specific title like "Rescan unavailable" to distinguish it from actual failures.

Apply this diff:

     case wallet::RescanStatus::BUSY:
-        QMessageBox::warning(m_parent_widget, tr("Rescan wallet failed"), tr("Wallet is currently rescanning. Abort existing rescan or wait."));
+        QMessageBox::warning(m_parent_widget, tr("Rescan unavailable"), tr("Wallet is currently rescanning. Abort existing rescan or wait."));
         Q_EMIT rescanFailed();
         break;
src/qt/rpcconsole.cpp (1)

926-942: Document the wallet selector index assumption.

Line 934 hardcodes itemData(1) to retrieve the wallet model. Based on the addWallet() and removeWallet() logic (lines 829-870), index 0 appears reserved and index 1 is the first/only wallet. The rescan buttons are disabled when multiple wallets are loaded (lines 846-847).

Add a clarifying comment:

+    // Index 1 always contains the wallet when exactly one wallet is loaded
+    // (rescan buttons are disabled for 0 or multiple wallets)
     WalletModel* wallet_model{ui->WalletSelector->itemData(1).value<WalletModel*>()};

Alternatively, consider using ui->WalletSelector->currentData() if the intent is to operate on the currently selected wallet, though the current approach aligns with the single-wallet enforcement.

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea73b83 and 28c3dff0036459ec42c18282913837dd0c6bfb25.

📒 Files selected for processing (9)
  • src/interfaces/wallet.h (2 hunks)
  • src/qt/bitcoingui.cpp (1 hunks)
  • src/qt/forms/debugwindow.ui (5 hunks)
  • src/qt/rpcconsole.cpp (4 hunks)
  • src/qt/rpcconsole.h (5 hunks)
  • src/qt/walletcontroller.cpp (1 hunks)
  • src/qt/walletcontroller.h (2 hunks)
  • src/wallet/interfaces.cpp (1 hunks)
  • src/wallet/wallet.h (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{cpp,h,hpp,cc}

📄 CodeRabbit inference engine (CLAUDE.md)

Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1

Files:

  • src/interfaces/wallet.h
  • src/wallet/interfaces.cpp
  • src/qt/walletcontroller.cpp
  • src/wallet/wallet.h
  • src/qt/rpcconsole.cpp
  • src/qt/walletcontroller.h
  • src/qt/rpcconsole.h
  • src/qt/bitcoingui.cpp
src/wallet/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

Wallet implementation must use Berkeley DB and SQLite

Files:

  • src/wallet/interfaces.cpp
  • src/wallet/wallet.h
src/qt/**/*.{cpp,h}

📄 CodeRabbit inference engine (CLAUDE.md)

GUI implementation in src/qt/ must use Qt 5

Files:

  • src/qt/walletcontroller.cpp
  • src/qt/rpcconsole.cpp
  • src/qt/walletcontroller.h
  • src/qt/rpcconsole.h
  • src/qt/bitcoingui.cpp
🧠 Learnings (6)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: knst
Repo: dashpay/dash PR: 6805
File: src/wallet/rpc/wallet.cpp:357-357
Timestamp: 2025-08-08T07:01:47.332Z
Learning: In src/wallet/rpc/wallet.cpp, the upgradetohd RPC now returns a UniValue string message (RPCResult::Type::STR) instead of a boolean, including guidance about mnemonic backup and null-character passphrase handling; functional tests have been updated to assert returned strings in several cases.
📚 Learning: 2025-08-08T07:01:47.332Z
Learnt from: knst
Repo: dashpay/dash PR: 6805
File: src/wallet/rpc/wallet.cpp:357-357
Timestamp: 2025-08-08T07:01:47.332Z
Learning: In src/wallet/rpc/wallet.cpp, the upgradetohd RPC now returns a UniValue string message (RPCResult::Type::STR) instead of a boolean, including guidance about mnemonic backup and null-character passphrase handling; functional tests have been updated to assert returned strings in several cases.

Applied to files:

  • src/interfaces/wallet.h
  • src/wallet/interfaces.cpp
  • src/wallet/wallet.h
  • src/qt/rpcconsole.cpp
  • src/qt/rpcconsole.h
  • src/qt/forms/debugwindow.ui
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay

Applied to files:

  • src/wallet/interfaces.cpp
📚 Learning: 2025-02-14T15:19:17.218Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/wallet/rpcwallet.cpp:3002-3003
Timestamp: 2025-02-14T15:19:17.218Z
Learning: The `GetWallet()` function calls in `src/wallet/rpcwallet.cpp` are properly validated with null checks that throw appropriate RPC errors, making additional validation unnecessary.

Applied to files:

  • src/qt/rpcconsole.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite

Applied to files:

  • src/qt/rpcconsole.cpp
  • src/qt/walletcontroller.h
  • src/qt/rpcconsole.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5

Applied to files:

  • src/qt/rpcconsole.cpp
🧬 Code graph analysis (6)
src/interfaces/wallet.h (1)
src/wallet/interfaces.cpp (2)
  • from_genesis (176-204)
  • from_genesis (176-176)
src/wallet/interfaces.cpp (2)
src/interfaces/chain.h (1)
  • FoundBlock (54-79)
src/wallet/test/wallet_tests.cpp (4)
  • reserver (123-123)
  • reserver (143-143)
  • reserver (187-187)
  • reserver (214-214)
src/qt/walletcontroller.cpp (2)
src/wallet/interfaces.cpp (2)
  • from_genesis (176-204)
  • from_genesis (176-176)
src/qt/walletcontroller.h (2)
  • m_rescan_wallet_model (191-193)
  • worker (98-98)
src/qt/rpcconsole.cpp (1)
src/qt/bitcoingui.cpp (2)
  • setWalletController (920-943)
  • setWalletController (920-920)
src/qt/walletcontroller.h (2)
src/qt/walletcontroller.cpp (16)
  • RescanWalletActivity (515-518)
  • WalletControllerActivity (189-195)
  • rescan (520-529)
  • rescan (520-520)
  • rescanComplete (535-535)
  • rescanFailed (539-539)
  • rescanFailed (543-543)
  • rescanFailed (547-547)
  • finish (280-367)
  • finish (280-280)
  • finish (408-419)
  • finish (408-408)
  • finish (497-513)
  • finish (497-497)
  • finish (531-552)
  • finish (531-531)
src/wallet/interfaces.cpp (2)
  • from_genesis (176-204)
  • from_genesis (176-176)
src/qt/rpcconsole.h (4)
src/qt/walletcontroller.cpp (2)
  • WalletController (42-59)
  • WalletController (63-68)
src/qt/walletcontroller.h (1)
  • WalletController (47-83)
src/qt/rpcconsole.cpp (10)
  • setWalletController (824-827)
  • setWalletController (824-824)
  • walletReindex (958-961)
  • walletReindex (958-958)
  • walletRescan1 (945-948)
  • walletRescan1 (945-945)
  • walletRescan2 (951-954)
  • walletRescan2 (951-951)
  • walletRescan (927-942)
  • walletRescan (927-927)
src/qt/bitcoingui.cpp (2)
  • setWalletController (920-943)
  • setWalletController (920-920)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: linux64_multiprocess-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: win64-build / Build source
🔇 Additional comments (9)
src/qt/bitcoingui.cpp (1)

920-943: Hooking RPCConsole up to WalletController looks correct; just confirm lifetime handling

Wiring wallet_controller into rpcConsole here makes sense so the console can drive wallet‑level actions (like rescan). Please just confirm that RPCConsole::setWalletController() mirrors BitcoinGUI’s WalletController::destroyed handling (e.g., clears its internal pointer or disconnects signals) so it never dereferences a destroyed controller.

src/qt/walletcontroller.h (1)

175-194: LGTM!

The new RescanWalletActivity class follows the established pattern of other wallet controller activities (CreateWalletActivity, OpenWalletActivity, etc.). The structure is clean with appropriate signals for completion and failure states.

src/qt/walletcontroller.cpp (1)

515-518: LGTM!

The constructor follows the established pattern for wallet controller activities.

src/qt/rpcconsole.cpp (3)

576-584: LGTM!

The comment change from "Wallet Repair Buttons" to "Repair Buttons" is appropriate since the reindex button (Line 584) is not wallet-specific. The wallet-specific wiring is correctly guarded by #ifdef ENABLE_WALLET.


824-827: LGTM!

Simple setter method that integrates the wallet controller with the RPC console.


944-954: LGTM!

The two rescan methods clearly delegate to the common walletRescan() helper with appropriate from_genesis parameters. The comments effectively document the difference between the two rescan modes.

src/qt/rpcconsole.h (3)

27-27: LGTM!

The forward declaration and setWalletController() method are properly declared and guarded by #ifdef ENABLE_WALLET.

Also applies to: 62-62


122-127: LGTM!

The reorganization correctly places walletReindex() outside the #ifdef ENABLE_WALLET guard since it only triggers a restart with the -reindex flag, which is not wallet-specific. The wallet-specific rescan methods remain properly guarded.


181-184: LGTM!

The private walletRescan() helper method and m_wallet_controller member are properly declared and guarded by #ifdef ENABLE_WALLET. The member initialization follows modern C++ conventions.

Also applies to: 199-199

@kwvg kwvg force-pushed the qt_rescan branch 3 times, most recently from 9295d46 to f4daa88 Compare December 17, 2025 16:56
@kwvg kwvg marked this pull request as ready for review December 17, 2025 18:27
@UdjinM6
Copy link

UdjinM6 commented Dec 17, 2025

Pls see 8fb6cdb and 1b875ed. Also, as a side effect, we can now enable rescans when multiple wallets are loaded 🎉 see 280e42c (can be done in a separate PR if you think it's out of scope)

@kwvg kwvg changed the title feat(qt): introduce Wallet::startRescan() to replace append-and-restart method in Qt wallet feat(qt): introduce Wallet::startRescan() to replace append-and-restart method in Qt wallet, enable wallet rescan for multiple loaded wallets Dec 18, 2025
@UdjinM6
Copy link

UdjinM6 commented Dec 18, 2025

80e4a33: changes in src/qt/walletcontroller.* should be in some another commit

Copy link

@UdjinM6 UdjinM6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

light ACK 931707c

@PastaPastaPasta PastaPastaPasta merged commit 0455eb8 into dashpay:develop Dec 19, 2025
71 of 73 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants