Skip to content

backport!: bitcoin#23123, #23147 (wallet rescan related, breaking changes)#7037

Open
knst wants to merge 2 commits into
dashpay:developfrom
knst:bp-breaking-to-v24
Open

backport!: bitcoin#23123, #23147 (wallet rescan related, breaking changes)#7037
knst wants to merge 2 commits into
dashpay:developfrom
knst:bp-breaking-to-v24

Conversation

@knst

@knst knst commented Dec 3, 2025

Copy link
Copy Markdown
Collaborator

What was done?

Various backports that have breaking changes. They are for Xmas Dash Core v24

How Has This Been Tested?

Run unit & functional tests

Breaking Changes

The -rescan startup parameter has been removed. Wallets which require
rescanning due to corruption will still be rescanned on startup.
Otherwise, please use the rescanblockchain RPC to trigger a rescan.

Checklist:

Go over all the following points, and put an x in all the boxes that apply.

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

@github-actions

github-actions Bot commented Dec 3, 2025

Copy link
Copy Markdown

✅ No Merge Conflicts Detected

This PR currently has no conflicts with other open PRs.

@kwvg kwvg added this to the 24 milestone Dec 4, 2025
@github-actions

github-actions Bot commented Feb 6, 2026

Copy link
Copy Markdown

This pull request has conflicts, please rebase.

@knst knst force-pushed the bp-breaking-to-v24 branch from 58b7f6a to f92df04 Compare June 3, 2026 07:55
@knst knst force-pushed the bp-breaking-to-v24 branch from f92df04 to e29ed01 Compare June 3, 2026 07:56
@knst knst added the RPC Some notable changes to RPC params/behaviour/descriptions label Jun 3, 2026
@knst knst marked this pull request as ready for review June 3, 2026 11:30
@knst knst requested review from PastaPastaPasta and UdjinM6 June 3, 2026 11:30
@knst knst changed the title backport: variour backport with breaking changes, for Dash Core v24 backport!: bitcoin#23123, #23147 (wallet rescan related, breaking changes) Jun 3, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e29ed01e62

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/wallet/wallet.cpp
}

return DBErrors::LOAD_OK;
return nLoadWalletRet;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Avoid writing to wallets that failed to load

Because the early return for non-LOAD_OK results was removed, any wallet load error now falls through to the CoinJoin salt initialization before this return. In the scenario where WalletBatch::LoadWallet() returns CORRUPT, TOO_NEW, or NEED_REWRITE and the wallet has no salt, SetCoinJoinSalt(GetRandHash()) writes a new record to the same database even though the wallet is about to be rejected, so merely attempting to open a damaged or unsupported wallet can mutate it. Please only fall through for statuses that are meant to continue loading, or return before side effects for hard failures.

Useful? React with 👍 / 👎.

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b66c3f57-9dc3-4b90-92ff-2cd93bd700fc

📥 Commits

Reviewing files that changed from the base of the PR and between fdaf1e4 and 2970303.

📒 Files selected for processing (17)
  • doc/release-notes-remove-rescan.md
  • src/dummywallet.cpp
  • src/init.cpp
  • src/wallet/init.cpp
  • src/wallet/rpc/backup.cpp
  • src/wallet/rpc/wallet.cpp
  • src/wallet/salvage.cpp
  • src/wallet/test/wallet_tests.cpp
  • src/wallet/wallet.cpp
  • src/wallet/wallet.h
  • src/wallet/walletdb.cpp
  • src/wallet/walletdb.h
  • src/wallet/wallettool.cpp
  • test/functional/feature_notifications.py
  • test/functional/wallet_basic.py
  • test/functional/wallet_hd.py
  • test/functional/wallet_upgradetohd.py
💤 Files with no reviewable changes (2)
  • src/wallet/init.cpp
  • src/dummywallet.cpp
✅ Files skipped from review due to trivial changes (4)
  • doc/release-notes-remove-rescan.md
  • src/wallet/salvage.cpp
  • src/init.cpp
  • src/wallet/rpc/backup.cpp
🚧 Files skipped from review as they are similar to previous changes (11)
  • src/wallet/test/wallet_tests.cpp
  • test/functional/wallet_upgradetohd.py
  • test/functional/wallet_hd.py
  • src/wallet/walletdb.h
  • src/wallet/rpc/wallet.cpp
  • src/wallet/walletdb.cpp
  • src/wallet/wallet.h
  • src/wallet/wallettool.cpp
  • test/functional/feature_notifications.py
  • test/functional/wallet_basic.py
  • src/wallet/wallet.cpp

Walkthrough

This PR removes the -rescan startup option, adds wallet::DBErrors::NEED_RESCAN, tracks rescan_required during wallet DB load, propagates that flag through CWallet::Create into CWallet::AttachChain (which now accepts rescan_required), and updates CLI/help/docs/RPC/tool/tests to use rescanblockchain for manual rescans.

Sequence Diagram(s)

sequenceDiagram
  participant WalletBatch
  participant CWalletCreate
  participant CWalletAttach
  participant Chain
  WalletBatch->>CWalletCreate: return DBErrors::NEED_RESCAN
  CWalletCreate->>CWalletAttach: AttachChain(rescan_required=true)
  CWalletAttach->>Chain: set rescan_height = 0 (full rescan from genesis)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • UdjinM6
  • PastaPastaPasta
  • thepastaclaw
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: removal of the -rescan startup parameter as part of backporting breaking changes for Dash Core v24.
Description check ✅ Passed The description is directly related to the changeset, explaining the removal of -rescan, automatic rescans for corruption, and the rescanblockchain RPC alternative.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Infer (1.2.0)
src/wallet/rpc/backup.cpp

src/wallet/rpc/backup.cpp:6:10: fatal error: 'chain.h' file not found
6 | #include <chain.h>
| ^~~~~~~~~
1 error generated.
src/wallet/rpc/backup.cpp:1249:28-1297:5: ERROR translating statement 'CompoundStmt'
Aborting translation of method 'wallet::ProcessImportLegacy' in file 'src/wallet/rpc/backup.cpp': "Assert_failure src/clang/cAst_utils.ml:249:53"
Uncaught Internal Error: "Assert_failure src/clang/cAst_utils.ml:249:53"
Error backtrace:
Raised at ClangFrontend__CAst_utils.get_decl_from_typ_ptr in file "src/clang/cAst_utils.ml", line 249, characters 53-65
Called from ClangFrontend__CTrans.CTrans_funct.get_destructor_decl_ref in file "src/clang/cTrans.ml", line 658, characters 12-59
Called from ClangFrontend__CTrans.CTrans_funct.destructor_calls.(fun) in file "src/clang/cTrans.ml", line 2048, characters 12-69
Called from Base__List.rev_filter_map.loop in file "src/list.ml", line 944, characters 13-17
Called from Base__List.filter_map in file "src/list.ml" (inlined)

... [truncated 2200 characters] ...

langFrontend__CTrans.CTrans_funct.instruction_insert_cxx_temporary_markers in file "src/clang/cTrans.ml", line 4866, characters 22-60
Called from ClangFrontend__CTrans.CTrans_funct.instruction_scope in file "src/clang/cTrans.ml", line 4850, characters 22-79
Called from ClangFrontend__CTrans.CTrans_funct.instruction_log.(fun) in file "src/clang/cTrans.ml", line 4782, characters 12-47
Re-raised at IStdlib__IExn.reraise_after in file "src/istd/IExn.ml" (inlined), line 13, characters 2-50
Called from ClangFrontend__CTrans.CTrans_funct.instruction_log.(fun) in file "src/clang/cTrans.ml", line 4784, characters 10-1023
Called from ClangFrontend__CTrans.CTrans_funct.instruction in file "src/clang/cTrans.ml" (inlined), line 4765, characters 38-71
Called from ClangFrontend__CTrans.CTrans_funct.exec_

src/wallet/rpc/wallet.cpp

src/wallet/rpc/wallet.cpp:7:10: fatal error: 'chainparams.h' file not found
7 | #include <chainparams.h>
| ^~~~~~~~~~~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/2970303a87b4432109e076a19f060b7464c3309b-7b13e03c457b6225/tmp/clang_command_.tmp.146002.txt
++Contents of '/tmp/coderabbit-infer/2970303a87b4432109e076a19f060b7464c3309b-7b13e03c457b6225/tmp/clang_command_.tmp.146002.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=65535" "-cc1" "-triple"
"x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "-disable-free"

... [truncated 1061 characters] ...

g/install/lib/clang/18/include"
"-internal-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-fdeprecated-macro" "-ferror-limit" "19" "-fgnuc-version=4.2.1"
"-fskip-odr-check-in-gmf" "-fcxx-exceptions" "-fexceptions"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/7b13e03c457b6225/file.o" "-x" "c++"
"src/wallet/rpc/wallet.cpp" "-O0" "-fno-builtin" "-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"

src/wallet/salvage.cpp

src/wallet/salvage.cpp:6:10: fatal error: 'fs.h' file not found
6 | #include <fs.h>
| ^~~~~~
1 error generated.
Error: the following clang command did not run successfully:
/opt/infer-linux-x86_64-v1.2.0/lib/infer/facebook-clang-plugins/clang/install/bin/clang-18
@/tmp/coderabbit-infer/2970303a87b4432109e076a19f060b7464c3309b-f2ce86303db55433/tmp/clang_command_.tmp.d1955c.txt
++Contents of '/tmp/coderabbit-infer/2970303a87b4432109e076a19f060b7464c3309b-f2ce86303db55433/tmp/clang_command_.tmp.d1955c.txt':
"-cc1" "-load"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../../facebook-clang-plugins/libtooling/build/FacebookClangPlugin.dylib"
"-add-plugin" "BiniouASTExporter" "-plugin-arg-BiniouASTExporter" "-"
"-plugin-arg-BiniouASTExporter" "PREPEND_CURRENT_DIR=1"
"-plugin-arg-BiniouASTExporter" "MAX_STRING_SIZE=65535" "-cc1" "-triple"
"x86_64-unknown-linux-gnu" "-emit-obj" "-mrelax-all" "-disable-free"
"-clear-ast-before-backen

... [truncated 1029 characters] ...

lang/install/lib/clang/18/include"
"-internal-isystem" "/usr/local/include" "-internal-isystem"
"/usr/lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include"
"-internal-externc-isystem" "/usr/include/x86_64-linux-gnu"
"-internal-externc-isystem" "/include" "-internal-externc-isystem"
"/usr/include" "-Wno-ignored-optimization-argument" "-Wno-everything"
"-fdeprecated-macro" "-ferror-limit" "19" "-fgnuc-version=4.2.1"
"-fskip-odr-check-in-gmf" "-fcxx-exceptions" "-fexceptions"
"-D__GCC_HAVE_DWARF2_CFI_ASM=1" "-o"
"/tmp/coderabbit-infer/f2ce86303db55433/file.o" "-x" "c++"
"src/wallet/salvage.cpp" "-O0" "-fno-builtin" "-include"
"/opt/infer-linux-x86_64-v1.2.0/lib/infer/infer/bin/../lib/clang_wrappers/global_defines.h"
"-Wno-everything"

  • 5 others

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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/wallet/wallet.cpp (1)

3504-3516: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Honor rescan_required when choosing the scan start.

Line 3507 still gates the birthday optimization on -rescan, but this PR removes that option. As written, the condition is effectively always true, so a wallet loaded with DBErrors::NEED_RESCAN can still skip forward to time_first_key instead of doing the intended full rescan from genesis.

Suggested fix
-        // No need to read and scan block if block was created before
-        // our wallet birthday (as adjusted for block time variability)
-        // unless a full rescan was requested
-        if (gArgs.GetIntArg("-rescan", 0) != 2) {
+        // No need to read and scan blocks created before the wallet birthday
+        // (as adjusted for block time variability), unless a full rescan was
+        // requested due to load-time corruption.
+        if (!rescan_required) {
             std::optional<int64_t> time_first_key;
             for (auto spk_man : walletInstance->GetAllScriptPubKeyMans()) {
                 int64_t time = spk_man->GetTimeFirstKey();
                 if (!time_first_key || time < *time_first_key) time_first_key = time;
             }
             if (time_first_key) {
                 chain.findFirstBlockWithTimeAndHeight(*time_first_key - TIMESTAMP_WINDOW, rescan_height, FoundBlock().height(rescan_height));
             }
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/wallet/wallet.cpp` around lines 3504 - 3516, The birthday-based
scan-start optimization currently checks gArgs.GetIntArg("-rescan", 0) instead
of honoring the wallet's rescan_required state, so a wallet flagged with
NEED_RESCAN can still use time_first_key; change the condition to consult
walletInstance->IsRescanRequired() (or the rescan_required flag) and skip the
birthday shortcut when rescan is required: compute time_first_key via
GetTimeFirstKey on each spk_man, and only call
chain.findFirstBlockWithTimeAndHeight(*time_first_key - TIMESTAMP_WINDOW,
rescan_height, FoundBlock().height(rescan_height)) when rescan_required is false
(or IsRescanRequired() returns false), otherwise preserve full
rescan-from-genesis behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/wallet/wallettool.cpp`:
- Around line 95-98: The branch that handles DBErrors::NEED_RESCAN logs an error
but does not stop wallet creation; update the MakeWallet() handling so that when
load_wallet_ret == DBErrors::NEED_RESCAN it returns/aborts immediately like
other fatal load states (e.g., return nullptr or propagate the failure) instead
of continuing. Locate the branch in wallettool.cpp where load_wallet_ret is
compared to DBErrors::NEED_RESCAN and change control flow to exit the function
early after logging (refer to the existing non-recoverable error branches in
MakeWallet() for the exact return behavior to mirror).

---

Outside diff comments:
In `@src/wallet/wallet.cpp`:
- Around line 3504-3516: The birthday-based scan-start optimization currently
checks gArgs.GetIntArg("-rescan", 0) instead of honoring the wallet's
rescan_required state, so a wallet flagged with NEED_RESCAN can still use
time_first_key; change the condition to consult
walletInstance->IsRescanRequired() (or the rescan_required flag) and skip the
birthday shortcut when rescan is required: compute time_first_key via
GetTimeFirstKey on each spk_man, and only call
chain.findFirstBlockWithTimeAndHeight(*time_first_key - TIMESTAMP_WINDOW,
rescan_height, FoundBlock().height(rescan_height)) when rescan_required is false
(or IsRescanRequired() returns false), otherwise preserve full
rescan-from-genesis behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3a24a618-4273-4ee7-b018-2551e111a833

📥 Commits

Reviewing files that changed from the base of the PR and between 0f3a2fe and e29ed01.

📒 Files selected for processing (17)
  • doc/release-notes-remove-rescan.md
  • src/dummywallet.cpp
  • src/init.cpp
  • src/wallet/init.cpp
  • src/wallet/rpc/backup.cpp
  • src/wallet/rpc/wallet.cpp
  • src/wallet/salvage.cpp
  • src/wallet/test/wallet_tests.cpp
  • src/wallet/wallet.cpp
  • src/wallet/wallet.h
  • src/wallet/walletdb.cpp
  • src/wallet/walletdb.h
  • src/wallet/wallettool.cpp
  • test/functional/feature_notifications.py
  • test/functional/wallet_basic.py
  • test/functional/wallet_hd.py
  • test/functional/wallet_upgradetohd.py
💤 Files with no reviewable changes (2)
  • src/wallet/init.cpp
  • src/dummywallet.cpp

Comment thread src/wallet/wallettool.cpp
@thepastaclaw

thepastaclaw commented Jun 3, 2026

Copy link
Copy Markdown

✅ Review complete (commit 2970303)

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

Backport of bitcoin#23123 (remove -rescan startup parameter) and bitcoin#23147 (rename DBErrors::RESCAN_REQUIRED to NEED_RESCAN) is structurally sound. Upstream API changes are correctly carried through (DBErrors::NEED_RESCAN, AttachChain(rescan_required, ...), gArgs removal). No blocking issues. Several Dash-specific adaptation cleanups remain: two leftover code blocks that still read the now-removed -rescan arg (always dead), a behavior-broadening fall-through in CWallet::LoadWallet, stale manpage text, and minor test-adaptation hygiene.

🟡 4 suggestion(s) | 💬 2 nitpick(s)

3 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/init.cpp`:
- [SUGGESTION] src/wallet/init.cpp:155-160: Dead `-rescan` mode validation after argument removal
  This Dash-specific block validates `-rescan` as an integer mode (0/1/2), but this PR removes the `-rescan` argument registration in `src/wallet/init.cpp` and `src/dummywallet.cpp`. With the arg no longer registered, `gArgs.GetIntArg("-rescan", 0)` returns the default 0, the `rescan_mode < 0 || rescan_mode > 2` condition is always false, and the warning plus `ForceRemoveArg` are unreachable. Delete the block to avoid misleading readers into thinking `-rescan=1|2` is still supported.

In `src/wallet/wallet.cpp`:
- [SUGGESTION] src/wallet/wallet.cpp:3507-3516: Dead `-rescan=2` (full-genesis) branch after argument removal
  This Dash-specific guard `if (gArgs.GetIntArg("-rescan", 0) != 2)` previously gave users `-rescan=2` to force a rescan from genesis (bypassing the wallet-birthday optimization). With `-rescan` removed by this PR, `GetIntArg("-rescan", 0)` is always 0, the condition is always true, and the implicit `else` (full-genesis) branch is dead. Functionally fine — `NEED_RESCAN`-driven rescans correctly use the birthday optimization — but the conditional misleads readers into thinking a removed CLI mode is still honored. Drop the `if`.
- [SUGGESTION] src/wallet/wallet.cpp:2439-2447: LoadWallet: removing the early-return broadens fall-through to all non-LOAD_OK results
  The merge removes the pre-existing Dash guard `if (nLoadWalletRet != DBErrors::LOAD_OK) return nLoadWalletRet;` so the new `NEED_RESCAN` result can propagate to `CWallet::Create`. That intent is correct, but the change also makes every other non-OK result (`CORRUPT`, `TOO_NEW`, `NEED_REWRITE`, `EXTERNAL_SIGNER_SUPPORT_REQUIRED`, `NONCRITICAL_ERROR`, ...) fall through into the Dash-only CoinJoin salt write. If `SetCoinJoinSalt` fails on a wallet that is already corrupt/unusable, `LoadWallet` returns `DBErrors::LOAD_FAIL`, shadowing the more specific error code that `CWallet::Create` keys its user-facing message off (e.g. "Wallet corrupted" becomes generic "Error loading..."). Narrow the gate so only `LOAD_OK` and `NEED_RESCAN` reach the salt block.

In `doc/man/dashd.1`:
- [SUGGESTION] doc/man/dashd.1:152: Shipped manpages still advertise the removed `-rescan` option
  After this PR `dashd` rejects `-rescan` on the command line and `rescan=` in the config as an unknown option. The packaged manpages still mention `-rescan` here and document `-rescan=<mode>` at `doc/man/dashd.1:554-557`; the same stale text exists in `doc/man/dash-qt.1`. Operators with `rescan=1` or `rescan=2` in `dash.conf` will hit a startup failure and the docs will mislead them. Note: this repo normally regenerates manpages at release-prep time (see `chore: regenerate manpages for v23.1.2`), so deferring to the release commit is acceptable — flagging so the regeneration isn't forgotten.

Comment thread src/wallet/wallet.cpp
Comment thread test/functional/feature_notifications.py
Comment thread doc/release-notes-remove-rescan.md Outdated
@knst knst force-pushed the bp-breaking-to-v24 branch from e29ed01 to fdaf1e4 Compare June 3, 2026 19:35

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

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

⚠️ Outside diff range comments (1)
src/wallet/walletdb.cpp (1)

880-890: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Route duplicate-TX corruption into NEED_RESCAN.

ReadKeyValue() marks wss.tx_corrupt for duplicate wallet transaction records and documents that the wallet can be repaired by rescanning, but this branch still sets DBErrors::CORRUPT. That prevents the new NEED_RESCAN path from ever reaching CWallet::Create() for this recoverable corruption case, so startup aborts instead of performing the deferred rescan this PR is adding.

Suggested fix
-                } else if (wss.tx_corrupt) {
+                } else if (wss.tx_corrupt) {
                     pwallet->WalletLogPrintf("Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.\n");
                     // Set tx_corrupt back to false so that the error is only printed once (per corrupt tx)
                     wss.tx_corrupt = false;
-                    result = DBErrors::CORRUPT;
+                    fNoncriticalErrors = true;
+                    rescan_required = true;
                 } else {

Also applies to: 954-958

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/wallet/walletdb.cpp` around lines 880 - 890, ReadKeyValue() currently
treats wss.tx_corrupt (duplicate TX records) as a hard CORRUPT error which
prevents the new deferred rescan path; change the branch that checks
wss.tx_corrupt in walletdb.cpp so that for DBKeys::TX it sets the result to
DBErrors::NEED_RESCAN (and sets rescan_required / leave fNoncriticalErrors
behavior) instead of DBErrors::CORRUPT, ensuring duplicate-TX corruption flows
into the rescan path in CWallet::Create(); update the identical handling at the
other occurrence (lines noted in review) to match.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/wallet/walletdb.cpp`:
- Around line 880-890: ReadKeyValue() currently treats wss.tx_corrupt (duplicate
TX records) as a hard CORRUPT error which prevents the new deferred rescan path;
change the branch that checks wss.tx_corrupt in walletdb.cpp so that for
DBKeys::TX it sets the result to DBErrors::NEED_RESCAN (and sets rescan_required
/ leave fNoncriticalErrors behavior) instead of DBErrors::CORRUPT, ensuring
duplicate-TX corruption flows into the rescan path in CWallet::Create(); update
the identical handling at the other occurrence (lines noted in review) to match.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b4867704-53d6-47b5-9d2f-758af312daf2

📥 Commits

Reviewing files that changed from the base of the PR and between e29ed01 and fdaf1e4.

📒 Files selected for processing (17)
  • doc/release-notes-remove-rescan.md
  • src/dummywallet.cpp
  • src/init.cpp
  • src/wallet/init.cpp
  • src/wallet/rpc/backup.cpp
  • src/wallet/rpc/wallet.cpp
  • src/wallet/salvage.cpp
  • src/wallet/test/wallet_tests.cpp
  • src/wallet/wallet.cpp
  • src/wallet/wallet.h
  • src/wallet/walletdb.cpp
  • src/wallet/walletdb.h
  • src/wallet/wallettool.cpp
  • test/functional/feature_notifications.py
  • test/functional/wallet_basic.py
  • test/functional/wallet_hd.py
  • test/functional/wallet_upgradetohd.py
💤 Files with no reviewable changes (2)
  • src/dummywallet.cpp
  • src/wallet/init.cpp
✅ Files skipped from review due to trivial changes (5)
  • src/wallet/salvage.cpp
  • src/init.cpp
  • src/wallet/test/wallet_tests.cpp
  • doc/release-notes-remove-rescan.md
  • src/wallet/rpc/backup.cpp
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/wallet/rpc/wallet.cpp
  • test/functional/wallet_hd.py
  • src/wallet/wallet.h
  • src/wallet/wallettool.cpp
  • test/functional/wallet_upgradetohd.py
  • test/functional/wallet_basic.py
  • test/functional/feature_notifications.py

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

Incremental review at fdaf1e4. The latest delta (e29ed01..fdaf1e4) addresses two prior findings: prior-3 (CoinJoin salt write now gated on LOAD_OK at wallet.cpp:2443) and prior-6 (release-notes-remove-rescan.md now ends with a trailing newline). Four prior findings remain valid against the current head and are carried forward: two dead -rescan code paths (init.cpp validator, wallet.cpp -rescan=2 birthday-skip), shipped manpages still advertising the removed option, and a stale connect_nodes(0, 1) in feature_notifications.py. No new findings introduced in this delta.

🟡 3 suggestion(s)

3 additional finding(s) omitted (not in diff).

1 carried-forward finding(s) already raised on this PR; not re-posting as new inline comments.

🤖 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/init.cpp`:
- [SUGGESTION] src/wallet/init.cpp:155-160: Dead `-rescan` mode validation after argument removal (carried forward)
  Carried forward from prior-1. This PR removes the `-rescan` argument registration (verified: no `AddArg("-rescan", ...)` remains anywhere in `src/`). Consequently `gArgs.GetIntArg("-rescan", 0)` here always returns the default 0, so `rescan_mode < 0 || rescan_mode > 2` can never trigger and the `InitWarning`/`ForceRemoveArg` paths are unreachable. Worse, if a user actually passes `-rescan=...`, argument parsing now rejects it as unknown before this validator ever runs, so the warning would be misleading even hypothetically. Removing the block keeps the PR's argument-removal story internally consistent.

In `src/wallet/wallet.cpp`:
- [SUGGESTION] src/wallet/wallet.cpp:3504-3516: Dead `-rescan=2` (full-genesis) branch after argument removal (carried forward)
  Carried forward from prior-2. With `-rescan` removed, `gArgs.GetIntArg("-rescan", 0) != 2` is now always true, so the birthday-shortcut always runs — including on the new corruption-driven `NEED_RESCAN` path introduced by this PR. The release notes promise that wallets requiring rescanning due to corruption will still be rescanned on startup; previously a user could force a from-genesis rescan via `-rescan=2`, but now even corruption recovery silently advances `rescan_height` to the wallet birthday. Either gate the birthday optimization on `!rescan_required` so `NEED_RESCAN` truly scans from genesis, or otherwise preserve a real full-genesis path for the corruption case. The removed startup arg cannot remain the gate.

In `doc/man/dashd.1`:
- [SUGGESTION] doc/man/dashd.1:152-557: Shipped manpages still advertise the removed `-rescan` option (carried forward)
  Carried forward from prior-4. After this PR, `dashd` rejects `-rescan` on the command line and `rescan=` in config as unknown, but `doc/man/dashd.1` still references `-rescan` at line 152 (in the `-prune` incompatibility note) and fully documents `-rescan=<mode>` at lines 554-557. The mirror entries in `doc/man/dash-qt.1` are similarly stale. Manpages are autogenerated, so the release-time regeneration step will pick this up, but flagging here so the release engineer doesn't miss it — operators consulting installed manpages will otherwise be directed to a flag that now causes startup to fail.

@github-actions

github-actions Bot commented Jun 5, 2026

Copy link
Copy Markdown

This pull request has conflicts, please rebase.

@knst knst force-pushed the bp-breaking-to-v24 branch from fdaf1e4 to 0adc5f1 Compare June 8, 2026 13:05
knst and others added 2 commits June 8, 2026 20:06
dc3ec74 Add rescan removal release note (Samuel Dobson)
bccd1d9 Remove -rescan startup parameter (Samuel Dobson)
f963b0f Corrupt wallet tx shouldn't trigger rescan of all wallets (Samuel Dobson)
6c00649 Remove outdated dummy wallet -salvagewallet arg (Samuel Dobson)

Pull request description:

  Remove the `-rescan` startup parameter.

  Rescans can be run with the `rescanblockchain` RPC.

  Rescans are still done on wallet-load if needed due to corruption, for example.

ACKs for top commit:
  achow101:
    ACK dc3ec74
  laanwj:
    re-ACK dc3ec74

Tree-SHA512: 608360d0e7d73737fd3ef408b01b33d97a75eebccd70c6d1b47a32fecb99b9105b520b111b225beb10611c09aa840a2b6d2b6e6e54be5d0362829e757289de5c

Co-authored-by: W. J. van der Laan <laanwj@protonmail.com>
…ED_RESCAN

8615507 scripted-diff: rename DBErrors::RESCAN_REQUIRED to NEED_RESCAN (Samuel Dobson)

Pull request description:

  Suggested here as a trivial follow-up: bitcoin#23123 (comment)

  Makes RESCAN_REQUIRED consistent with NEED_REWRITE

ACKs for top commit:
  achow101:
    ACK 8615507
  jonatack:
    ACK 8615507

Tree-SHA512: 82d057c45e192cd6dd8a47675b52699e6cbc82272609a971e6e5d6796aad14a941a70e40d3913dbb611f79c8eadff8030c60ea6f203f2edc3720c0e78c166b97

Co-authored-by: fanquake <fanquake@gmail.com>
@knst knst force-pushed the bp-breaking-to-v24 branch from 0adc5f1 to 2970303 Compare June 8, 2026 13:06

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

PR #7037 backports bitcoin#23123 (remove -rescan startup parameter) and bitcoin#23147 (rename DBErrors::RESCAN_REQUIRED to NEED_RESCAN). The latest delta (fdaf1e4..2970303) adds nothing new beyond those two merge commits. All four prior findings remain valid on the current head and are carried forward; nothing was fixed. No new in-scope blocking issues were introduced. Codex-general's two new findings about src/txdb.cpp (legacy index migration) and src/masternode/payments.cpp (old-budget validation) target files modified by earlier unrelated develop merges (#7101 and masternode reward share commits), not by this PR — they are dropped as out-of-scope.

🟡 3 suggestion(s)

3 additional finding(s) omitted (not in diff).

1 carried-forward finding(s) already raised on this PR; not re-posting as new inline comments.

🤖 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/init.cpp`:
- [SUGGESTION] src/wallet/init.cpp:155-160: Dead -rescan mode validation after argument removal (carried forward from prior-1)
  Carried forward from prior-1 — still valid at 2970303a. This PR removes the `-rescan` argument registration from `WalletInit::AddWalletOptions`, and no `AddArg("-rescan", ...)` remains anywhere under `src/`. Because `-rescan` is no longer recognized, `gArgs.GetIntArg("-rescan", 0)` always returns the default 0 here, so `rescan_mode < 0 || rescan_mode > 2` can never be true and the warning, init-warning, and `ForceRemoveArg("rescan")` block is unreachable. This is Dash-specific residue from the older numeric `-rescan` mode that upstream bitcoin#23123 did not have. Removing it also retires the orphaned translated string `"Incorrect -rescan mode, falling back to default value"` in `src/qt/dashstrings.cpp`.

In `src/wallet/wallet.cpp`:
- [SUGGESTION] src/wallet/wallet.cpp:3468-3489: Dead `-rescan != 2` gate around the birthday shortcut (carried forward from prior-2)
  Carried forward from prior-2 — still valid at 2970303a. The `if (gArgs.GetIntArg("-rescan", 0) != 2)` predicate at line 3473 is a Dash-only construct (upstream's `-rescan` was boolean and had no such gate). With the startup `-rescan` registration removed in this PR, the predicate is always true, so the birthday-shortcut now runs unconditionally — including on the corruption-driven `NEED_RESCAN` path that this PR introduces by setting `rescan_height = 0` in `CWallet::Create`. Functionally this matches upstream post-bitcoin#23123 behaviour, so it is not a regression vs. upstream, but it is dead code that misleadingly hints at a `-rescan=2` full-genesis mode. Either drop the predicate so the birthday-shortcut block is plain code, or, if the PR's release-note promise that "wallets which require rescanning due to corruption will still be rescanned" is meant to imply true genesis recovery, gate it on `!rescan_required` instead so the corruption path skips the birthday optimisation.

In `doc/man/dashd.1`:
- [SUGGESTION] doc/man/dashd.1:152-556: Shipped manpages still advertise the removed -rescan option (carried forward from prior-3)
  Carried forward from prior-3 — still valid at 2970303a. After this PR, `dashd` rejects `-rescan` on the command line and `rescan=` in the config as an unknown argument, but `doc/man/dashd.1` still references `-rescan` in the `-prune` incompatibility note (line 152) and fully documents `-rescan=<mode>` (line 554). The same stale entries exist in `doc/man/dash-qt.1`. These files carry a `help2man`-generated banner and are regenerated via `contrib/devtools/gen-manpages.py` at release time, so they will refresh out-of-band; flagging here so the release manager catches the regeneration rather than shipping documentation for a removed option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

RPC Some notable changes to RPC params/behaviour/descriptions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants