Skip to content

Conversation

@kwvg
Copy link
Collaborator

@kwvg kwvg commented Jun 24, 2025

Additional Information

  • When backporting bitcoin#23497 (see dash#6732), some BOOST_AUTO_TEST_SUITE_END()s were placed outside the wallet namespace scope, which resulted in incorrect behavior when rebasing this pull request over dash#6732. This has been resolved.

  • Backports of bitcoin#25083 and bitcoin#25005 do not include changes to wallet/rpc/spend.cpp as the sendall() RPC has not been implemented in develop (f453998) as of this writing.

  • Backporting bitcoin#24236 required a fair number of additional considerations, firstly because the pull request introduces a test, feature_unsupported_utxo_db.py, that requires the last-capable of version Dash Core to generate a legacy UTXO database (the current database format debuted in dash#1701, included in v0.12.2.2) and secondly, because v0.15 is the earliest expected version of Dash Core to work smoothly with our test framework (source).

    As we require the last release cycle that generates the legacy UTXO database by default, we used the last version of the v0.12.1.x family, v0.12.1.5 as the old node used in feature_unsupported_utxo_db.py. This brings unique challenges which are elaborated on below.

    • The test framework relies on generatetoaddress, a wallet-independent RPC call that was introduced in bitcoin#7671 to replace the old wallet-dependent generate RPC. It was backported as 760d58e in dash#1790 and debuted in v0.12.3. We cannot use the self.generate() helper as simply dispatches a generatetoaddress (source), which does not exist in v0.12.1.5.

      We work around this by using the more archaic self.nodes[0].rpc.generate(), in line with usage in rpc_generate.py (source).

    • Releases before v0.12.3.x did not include the target triples in their naming convention (see tag v0.12.3.1 vs v0.12.1.5), which causes problems when fetching packages based on the target HOST of the build environment. This has been remedied by introducing awareness for RPi2, osx and linux{32,64} labels.

      • Note, RPi2 corresponds to arm-linux-gnueabihf based on the Gitian descriptor that was removed in dash#2183 (source)
    • This was also taken as an opportunity to introduce awareness for the win32 and win64 labels which persist even now (see tag v22.1.2)

    • Currently, when we want to make RPC calls without arguments, a blank object is sent to by the RPC dispatcher. This is acceptable as objects are supported since bitcoin#8811 (backported as eb7a6b0 in dash#1851), included in v0.12.3.

      Unfortunately, since we are dealing with a version of Dash that is ancient even by previous release standards, this prevents the dispatcher from even acknowledging the RPC server is active (see below).

      Test failure:
      $ ./test/functional/feature_unsupported_utxo_db.py
      2025-06-24T15:06:53.642000Z TestFramework (INFO): PRNG seed is: 1995903613070947610
      2025-06-24T15:06:53.642000Z TestFramework (INFO): Initializing test directory /tmp/dash_func_test_1tqzf43o
      2025-06-24T15:06:53.642000Z TestFramework (INFO): Create previous version (v0.12.1.5) utxo db
      2025-06-24T15:06:53.895000Z TestFramework (ERROR): JSONRPC error
      Traceback (most recent call last):
        File "/home/eclair/Repositories/dashpay/dash/test/functional/test_framework/test_framework.py", line 161, in main
          self.run_test()
        File "/home/eclair/Repositories/dashpay/dash/./test/functional/feature_unsupported_utxo_db.py", line 35, in run_test
          self.start_node(0)
        File "/home/eclair/Repositories/dashpay/dash/test/functional/test_framework/test_framework.py", line 647, in start_node
          node.wait_for_rpc_connection()
        File "/home/eclair/Repositories/dashpay/dash/test/functional/test_framework/test_node.py", line 276, in wait_for_rpc_connection
          rpc.getblockcount()
        File "/home/eclair/Repositories/dashpay/dash/test/functional/test_framework/coverage.py", line 49, in __call__
          return_val = self.auth_service_proxy_instance.__call__(*args, **kwargs)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/eclair/Repositories/dashpay/dash/test/functional/test_framework/authproxy.py", line 144, in __call__
          raise JSONRPCException(response['error'], status)
      test_framework.authproxy.JSONRPCException: Params must be an array (-32600)
      2025-06-24T15:06:53.947000Z TestFramework (INFO): Stopping nodes
      [...]
      
      • This is worked around by dispatching an empty array instead of an empty object, it has the same practical effect (conveying the lack of arguments) and is forwards-compatible.
    • Currently, the password used for RPC authentication in Base16 encoded. This is a result of dash#1454, which switched away from Base64. Unfortunately, this benefit only extends to v0.12.2.0 onwards, which is too new for the old node needed in our functional test.

      Worse still, it was not the URL-safe variant of Base64, so attempting to establish a connection with the old node resulted in sporadic failures (see below).

      Test failure:
      $ ./test/functional/feature_unsupported_utxo_db.py
      2025-06-24T15:13:27.517000Z TestFramework (INFO): PRNG seed is: 3228606794541395700
      2025-06-24T15:13:27.518000Z TestFramework (INFO): Initializing test directory /tmp/dash_func_test_97d987gf
      2025-06-24T15:13:27.518000Z TestFramework (INFO): Create previous version (v0.12.1.5) utxo db
      2025-06-24T15:13:27.769000Z TestFramework (ERROR): Unexpected exception caught during testing
      Traceback (most recent call last):
        File "/home/eclair/Repositories/dashpay/dash/test/functional/test_framework/test_framework.py", line 161, in main
          self.run_test()
        File "/home/eclair/Repositories/dashpay/dash/./test/functional/feature_unsupported_utxo_db.py", line 35, in run_test
          self.start_node(0)
        File "/home/eclair/Repositories/dashpay/dash/test/functional/test_framework/test_framework.py", line 647, in start_node
          node.wait_for_rpc_connection()
        File "/home/eclair/Repositories/dashpay/dash/test/functional/test_framework/test_node.py", line 270, in wait_for_rpc_connection
          rpc = get_rpc_proxy(
                ^^^^^^^^^^^^^^
        File "/home/eclair/Repositories/dashpay/dash/test/functional/test_framework/util.py", line 341, in get_rpc_proxy
          proxy = AuthServiceProxy(url, **proxy_kwargs)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/home/eclair/Repositories/dashpay/dash/test/functional/test_framework/authproxy.py", line 78, in __init__
          authpair = user + b':' + passwd
                    ~~~~~^~~~~~
      TypeError: unsupported operand type(s) for +: 'NoneType' and 'bytes'
      2025-06-24T15:13:27.822000Z TestFramework (INFO): Stopping nodes
      [...]
      
      • This is worked around by escaping URL special characters for the password field. It is practically a no-op for the Base16 passwords generated from v0.12.2.0 onwards but allows connection and authentication with older versions of Dash Core.

How Has This Been Tested?

A full CoinJoin session run on 89cd497

CoinJoin session run on build 89cd4978c141

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
  • 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 milestone Jun 24, 2025
@kwvg kwvg changed the title backport: merge bitcoin#24711, #24666, #25083, #25005, #24236, #25438, #25036, #25489, #25544, #25594, #13226, partial bitcoin#25218, #26005 (wallet backports: part 6) backport: merge bitcoin#24711, #24666, #25083, #25005, #25410, #24236, #25438, #25036, #25489, #25544, #25594, #13226, partial bitcoin#25218, #26005 (wallet backports: part 6) Jun 24, 2025
@kwvg kwvg marked this pull request as ready for review June 24, 2025 21:16
@kwvg kwvg requested review from PastaPastaPasta, UdjinM6 and knst June 24, 2025 21:17
@coderabbitai
Copy link

coderabbitai bot commented Jun 24, 2025

Walkthrough

This set of changes introduces significant refactoring and new functionality across the wallet, coin selection, database, and testing components. The wallet code now uses unified interfaces for checking spent and locked coins via COutPoint and script parameters, and introduces a centralized NotifyWalletLoaded function for wallet load notifications. The coin selection logic is updated to use a new COutput struct with explicit fee and effective value handling, and coin selection functions now return a CoinsResult struct encapsulating both outputs and total amounts. The legacy UTXO database upgrade logic is removed, replaced with a check for unsupported formats, and a new functional test (feature_unsupported_utxo_db.py) ensures that loading such legacy databases fails with a clear error and recovery instruction. The wallet rescan logic gains a save_progress parameter for improved progress persistence. Error handling in wallet restoration is unified using a new BResult<T> result type. The test framework and compatibility scripts are updated to support and test against older releases, particularly v0.12.1.5, including adjustments for legacy RPC and authentication behaviors. Public interfaces in headers are updated to reflect these changes, and corresponding tests are enhanced or added to verify new behaviors and error handling.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 640c2b6 and 175970e.

📒 Files selected for processing (47)
  • ci/test/00_setup_env_native_qt5.sh (1 hunks)
  • src/Makefile.am (1 hunks)
  • src/bench/coin_selection.cpp (2 hunks)
  • src/coinjoin/client.cpp (1 hunks)
  • src/coinjoin/util.h (1 hunks)
  • src/coins.h (0 hunks)
  • src/dbwrapper.h (0 hunks)
  • src/init.cpp (1 hunks)
  • src/interfaces/chain.h (1 hunks)
  • src/interfaces/wallet.h (2 hunks)
  • src/node/chainstate.cpp (1 hunks)
  • src/node/interfaces.cpp (4 hunks)
  • src/qt/coincontroldialog.cpp (1 hunks)
  • src/qt/test/wallettests.cpp (1 hunks)
  • src/qt/walletcontroller.cpp (1 hunks)
  • src/qt/walletmodel.h (1 hunks)
  • src/rpc/evo.cpp (2 hunks)
  • src/rpc/masternode.cpp (1 hunks)
  • src/txdb.cpp (3 hunks)
  • src/txdb.h (1 hunks)
  • src/util/result.h (1 hunks)
  • src/wallet/coincontrol.cpp (1 hunks)
  • src/wallet/coinjoin.cpp (7 hunks)
  • src/wallet/coinselection.cpp (6 hunks)
  • src/wallet/coinselection.h (2 hunks)
  • src/wallet/interfaces.cpp (4 hunks)
  • src/wallet/load.cpp (1 hunks)
  • src/wallet/receive.cpp (4 hunks)
  • src/wallet/rpc/backup.cpp (1 hunks)
  • src/wallet/rpc/coins.cpp (4 hunks)
  • src/wallet/rpc/transactions.cpp (1 hunks)
  • src/wallet/rpc/wallet.cpp (1 hunks)
  • src/wallet/spend.cpp (6 hunks)
  • src/wallet/spend.h (1 hunks)
  • src/wallet/test/bip39_tests.cpp (1 hunks)
  • src/wallet/test/coinjoin_tests.cpp (2 hunks)
  • src/wallet/test/coinselector_tests.cpp (10 hunks)
  • src/wallet/test/util.cpp (1 hunks)
  • src/wallet/test/wallet_tests.cpp (11 hunks)
  • src/wallet/wallet.cpp (15 hunks)
  • src/wallet/wallet.h (5 hunks)
  • test/README.md (1 hunks)
  • test/functional/feature_unsupported_utxo_db.py (1 hunks)
  • test/functional/test_framework/authproxy.py (2 hunks)
  • test/functional/test_framework/util.py (2 hunks)
  • test/functional/test_runner.py (1 hunks)
  • test/get_previous_releases.py (2 hunks)
💤 Files with no reviewable changes (2)
  • src/coins.h
  • src/dbwrapper.h
✅ Files skipped from review due to trivial changes (5)
  • src/coinjoin/util.h
  • src/wallet/test/bip39_tests.cpp
  • test/functional/test_runner.py
  • src/qt/coincontroldialog.cpp
  • test/functional/test_framework/util.py
🚧 Files skipped from review as they are similar to previous changes (38)
  • test/README.md
  • src/wallet/coincontrol.cpp
  • src/wallet/load.cpp
  • src/Makefile.am
  • src/txdb.h
  • src/bench/coin_selection.cpp
  • src/node/chainstate.cpp
  • src/qt/walletmodel.h
  • src/wallet/rpc/transactions.cpp
  • src/wallet/rpc/backup.cpp
  • src/rpc/masternode.cpp
  • src/wallet/test/coinjoin_tests.cpp
  • src/wallet/rpc/wallet.cpp
  • test/functional/test_framework/authproxy.py
  • src/interfaces/chain.h
  • src/init.cpp
  • ci/test/00_setup_env_native_qt5.sh
  • src/interfaces/wallet.h
  • src/rpc/evo.cpp
  • src/qt/walletcontroller.cpp
  • src/wallet/rpc/coins.cpp
  • test/functional/feature_unsupported_utxo_db.py
  • src/node/interfaces.cpp
  • src/wallet/receive.cpp
  • src/wallet/coinselection.cpp
  • src/wallet/interfaces.cpp
  • src/wallet/coinjoin.cpp
  • test/get_previous_releases.py
  • src/util/result.h
  • src/qt/test/wallettests.cpp
  • src/wallet/spend.h
  • src/wallet/coinselection.h
  • src/wallet/test/util.cpp
  • src/wallet/wallet.h
  • src/wallet/test/coinselector_tests.cpp
  • src/wallet/spend.cpp
  • src/coinjoin/client.cpp
  • src/wallet/wallet.cpp
🧰 Additional context used
📓 Path-based instructions (2)
src/**/*.{cpp,h,cc,cxx,hpp}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • CLAUDE.md
src/{test,wallet/test,qt/test}/**/*.{cpp,h,cc,cxx,hpp}

Instructions used from:

Sources:
📄 CodeRabbit Inference Engine

  • CLAUDE.md
🧠 Learnings (3)
📓 Common learnings
Learnt from: kwvg
PR: dashpay/dash#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
PR: dashpay/dash#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.
Learnt from: kwvg
PR: dashpay/dash#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.
Learnt from: CR
PR: dashpay/dash#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-10T16:26:00.371Z
Learning: Favor extension over modification of the Bitcoin Core foundation
src/wallet/test/wallet_tests.cpp (6)
Learnt from: kwvg
PR: dashpay/dash#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.
Learnt from: CR
PR: dashpay/dash#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-10T16:26:00.371Z
Learning: Applies to src/{test,wallet/test,qt/test}/**/*.{cpp,h,cc,cxx,hpp} : Unit tests should be implemented in src/test/, src/wallet/test/, and src/qt/test/ using Boost::Test or Qt 5 for GUI tests
Learnt from: kwvg
PR: dashpay/dash#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.
Learnt from: kwvg
PR: dashpay/dash#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
PR: dashpay/dash#6726
File: test/functional/rpc_createmultisig.py:120-120
Timestamp: 2025-06-20T23:32:16.225Z
Learning: In the rpc_createmultisig.py test, the checkbalances() function correctly excludes 9 blocks from the balance calculation: 8 blocks from do_multisig() calls (2 blocks per call × 4 calls) plus 1 block from checkbalances() itself.
Learnt from: kwvg
PR: dashpay/dash#6530
File: src/validation.cpp:360-362
Timestamp: 2025-01-14T08:37:16.955Z
Learning: The UpdateTransactionsFromBlock() method in txmempool.cpp takes parameters in the order: vHashUpdate, ancestor_size_limit, ancestor_count_limit. The size limit comes before the count limit.
src/txdb.cpp (3)
Learnt from: knst
PR: dashpay/dash#6511
File: src/evo/deterministicmns.cpp:1369-1373
Timestamp: 2025-01-07T18:50:44.838Z
Learning: The functions `MigrateDBIfNeeded` and `MigrateDBIfNeeded2` in `src/evo/deterministicmns.cpp` are temporary and will be removed in a future version. Refactoring suggestions for these functions should be avoided.
Learnt from: kwvg
PR: dashpay/dash#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
PR: dashpay/dash#6665
File: src/evo/providertx.h:82-82
Timestamp: 2025-06-06T11:53:09.094Z
Learning: In ProTx serialization code (SERIALIZE_METHODS), version checks should use hardcoded maximum flags (/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true) rather than deployment-based flags. This is because serialization code should be able to deserialize any structurally valid ProTx up to the maximum version the code knows how to handle, regardless of current consensus validity. Validation code, not serialization code, is responsible for checking whether a ProTx version is consensus-valid based on deployment status.
⏰ 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). (6)
  • GitHub Check: linux64_multiprocess-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: arm-linux-build / Build source
  • GitHub Check: x86_64-apple-darwin / Build depends
  • GitHub Check: x86_64-pc-linux-gnu / Build depends
🔇 Additional comments (10)
src/txdb.cpp (3)

34-34: Good organizational change moving deprecated constant.

Moving DB_COINS to the "Keys used in previous version" section properly reflects its deprecated status and improves code organization.


56-63: Simple and effective legacy database detection.

The NeedsUpgrade() method provides a clean way to detect legacy UTXO database entries without performing complex upgrade operations. The implementation correctly:

  • Uses RAII with unique_ptr for iterator management
  • Seeks to the deprecated DB_COINS key prefix
  • Returns a simple boolean indicating presence of legacy entries

This aligns well with the new approach of requiring external reindexing for unsupported database formats.


75-75: Cleanup indicates successful removal of legacy upgrade code.

The empty namespace closure confirms that the complex legacy upgrade logic (including the old CCoins class and Upgrade() method) has been successfully removed, simplifying the codebase maintenance.

src/wallet/test/wallet_tests.cpp (7)

70-70: LGTM! Proper integration of centralized wallet load notification.

The NotifyWalletLoaded call is correctly placed after adding the wallet to the context, ensuring proper notification ordering during wallet initialization.


131-131: LGTM! Correct adaptation to updated ScanForWalletTransactions API.

The addition of the save_progress parameter is consistent across all calls and appropriately set based on test requirements - false for basic scanning tests and true when testing progress persistence functionality.

Also applies to: 160-160, 195-195, 222-222, 1016-1016, 1456-1456


142-142: LGTM! Updated test utility usage.

The change from CreateDummyWalletDatabase() to CreateMockWalletDatabase() reflects updated test utilities and improved naming clarity.


150-152: LGTM! Enhanced testing with simulated time progression.

The fake time function setup enables deterministic testing of time-dependent behavior during wallet rescans. The 60-second increment provides reasonable time progression for test scenarios.


154-159: LGTM! Comprehensive testing of progress persistence.

The test correctly validates that best block information is not stored before scanning and is properly persisted when save_progress=true is used, providing good coverage of the new functionality.

Also applies to: 167-172


616-616: LGTM! Correct adaptation to updated coin listing API.

The changes properly use the new AvailableCoinsListUnspent function and access the .coins member of the returned CoinsResult structure, consistent with the wallet spend and coin selection refactors.

Also applies to: 627-627, 1305-1305, 1361-1361


70-70: Excellent test adaptation to wallet API changes.

The test updates comprehensively and consistently reflect the wallet subsystem refactoring:

  • Proper integration of centralized wallet load notifications
  • Correct usage of the new save_progress parameter in scan functions
  • Updated coin listing API usage with CoinsResult structure
  • Enhanced testing capabilities with fake time progression
  • Thorough validation of progress persistence functionality

All changes maintain existing test coverage while adapting to the new APIs, consistent with the backport's focus on refactoring without behavior changes.

Also applies to: 131-131, 142-142, 150-172, 195-195, 222-222, 616-616, 627-627, 1016-1016, 1305-1305, 1361-1361, 1456-1456

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 0

🧹 Nitpick comments (5)
src/Makefile.am (1)

370-370: Keep alphabetical ordering in BITCOIN_CORE_H for easier grepping

util/result.h was appended to the end of the block. For long, alphabetically-sorted lists like this one it is worth inserting the path at the right spot (util/ranges.h, util/readwritefile.h, util/result.h, util/ranges_set.h, …) to avoid duplicated entries and reduce merge-conflict friction.

src/qt/coincontroldialog.cpp (1)

22-23: <wallet/coinselection.h> appears to be unused

The translation unit already included <wallet/coincontrol.h> for the dialog’s existing logic, but I can’t find any direct usage of symbols from wallet/coinselection.h in this file. Dropping the include avoids an extra heavyweight header and reduces rebuild fan-out.

-#include <wallet/coincontrol.h>
-#include <wallet/coinselection.h>
+#include <wallet/coincontrol.h>

If forthcoming patches do need coinselection.h, ignore this note; otherwise please remove.

test/functional/test_framework/util.py (1)

368-368: Fix comment formatting and approve legacy compatibility enhancement.

The URL encoding of RPC passwords correctly addresses compatibility with legacy versions (v0.12.1.x and lower) that used URL-unsafe Base64 passwords.

Apply this diff to fix the comment formatting:

-    rpc_p = urllib.parse.quote(rpc_p, safe='') # v0.12.1.x and lower used URL unsafe Base64 for their passwords, quote it
+    rpc_p = urllib.parse.quote(rpc_p, safe='')  # v0.12.1.x and lower used URL unsafe Base64 for their passwords, quote it
src/wallet/coinselection.h (2)

21-28: Consider the design choice of struct with private members.

While the use of std::optional for calculated values is appropriate, having a struct with private members is unconventional. Structs typically have public members by default. Consider either:

  1. Keeping it as a class if you want private members with public accessors
  2. Making it a true POD struct with all public members

The current approach works but may surprise other developers.


101-111: Consider safer accessor patterns.

While the assertions ensure values are set, they could cause runtime crashes. Consider providing safer alternatives:

+    bool HasFee() const { return fee.has_value(); }
+    bool HasEffectiveValue() const { return effective_value.has_value(); }
+
     CAmount GetFee() const
     {
         assert(fee.has_value());
         return fee.value();
     }

This would allow callers to check before accessing, preventing potential crashes in production.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f453998 and 89cd497.

📒 Files selected for processing (46)
  • ci/test/00_setup_env_native_qt5.sh (1 hunks)
  • src/Makefile.am (1 hunks)
  • src/bench/coin_selection.cpp (2 hunks)
  • src/coinjoin/client.cpp (1 hunks)
  • src/coinjoin/util.h (1 hunks)
  • src/coins.h (0 hunks)
  • src/dbwrapper.h (0 hunks)
  • src/init.cpp (1 hunks)
  • src/interfaces/chain.h (1 hunks)
  • src/interfaces/wallet.h (2 hunks)
  • src/node/chainstate.cpp (1 hunks)
  • src/node/interfaces.cpp (4 hunks)
  • src/qt/coincontroldialog.cpp (1 hunks)
  • src/qt/test/wallettests.cpp (1 hunks)
  • src/qt/walletcontroller.cpp (1 hunks)
  • src/qt/walletmodel.h (1 hunks)
  • src/rpc/evo.cpp (2 hunks)
  • src/rpc/masternode.cpp (1 hunks)
  • src/txdb.cpp (3 hunks)
  • src/txdb.h (1 hunks)
  • src/util/result.h (1 hunks)
  • src/wallet/coincontrol.cpp (1 hunks)
  • src/wallet/coinjoin.cpp (7 hunks)
  • src/wallet/coinselection.cpp (6 hunks)
  • src/wallet/coinselection.h (2 hunks)
  • src/wallet/interfaces.cpp (4 hunks)
  • src/wallet/load.cpp (1 hunks)
  • src/wallet/receive.cpp (4 hunks)
  • src/wallet/rpc/backup.cpp (1 hunks)
  • src/wallet/rpc/coins.cpp (4 hunks)
  • src/wallet/rpc/transactions.cpp (1 hunks)
  • src/wallet/rpc/wallet.cpp (1 hunks)
  • src/wallet/spend.cpp (6 hunks)
  • src/wallet/spend.h (1 hunks)
  • src/wallet/test/coinjoin_tests.cpp (1 hunks)
  • src/wallet/test/coinselector_tests.cpp (10 hunks)
  • src/wallet/test/util.cpp (1 hunks)
  • src/wallet/test/wallet_tests.cpp (11 hunks)
  • src/wallet/wallet.cpp (15 hunks)
  • src/wallet/wallet.h (5 hunks)
  • test/README.md (1 hunks)
  • test/functional/feature_unsupported_utxo_db.py (1 hunks)
  • test/functional/test_framework/authproxy.py (2 hunks)
  • test/functional/test_framework/util.py (2 hunks)
  • test/functional/test_runner.py (1 hunks)
  • test/get_previous_releases.py (2 hunks)
💤 Files with no reviewable changes (2)
  • src/dbwrapper.h
  • src/coins.h
🧰 Additional context used
🪛 Flake8 (7.2.0)
test/functional/test_framework/util.py

[error] 368-368: at least two spaces before inline comment

(E261)

🔇 Additional comments (96)
src/interfaces/chain.h (1)

131-133: Well-designed interface addition.

The new getActiveChainLocator method is properly documented and follows good interface design practices. The method signature is appropriate and the documentation clearly explains the expected behavior for both scenarios (block in active chain vs. ancestor lookup).

src/node/interfaces.cpp (2)

736-736: Good improvement: Explicit global mutex references.

The change from LOCK(cs_main) to LOCK(::cs_main) explicitly references the global cs_main mutex, improving code clarity and avoiding potential ambiguity with local variables. This change is consistent across multiple methods and follows best practices.

Also applies to: 761-761, 773-773, 855-855, 945-945


764-770: Correct implementation of the new interface method.

The getActiveChainLocator implementation is well-structured and correct:

  • Proper mutex locking with ::cs_main
  • Appropriate error handling by returning an empty locator when block is not found
  • Correct use of chainman().ActiveChain().GetLocator(index) to generate the locator
  • Implementation matches the interface contract and follows existing patterns in the codebase
src/coinjoin/util.h (1)

8-8: Header inclusion is justified

CCoinControl is used as a value-type member on line 83, therefore a full definition is required. Including the header here is correct and unavoidable; a mere forward declaration would be insufficient.

test/functional/test_runner.py (1)

370-373: New test added – ensure cache population cost is acceptable

feature_unsupported_utxo_db.py is inserted near fast (<60 s) tests. If this test pulls a legacy binary and spins up an extra node, its wall-time might be significantly higher and would be better placed nearer the top-of-file “longer” section to optimise parallelisation. Consider measuring its runtime on CI and moving accordingly.

test/README.md (1)

106-107: Good catch – docs now reference v0.12.1.5

The example command aligns with the new functional test. No issues spotted.

src/qt/walletmodel.h (1)

37-37: LGTM: Forward declaration updated to match struct definition.

The change correctly updates the forward declaration to match the COutput refactoring from class to struct in the coin selection codebase.

src/wallet/coincontrol.cpp (1)

10-10: LGTM: Modern initialization syntax adopted.

The change from parentheses to brace initialization is a good modernization that improves consistency and prevents potential narrowing conversions.

src/bench/coin_selection.cpp (2)

48-48: LGTM: COutput constructor updated for new interface.

The addition of the fees parameter with value 0 correctly adapts to the new COutput constructor signature. Using 0 is appropriate for benchmark scenarios.


77-77: LGTM: Consistent COutput constructor update.

The fees parameter addition maintains consistency with the updated COutput interface throughout the benchmark code.

src/wallet/load.cpp (1)

136-136: LGTM: Centralized wallet load notification.

The addition of NotifyWalletLoaded centralizes wallet load notifications and eliminates code duplication. The placement after successful wallet creation and before adding to context is correct.

src/qt/test/wallettests.cpp (1)

136-136: LGTM: Test updated for new scan method signature.

The addition of save_progress=false correctly adapts to the extended ScanForWalletTransactions method signature. Disabling progress saving is appropriate for test scenarios.

src/wallet/test/coinjoin_tests.cpp (1)

152-152: LGTM: Correct addition of save_progress parameter for test context.

The addition of save_progress=false to the ScanForWalletTransactions call is appropriate for test setup. Tests should not persist intermediate progress to avoid side effects, making false the correct choice here.

src/wallet/test/util.cpp (1)

40-40: LGTM: Appropriate parameter addition for test utility.

The save_progress=false parameter addition is correct for the CreateSyncedWallet test utility function. Test utilities should not save progress to maintain test isolation and avoid persistent side effects.

src/wallet/rpc/backup.cpp (1)

808-808: LGTM: Correct parameter choice for import operation.

The addition of save_progress=false is appropriate for the Electrum wallet import operation. Import operations should typically complete atomically rather than saving intermediate progress, ensuring that failed imports can be cleanly retried without partial state persistence.

src/wallet/rpc/wallet.cpp (1)

425-425: LGTM! Parameter addition aligns with wallet rescan refactor.

The addition of the explicit save_progress=false parameter is consistent with the broader wallet refactor that enhances ScanForWalletTransactions with progress saving control during rescans.

test/functional/test_framework/util.py (1)

20-20: LGTM! Import addition supports legacy compatibility.

The urllib.parse import is correctly added to support URL encoding of RPC passwords for legacy version compatibility.

src/txdb.h (1)

71-72: LGTM! Method rename improves semantic clarity.

The rename from Upgrade() to NeedsUpgrade() correctly reflects the semantic change from performing an upgrade to detecting unsupported database formats. The updated comment clearly documents the method's purpose.

test/functional/test_framework/authproxy.py (2)

77-78: LGTM! Password handling improves legacy compatibility.

The URL decoding of passwords before UTF-8 encoding correctly addresses compatibility with legacy versions (v0.12.1.x and lower) that used URL-unsafe Base64 passwords. The implementation properly chains the decode and encode operations.


135-136: LGTM! Parameter conversion enhances RPC compatibility.

The conversion of empty parameter dictionaries to empty arrays correctly addresses compatibility with versions v0.12.2.x and lower that expect array parameters. The logic properly handles the edge case while preserving existing functionality.

ci/test/00_setup_env_native_qt5.sh (1)

17-17: LGTM! Enhanced test coverage with legacy release.

The addition of "v0.12.1.5" to PREVIOUS_RELEASES_TO_DOWNLOAD correctly expands the test infrastructure to support testing with legacy releases, enabling verification of unsupported UTXO database format handling.

src/wallet/rpc/transactions.cpp (1)

911-911: LGTM! Consistent with the wallet scanning standardization effort.

The addition of the explicit save_progress=false parameter to ScanForWalletTransactions is appropriate for the rescanblockchain RPC context. Setting progress saving to false makes sense for user-initiated manual rescans where the operation should complete atomically without intermediate progress persistence.

This change aligns well with the broader wallet enhancement pattern described in the PR objectives.

src/coinjoin/client.cpp (1)

1553-1554: LGTM! Modern wallet API usage.

The change correctly modernizes the coin selection to use AvailableCoinsListUnspent with the same CCoinControl filter, maintaining identical functionality while aligning with the broader wallet interface refactoring.

src/node/chainstate.cpp (1)

158-162: Approve the safety-first approach to database format handling.

This change correctly prioritizes safety by refusing to load unsupported database formats rather than attempting risky automatic upgrades. The explicit requirement for user reindexing (-reindex-chainstate) provides a clear recovery path while preventing potential database corruption during automated upgrades.

src/init.cpp (1)

2014-2016: LGTM! Excellent improvement to error handling and user experience.

This change effectively replaces complex legacy database upgrade logic with a clean, fail-fast approach that provides clear user guidance. The immediate return with an actionable error message (restart with -reindex-chainstate) is much better than attempting potentially risky automatic upgrades. This aligns well with the broader architectural changes to simplify chainstate database handling.

test/get_previous_releases.py (2)

95-102: LGTM: SHA256 checksums added for v0.12.1.5 release.

The checksums are properly formatted and cover all supported platforms for the legacy v0.12.1.5 release, enabling secure downloads for testing compatibility with older versions.


129-143: Good enhancement: Platform normalization for legacy releases.

The enhanced platform mapping logic properly handles the differences between modern and legacy platform naming conventions. The Windows platform mappings and the conditional logic for tags < "v0.12.2.3" ensure backward compatibility with older release naming schemes.

src/interfaces/wallet.h (2)

15-15: LGTM: Required include for BResult type.

The inclusion of util/result.h is necessary to support the new BResult return type used in the restoreWallet method.


356-356: Excellent modernization of error handling.

The change from returning a raw pointer with an error output parameter to returning BResult<std::unique_ptr<Wallet>> provides a more modern, unified approach to error handling. This eliminates the need for output parameters and makes error handling more explicit and type-safe.

src/rpc/masternode.cpp (1)

134-139: Excellent refactoring to modern coin selection approach.

The refactoring simplifies the masternode collateral retrieval by:

  • Using CCoinControl with CoinType::ONLY_MASTERNODE_COLLATERAL filter directly in the constructor
  • Leveraging AvailableCoinsListUnspent under proper wallet locking
  • Eliminating manual vector declaration and explicit wallet locking

This approach is more consistent with the broader wallet coin selection modernization across the codebase.

src/util/result.h (1)

16-47: Excellent implementation of result/error handling utility.

The BResult<T> class provides a clean, type-safe approach to error handling:

Strengths:

  • Uses std::variant for efficient storage of either result or error
  • Proper move semantics in constructors and ReleaseObj()
  • Clear method naming (HasRes(), GetObj(), GetError())
  • Appropriate use of assertions to enforce correct usage
  • Explicit bool conversion operator for natural conditional checking

Design considerations:

  • The default constructor creates an empty error, which may be unexpected
  • The class correctly prevents access to the wrong variant arm via assertions

This utility will provide a solid foundation for unified error handling across the codebase.

src/rpc/evo.cpp (2)

258-263: LGTM: Clean refactor to use AvailableCoinsListUnspent interface.

The change to iterate directly over .coins from the CoinsResult returned by AvailableCoinsListUnspent is cleaner and aligns with the wallet interface refactoring. This eliminates the need for explicit vector declarations and simplifies the coin selection logic.


784-784: LGTM: Unified coin locking interface using COutPoint.

The change to use IsLockedCoin(ptx.collateralOutpoint) with a single COutPoint parameter is consistent with the interface unification mentioned in the refactoring. This simplifies the API by eliminating the need for separate hash and index arguments.

src/qt/walletcontroller.cpp (1)

372-375: LGTM: Proper implementation of BResult interface for wallet restoration.

The changes correctly implement the new BResult<std::unique_ptr<Wallet>> interface:

  1. Line 372: The restoreWallet call signature is simplified by removing the explicit error output parameter, as errors are now encapsulated in the BResult return type.

  2. Line 374: Error handling properly uses the BResult conditional check and GetError() method to extract error messages when the operation fails.

  3. Line 375: Ownership transfer correctly uses ReleaseObj() to extract the wallet object from the successful BResult.

This refactoring improves error handling consistency across the wallet interface layer.

src/wallet/rpc/coins.cpp (4)

349-349: Excellent interface unification with COutPoint.

The updates to use COutPoint directly for IsSpent() and IsLockedCoin() improve interface consistency and code clarity by eliminating the need to pass separate transaction hash and output index parameters.

Also applies to: 353-353


605-605: Good simplification of CCoinControl construction.

Passing the coin type filter directly in the constructor reduces complexity compared to setting it as a separate step.


661-661: Approve the modernized coin retrieval interface.

The switch from AvailableCoins() (which fills a passed vector) to AvailableCoinsListUnspent() (which returns a struct containing the coins) follows modern C++ practices and aligns with the broader wallet refactoring.


672-672: Consistent scriptPubKey parameter usage.

The direct use of scriptPubKey parameter for IsSpentKey() maintains consistency with the broader COutPoint and script-based interface unification.

test/functional/feature_unsupported_utxo_db.py (4)

16-31: Well-structured test setup for version compatibility.

The test configuration properly sets up two nodes with different versions (v0.12.1.5 and current) to test the unsupported UTXO database scenario. The version array setup is clear and appropriate.


34-40: Good adaptation for legacy RPC compatibility.

Using the legacy generate RPC instead of generatetoaddress for v0.12.1.5 compatibility shows attention to historical API differences. The test correctly validates both the block hash and UTXO set state.


42-53: Comprehensive error message validation.

The test properly validates that the current node fails to start with the expected error message instructing users to restart with -reindex-chainstate. The error message is clear and actionable for users.


55-58: Thorough recovery validation.

The test confirms that the recovery mechanism works correctly by starting with -reindex-chainstate and validating that both the block hash and UTXO set amount match the expected values, ensuring data integrity after reindexing.

src/wallet/receive.cpp (4)

118-122: Effective consolidation of filter handling.

The consolidation of separate ISMINE_SPENDABLE and ISMINE_WATCH_ONLY checks into a single combined filter masked by ISMINE_ALL reduces code duplication and improves maintainability.


132-135: Consistent filter pattern application.

Applying the same filter consolidation pattern in CachedTxGetDebit maintains consistency with the credit calculation changes.


177-184: Improved code clarity with local references and COutPoint usage.

Using a local reference const CTxOut& txout and COutPoint(hashTx, i) for spent status checks improves readability and aligns with the codebase's move toward consistent COutPoint usage.


354-365: Enhanced readability in address balance calculation.

The use of local reference const auto& output and direct COutPoint construction COutPoint(walletEntry.first, i) makes the code more readable while maintaining the same logic.

src/wallet/coinselection.cpp (5)

71-71: Approve the algorithmic improvement to use explicit indexes.

The change from boolean inclusion flags to explicit index vectors (std::vector<size_t>) in the Branch and Bound algorithm improves clarity by making the selected UTXOs explicit rather than implicit.

Also applies to: 89-89


158-160: Correct output construction with index-based selection.

The output construction correctly uses the selected indexes to build the final result, maintaining the algorithm's correctness despite the internal representation change.


399-399: Proper adoption of COutput getter methods.

The updates to use GetEffectiveValue() and GetFee() instead of direct member access align with the new fee-aware COutput design and improve encapsulation.

Also applies to: 404-404, 409-409


444-445: Consistent getter usage in waste calculation.

The GetSelectionWaste function correctly adopts the new getter methods, maintaining consistency with the broader COutput interface changes.


114-149: Verify the backtracking logic correctness.

The refactored backtracking logic with explicit indexes is more complex. The loop that restores lookahead values (for (--utxo_pool_index; utxo_pool_index > curr_selection.back(); --utxo_pool_index)) and the exclusion shortcut condition need careful verification.

#!/bin/bash
# Verify that the branch and bound algorithm logic is tested adequately
rg -A 10 -B 5 "SelectCoinsBnB.*test" --type cpp
src/wallet/interfaces.cpp (3)

131-131: Consistent COutPoint adoption in wallet transaction output construction.

The updates to use COutPoint directly in MakeWalletTxOut functions maintain consistency with the broader wallet interface unification and improve parameter clarity.

Also applies to: 142-142


274-274: Unified coin locking interface.

The direct use of COutPoint parameter for IsLockedCoin() maintains consistency with the interface unification across wallet methods.


630-637: Improved error handling with BResult pattern.

The update to return BResult<std::unique_ptr<Wallet>> instead of using an explicit error output parameter improves error handling consistency. The implementation correctly wraps either the wallet result or the error in the BResult structure.

src/wallet/test/wallet_tests.cpp (7)

66-66: LGTM!

The addition of NotifyWalletLoaded ensures wallet load callbacks are triggered during tests, maintaining consistency with the production wallet loading process.


138-167: Well-structured test for the new save_progress functionality.

The test properly verifies that:

  1. Block locator is not saved when save_progress=false
  2. Block locator is saved when save_progress=true
  3. The fake time mechanism allows controlled testing of progress persistence

The switch to CreateMockWalletDatabase() improves test isolation.


191-191: Consistent parameter usage.

Appropriately using save_progress=false for pruning tests where progress persistence is not being tested.

Also applies to: 218-218


612-612: Correct usage of the new coin selection API.

The changes properly use AvailableCoinsListUnspent(*wallet).coins.size() to get the coin count, reflecting the new CoinsResult struct return type.

Also applies to: 622-622


1012-1012: Consistent parameter addition.

Correctly adds save_progress=false to maintain existing test behavior.


1301-1305: Proper adaptation to the new coin selection API.

The code correctly uses AvailableCoinsListUnspent and iterates over the coins vector from the returned CoinsResult struct, maintaining the same locking behavior.

Also applies to: 1357-1358


1452-1452: Consistent parameter usage.

Correctly adds save_progress=false to the rescan operation.

src/wallet/coinselection.h (2)

68-83: Well-implemented constructor with fee rate calculation.

The constructor correctly:

  • Handles the optional fee rate parameter
  • Sets fee to 0 when input_bytes < 0 (unknown size)
  • Calculates effective value as output value minus fee

Good defensive programming with the conditional calculation.


85-92: Good validation logic in the fee-based constructor.

The assertion properly enforces the invariant that unknown input sizes (input_bytes < 0) must have zero fees, while known sizes can have non-negative fees. The constructor delegation pattern keeps the code DRY.

src/txdb.cpp (2)

33-34: Appropriate categorization of legacy database key.

Moving DB_COINS to the deprecated keys section correctly reflects that this key format is no longer supported, only detected.


56-63: Clean implementation of legacy format detection.

The NeedsUpgrade() method efficiently detects legacy UTXO entries by:

  • Seeking directly to the DB_COINS prefix
  • Returning immediately upon finding any such entry
  • Providing clear documentation about when this format was deprecated

This is much simpler than the removed upgrade logic while serving the detection purpose.

src/wallet/spend.h (3)

28-32: Well-designed result structure.

The CoinsResult struct cleanly encapsulates both the coins list and their total amount, providing a more cohesive API than the previous approach of modifying parameters by reference.


33-44: Excellent API improvements to AvailableCoins.

The refactored function signature provides:

  • Clean return type with CoinsResult
  • Fee rate awareness via optional parameter
  • Flexibility with only_spendable flag
  • Good defaults maintaining backward compatibility
  • Clear documentation of default behavior

These changes make the API more intuitive and powerful.


46-50: Useful wrapper function for coin enumeration.

AvailableCoinsListUnspent provides a clear API for listing all coins without transaction funding context. The documentation properly explains its use case (e.g., RPC commands), and setting only_spendable=false ensures comprehensive coin listing.

src/wallet/test/coinselector_tests.cpp (5)

39-91: LGTM! Test helper functions correctly adapted for fee-aware coin selection.

The updates to the add_coin helper functions properly incorporate the new fee parameters required by the updated COutput constructor. Setting input_bytes to 148 is appropriate for typical P2PKH inputs.


308-396: Test scenarios properly cover fee-aware coin selection logic.

The updated tests correctly validate coin selection behavior under different fee rate conditions:

  • Single coin selection when effective fee rate > long-term fee rate
  • Multiple coin selection when effective fee rate < long-term fee rate
  • Pre-selected coin behavior

Note: The comment on line 378 appropriately documents that Dash doesn't use BnB algorithm, explaining why that particular check is commented out.


420-442: Knapsack solver tests correctly updated with fee rate parameters.

The test maintains backward compatibility by using CFeeRate(0) for scenarios where fee rates aren't relevant to the test logic.


92-96: Correct usage of GetEffectiveValue() accessor method.

The change from direct member access to the GetEffectiveValue() method properly follows the updated COutput interface design.


884-918: Excellent test coverage for the new GetEffectiveValue() functionality.

The test comprehensively covers:

  • Standard fee rate calculation (10000 - 148 = 9852)
  • Unknown input size handling (returns absolute value)
  • Negative effective value scenarios
  • Direct fee passing vs. fee rate calculation

All expected values are correctly calculated.

src/wallet/coinjoin.cpp (5)

56-61: Clean refactoring using the new coin selection interface.

The change to use CCoinControl with CoinType::ONLY_READY_TO_MIX and AvailableCoinsListUnspent improves code clarity and maintainability by leveraging the centralized coin selection infrastructure.


92-108: Consistent refactoring and proper GetEffectiveValue() usage.

The changes properly:

  1. Use GetEffectiveValue() accessor in the comparator
  2. Apply the same CCoinControl/AvailableCoins pattern for consistency
  3. Document why CFeeRate(0) is used (effective value calculation requirement)

170-184: Proper use of COutPoint for coin state checks.

The changes correctly use COutPoint objects for IsSpent, IsLockedCoin, and IsFullyMixed checks, aligning with the improved wallet interface that uses unified output references.


230-234: Clean refactoring of HasCollateralInputs using the coin control pattern.

The function now properly uses CCoinControl with CoinType::ONLY_COINJOIN_COLLATERAL filter and the simplified AvailableCoinsListUnspent interface.


508-508: Consistent COutPoint usage for IsSpent checks.

Both instances correctly use COutPoint objects for IsSpent checks, maintaining consistency with the updated wallet interface.

Also applies to: 548-548

src/wallet/wallet.h (4)

69-69: Good addition of wallet load notification function.

The NotifyWalletLoaded function follows the established pattern for wallet event notifications and will help with event-driven wallet management.


550-559: Improved method signatures using proper types.

The changes to use COutPoint and CScript parameters instead of separate hash/index parameters improve:

  • Type safety by using domain objects
  • Code clarity by reducing parameter count
  • Consistency across the wallet interface

639-639: Useful addition of save_progress parameter to wallet scanning.

The save_progress parameter allows callers to control whether scan progress is persisted, which is valuable for different scanning scenarios (e.g., initial scan vs. rescan).


1063-1092: Excellent testability improvement for wallet rescanning.

The addition of clock abstraction through:

  • Clock type alias
  • NowFn function type
  • Injectable time function via setNow()

This follows best practices for making time-dependent code testable by allowing time injection in tests.

src/wallet/spend.cpp (8)

69-77: Function signature modernization looks good

The transformation from a void function with output parameter to returning a CoinsResult struct is a clean refactoring that improves the API. The addition of feerate and only_spendable parameters enables fee-aware coin selection, which aligns with the broader wallet modernization effort.


190-192: Fee-aware COutput construction is properly implemented

The construction includes the fee rate parameter which enables effective value calculations in coin selection algorithms. The total amount accumulation is correctly maintained.


210-213: Well-designed wrapper function for backward compatibility

The AvailableCoinsListUnspent wrapper provides a clean interface for callers that don't need fee-aware coin selection, maintaining backward compatibility while allowing the main function to evolve.


218-224: GetAvailableBalance correctly adapted to new interface

The function properly uses the new AvailableCoins interface and returns the total_amount field from the result structure.


257-257: ListCoins properly uses the new interface

The function correctly uses AvailableCoinsListUnspent() and accesses the coins field from the returned CoinsResult.


489-494: Fee-aware coin selection properly implemented

The COutput construction correctly includes the effective fee rate, and the subsequent use of GetEffectiveValue() ensures that the effective value is calculated considering the transaction fees.


793-802: Transaction creation correctly uses fee-aware coin selection

The call to AvailableCoins properly passes the effective fee rate for fee-aware coin selection, and correctly uses only_spendable=true by default to ensure only spendable outputs are considered for transaction creation.


186-190: Potential inconsistency in watch-only parameter usage

The spendable variable already considers coinControl && coinControl->fAllowWatchOnly && solvable in line 184, but line 189 uses coinControl && coinControl->fAllowWatchOnly directly. Consider using the computed spendable value for consistency:

-int input_bytes = GetTxSpendSize(wallet, wtx, i, (coinControl && coinControl->fAllowWatchOnly));
+int input_bytes = GetTxSpendSize(wallet, wtx, i, spendable && (mine & ISMINE_WATCH_ONLY));

Likely an incorrect or invalid review comment.

src/wallet/wallet.cpp (6)

185-191: Good refactoring: Centralized wallet load notifications.

The new NotifyWalletLoaded function properly consolidates the wallet load notification logic that was previously duplicated across multiple functions. The mutex locking ensures thread safety.


393-416: Enhanced error handling with exception safety.

The try-catch wrapper properly handles exceptions during wallet restoration while preserving existing error messages. The cleanup logic correctly removes files on failure regardless of the error path.


625-640: Improved API: Using COutPoint for spent checking.

The signature change from separate hash/index parameters to a single COutPoint parameter improves type safety and API consistency. The implementation correctly uses the outpoint for lookups.


877-897: Correct implementation with legacy wallet compatibility.

The new IsSpentKey implementation properly handles both standard destination extraction and legacy wallet key checking. The additional complexity for legacy wallets is necessary for backward compatibility.


1679-1683: Well-implemented progress persistence for wallet rescanning.

The addition of the save_progress parameter and interval-based saving logic is a good optimization. Using the WalletRescanReserver's clock abstraction ensures consistent timing throughout the rescan process.

Also applies to: 1711-1752


2138-2141: Consistent UTXO handling with COutPoint objects.

The UTXO loading logic correctly uses COutPoint objects and the updated IsSpent interface, maintaining consistency with the API changes throughout the wallet.

@github-actions
Copy link

This pull request has conflicts, please rebase.

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: 0

🧹 Nitpick comments (1)
test/functional/test_framework/util.py (1)

368-369: Fix inline comment spacing and approve backward compatibility enhancement.

The URL encoding logic correctly addresses the compatibility issue with v0.12.1.x and lower versions that used URL-unsafe Base64 for RPC passwords. Using safe='' ensures all potentially problematic characters are properly encoded.

Fix the inline comment spacing to comply with PEP 8:

-    rpc_p = urllib.parse.quote(rpc_p, safe='') # v0.12.1.x and lower used URL unsafe Base64 for their passwords, quote it
+    rpc_p = urllib.parse.quote(rpc_p, safe='')  # v0.12.1.x and lower used URL unsafe Base64 for their passwords, quote it
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 89cd497 and 01a22de.

📒 Files selected for processing (46)
  • ci/test/00_setup_env_native_qt5.sh (1 hunks)
  • src/Makefile.am (1 hunks)
  • src/bench/coin_selection.cpp (2 hunks)
  • src/coinjoin/client.cpp (1 hunks)
  • src/coinjoin/util.h (1 hunks)
  • src/coins.h (0 hunks)
  • src/dbwrapper.h (0 hunks)
  • src/init.cpp (1 hunks)
  • src/interfaces/chain.h (1 hunks)
  • src/interfaces/wallet.h (2 hunks)
  • src/node/chainstate.cpp (1 hunks)
  • src/node/interfaces.cpp (4 hunks)
  • src/qt/coincontroldialog.cpp (1 hunks)
  • src/qt/test/wallettests.cpp (1 hunks)
  • src/qt/walletcontroller.cpp (1 hunks)
  • src/qt/walletmodel.h (1 hunks)
  • src/rpc/evo.cpp (2 hunks)
  • src/rpc/masternode.cpp (1 hunks)
  • src/txdb.cpp (3 hunks)
  • src/txdb.h (1 hunks)
  • src/util/result.h (1 hunks)
  • src/wallet/coincontrol.cpp (1 hunks)
  • src/wallet/coinjoin.cpp (7 hunks)
  • src/wallet/coinselection.cpp (6 hunks)
  • src/wallet/coinselection.h (2 hunks)
  • src/wallet/interfaces.cpp (4 hunks)
  • src/wallet/load.cpp (1 hunks)
  • src/wallet/receive.cpp (4 hunks)
  • src/wallet/rpc/backup.cpp (1 hunks)
  • src/wallet/rpc/coins.cpp (4 hunks)
  • src/wallet/rpc/transactions.cpp (1 hunks)
  • src/wallet/rpc/wallet.cpp (1 hunks)
  • src/wallet/spend.cpp (6 hunks)
  • src/wallet/spend.h (1 hunks)
  • src/wallet/test/coinjoin_tests.cpp (1 hunks)
  • src/wallet/test/coinselector_tests.cpp (10 hunks)
  • src/wallet/test/util.cpp (1 hunks)
  • src/wallet/test/wallet_tests.cpp (11 hunks)
  • src/wallet/wallet.cpp (15 hunks)
  • src/wallet/wallet.h (5 hunks)
  • test/README.md (1 hunks)
  • test/functional/feature_unsupported_utxo_db.py (1 hunks)
  • test/functional/test_framework/authproxy.py (2 hunks)
  • test/functional/test_framework/util.py (2 hunks)
  • test/functional/test_runner.py (1 hunks)
  • test/get_previous_releases.py (2 hunks)
💤 Files with no reviewable changes (2)
  • src/coins.h
  • src/dbwrapper.h
✅ Files skipped from review due to trivial changes (1)
  • src/coinjoin/util.h
🚧 Files skipped from review as they are similar to previous changes (40)
  • src/Makefile.am
  • src/wallet/coincontrol.cpp
  • test/functional/test_runner.py
  • src/wallet/load.cpp
  • test/README.md
  • src/wallet/test/coinjoin_tests.cpp
  • src/qt/test/wallettests.cpp
  • src/wallet/rpc/wallet.cpp
  • src/txdb.h
  • src/node/chainstate.cpp
  • src/bench/coin_selection.cpp
  • src/wallet/test/util.cpp
  • test/functional/test_framework/authproxy.py
  • src/qt/walletmodel.h
  • src/interfaces/chain.h
  • src/qt/coincontroldialog.cpp
  • src/node/interfaces.cpp
  • src/wallet/rpc/transactions.cpp
  • src/wallet/rpc/backup.cpp
  • ci/test/00_setup_env_native_qt5.sh
  • src/init.cpp
  • src/rpc/masternode.cpp
  • src/qt/walletcontroller.cpp
  • src/wallet/rpc/coins.cpp
  • src/wallet/coinselection.cpp
  • src/util/result.h
  • test/get_previous_releases.py
  • src/interfaces/wallet.h
  • src/rpc/evo.cpp
  • test/functional/feature_unsupported_utxo_db.py
  • src/wallet/interfaces.cpp
  • src/wallet/coinjoin.cpp
  • src/wallet/test/wallet_tests.cpp
  • src/wallet/coinselection.h
  • src/wallet/receive.cpp
  • src/wallet/spend.h
  • src/wallet/test/coinselector_tests.cpp
  • src/wallet/wallet.h
  • src/coinjoin/client.cpp
  • src/wallet/wallet.cpp
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: kwvg
PR: dashpay/dash#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
PR: dashpay/dash#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.
Learnt from: kwvg
PR: dashpay/dash#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.
src/txdb.cpp (3)
Learnt from: knst
PR: dashpay/dash#6511
File: src/evo/deterministicmns.cpp:1369-1373
Timestamp: 2025-01-07T18:50:44.838Z
Learning: The functions `MigrateDBIfNeeded` and `MigrateDBIfNeeded2` in `src/evo/deterministicmns.cpp` are temporary and will be removed in a future version. Refactoring suggestions for these functions should be avoided.
Learnt from: kwvg
PR: dashpay/dash#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
PR: dashpay/dash#6665
File: src/evo/providertx.h:82-82
Timestamp: 2025-06-06T11:53:09.094Z
Learning: In ProTx serialization code (SERIALIZE_METHODS), version checks should use hardcoded maximum flags (/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true) rather than deployment-based flags. This is because serialization code should be able to deserialize any structurally valid ProTx up to the maximum version the code knows how to handle, regardless of current consensus validity. Validation code, not serialization code, is responsible for checking whether a ProTx version is consensus-valid based on deployment status.
src/wallet/spend.cpp (2)
Learnt from: kwvg
PR: dashpay/dash#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
PR: dashpay/dash#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.
🪛 Flake8 (7.2.0)
test/functional/test_framework/util.py

[error] 368-368: at least two spaces before inline comment

(E261)

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: linux64_multiprocess-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: win64-build / Build source
  • GitHub Check: arm-linux-build / Build source
🔇 Additional comments (8)
src/txdb.cpp (3)

34-34: Good architectural decision to move deprecated constant.

Moving DB_COINS to the "Keys used in previous version" section clearly indicates its deprecated status while preserving it for legacy detection purposes.


56-63: Clean implementation of legacy database detection.

The NeedsUpgrade() method provides a simple and efficient way to detect legacy UTXO entries without the complexity of the previous upgrade logic. The implementation correctly:

  • Creates a database iterator to seek deprecated DB_COINS entries
  • Uses std::make_pair(DB_COINS, uint256{}) to find the first entry with the deprecated prefix
  • Returns a boolean indicating whether any legacy entries exist

This aligns well with the PR's goal of replacing upgrade functionality with detection and reindex requirements.


75-75: Confirms removal of legacy upgrade code.

The closure of the anonymous namespace at this point, combined with the AI summary, indicates successful removal of the complex legacy CCoins class and upgrade logic that was previously contained within this namespace.

test/functional/test_framework/util.py (1)

20-20: LGTM: Import supports backward compatibility fix.

The import of urllib.parse is necessary for the URL encoding functionality added on line 368 to handle legacy RPC password formats.

src/wallet/spend.cpp (4)

70-77: LGTM! Well-designed API improvement.

The function signature refactoring improves the interface by returning a structured result instead of using out-parameters, and adds useful fee rate awareness and spendable filtering capabilities.


83-83: LGTM! Clean implementation of the refactoring.

The implementation correctly:

  • Uses local variables for better readability
  • Implements the new spendable filter logic
  • Constructs COutput with fee rate awareness
  • Accumulates total amount properly
  • Includes early return optimizations for efficiency

Also applies to: 119-121, 187-192, 196-198, 202-204, 207-209


211-214: LGTM! Good backward compatibility wrapper.

The helper function provides a clean interface for basic coin listing while maintaining compatibility with existing code that doesn't need fee rate awareness or spendable filtering.


219-225: LGTM! Consistent adoption of the new interface.

All functions have been correctly updated to use the new CoinsResult interface:

  • GetAvailableBalance properly extracts total_amount
  • ListCoins uses the appropriate helper function
  • SelectCoins constructs COutput with fee rate and uses GetEffectiveValue()
  • CreateTransactionInternal passes the effective fee rate correctly

The changes maintain existing functionality while leveraging the improved API design.

Also applies to: 258-258, 490-490, 494-494, 794-800, 803-803

@kwvg
Copy link
Collaborator Author

kwvg commented Jul 5, 2025

Rebased on top of develop (094ceb9) due to dash#6735

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: 0

🧹 Nitpick comments (1)
test/functional/test_framework/util.py (1)

368-369: Fix inline comment spacing and approve the URL encoding logic.

The URL encoding logic correctly addresses compatibility issues with older Dash Core versions (v0.12.1.x and lower) that used URL-unsafe Base64 for RPC passwords. However, there's a formatting issue with the inline comment spacing.

Apply this diff to fix the spacing:

-    rpc_p = urllib.parse.quote(rpc_p, safe='') # v0.12.1.x and lower used URL unsafe Base64 for their passwords, quote it
+    rpc_p = urllib.parse.quote(rpc_p, safe='')  # v0.12.1.x and lower used URL unsafe Base64 for their passwords, quote it
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01a22de and 640c2b6.

📒 Files selected for processing (46)
  • ci/test/00_setup_env_native_qt5.sh (1 hunks)
  • src/Makefile.am (1 hunks)
  • src/bench/coin_selection.cpp (2 hunks)
  • src/coinjoin/client.cpp (1 hunks)
  • src/coinjoin/util.h (1 hunks)
  • src/coins.h (0 hunks)
  • src/dbwrapper.h (0 hunks)
  • src/init.cpp (1 hunks)
  • src/interfaces/chain.h (1 hunks)
  • src/interfaces/wallet.h (2 hunks)
  • src/node/chainstate.cpp (1 hunks)
  • src/node/interfaces.cpp (4 hunks)
  • src/qt/coincontroldialog.cpp (1 hunks)
  • src/qt/test/wallettests.cpp (1 hunks)
  • src/qt/walletcontroller.cpp (1 hunks)
  • src/qt/walletmodel.h (1 hunks)
  • src/rpc/evo.cpp (2 hunks)
  • src/rpc/masternode.cpp (1 hunks)
  • src/txdb.cpp (3 hunks)
  • src/txdb.h (1 hunks)
  • src/util/result.h (1 hunks)
  • src/wallet/coincontrol.cpp (1 hunks)
  • src/wallet/coinjoin.cpp (7 hunks)
  • src/wallet/coinselection.cpp (6 hunks)
  • src/wallet/coinselection.h (2 hunks)
  • src/wallet/interfaces.cpp (4 hunks)
  • src/wallet/load.cpp (1 hunks)
  • src/wallet/receive.cpp (4 hunks)
  • src/wallet/rpc/backup.cpp (1 hunks)
  • src/wallet/rpc/coins.cpp (4 hunks)
  • src/wallet/rpc/transactions.cpp (1 hunks)
  • src/wallet/rpc/wallet.cpp (1 hunks)
  • src/wallet/spend.cpp (6 hunks)
  • src/wallet/spend.h (1 hunks)
  • src/wallet/test/coinjoin_tests.cpp (1 hunks)
  • src/wallet/test/coinselector_tests.cpp (10 hunks)
  • src/wallet/test/util.cpp (1 hunks)
  • src/wallet/test/wallet_tests.cpp (11 hunks)
  • src/wallet/wallet.cpp (15 hunks)
  • src/wallet/wallet.h (5 hunks)
  • test/README.md (1 hunks)
  • test/functional/feature_unsupported_utxo_db.py (1 hunks)
  • test/functional/test_framework/authproxy.py (2 hunks)
  • test/functional/test_framework/util.py (2 hunks)
  • test/functional/test_runner.py (1 hunks)
  • test/get_previous_releases.py (2 hunks)
💤 Files with no reviewable changes (2)
  • src/coins.h
  • src/dbwrapper.h
✅ Files skipped from review due to trivial changes (4)
  • src/qt/walletmodel.h
  • test/functional/test_runner.py
  • src/Makefile.am
  • src/rpc/evo.cpp
🚧 Files skipped from review as they are similar to previous changes (38)
  • src/coinjoin/util.h
  • src/wallet/coincontrol.cpp
  • src/wallet/test/util.cpp
  • src/node/chainstate.cpp
  • src/wallet/load.cpp
  • src/wallet/rpc/backup.cpp
  • src/qt/coincontroldialog.cpp
  • src/wallet/rpc/wallet.cpp
  • src/wallet/test/coinjoin_tests.cpp
  • test/README.md
  • src/bench/coin_selection.cpp
  • src/qt/test/wallettests.cpp
  • src/wallet/rpc/transactions.cpp
  • src/txdb.h
  • test/functional/test_framework/authproxy.py
  • src/interfaces/wallet.h
  • src/init.cpp
  • src/interfaces/chain.h
  • ci/test/00_setup_env_native_qt5.sh
  • src/coinjoin/client.cpp
  • src/node/interfaces.cpp
  • src/wallet/coinselection.cpp
  • test/get_previous_releases.py
  • src/rpc/masternode.cpp
  • src/util/result.h
  • src/qt/walletcontroller.cpp
  • src/wallet/receive.cpp
  • src/wallet/rpc/coins.cpp
  • test/functional/feature_unsupported_utxo_db.py
  • src/wallet/interfaces.cpp
  • src/wallet/coinjoin.cpp
  • src/wallet/coinselection.h
  • src/wallet/test/wallet_tests.cpp
  • src/wallet/spend.h
  • src/wallet/test/coinselector_tests.cpp
  • src/wallet/spend.cpp
  • src/wallet/wallet.h
  • src/wallet/wallet.cpp
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: kwvg
PR: dashpay/dash#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
PR: dashpay/dash#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.
Learnt from: kwvg
PR: dashpay/dash#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.
src/txdb.cpp (3)
Learnt from: knst
PR: dashpay/dash#6511
File: src/evo/deterministicmns.cpp:1369-1373
Timestamp: 2025-01-07T18:50:44.838Z
Learning: The functions `MigrateDBIfNeeded` and `MigrateDBIfNeeded2` in `src/evo/deterministicmns.cpp` are temporary and will be removed in a future version. Refactoring suggestions for these functions should be avoided.
Learnt from: kwvg
PR: dashpay/dash#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
PR: dashpay/dash#6665
File: src/evo/providertx.h:82-82
Timestamp: 2025-06-06T11:53:09.094Z
Learning: In ProTx serialization code (SERIALIZE_METHODS), version checks should use hardcoded maximum flags (/*is_basic_scheme_active=*/true, /*is_extended_addr=*/true) rather than deployment-based flags. This is because serialization code should be able to deserialize any structurally valid ProTx up to the maximum version the code knows how to handle, regardless of current consensus validity. Validation code, not serialization code, is responsible for checking whether a ProTx version is consensus-valid based on deployment status.
🪛 Flake8 (7.2.0)
test/functional/test_framework/util.py

[error] 368-368: at least two spaces before inline comment

(E261)

⏰ Context from checks skipped due to timeout of 90000ms (10)
  • GitHub Check: linux64_multiprocess-build / Build source
  • GitHub Check: linux64_tsan-build / Build source
  • GitHub Check: linux64_nowallet-build / Build source
  • GitHub Check: mac-build / Build source
  • GitHub Check: linux64_ubsan-build / Build source
  • GitHub Check: linux64_fuzz-build / Build source
  • GitHub Check: linux64-build / Build source
  • GitHub Check: linux64_sqlite-build / Build source
  • GitHub Check: win64-build / Build source
  • GitHub Check: arm-linux-build / Build source
🔇 Additional comments (4)
src/txdb.cpp (3)

34-34: LGTM: Correct placement in deprecated keys section.

Moving DB_COINS to the deprecated keys section is appropriate since it was deprecated in v0.15.0. The positioning clearly indicates this is a legacy key that might still be found in older databases.


56-63: LGTM: Clean detection logic replaces upgrade attempts.

The NeedsUpgrade() method provides a simple and effective way to detect legacy database formats without attempting to upgrade them. The implementation correctly:

  • Uses the deprecated DB_COINS key to detect legacy entries
  • Provides a clear comment explaining the deprecation timeline
  • Returns a boolean indicating whether legacy entries are present

This aligns well with the PR's objective to replace upgrade attempts with detection and refusal to load unsupported formats.


75-75: LGTM: Proper namespace formatting.

The namespace closing marker is correctly placed and follows standard C++ formatting practices.

test/functional/test_framework/util.py (1)

20-20: LGTM: Import added for URL encoding functionality.

The import is necessary for the URL encoding functionality used later in the file.

PastaPastaPasta
PastaPastaPasta previously approved these changes Jul 9, 2025
Copy link
Member

@PastaPastaPasta PastaPastaPasta left a comment

Choose a reason for hiding this comment

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

utACK 640c2b6

UdjinM6
UdjinM6 previously approved these changes Jul 11, 2025
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.

utACK 640c2b6

kwvg added 10 commits July 13, 2025 15:32
Changes to `src/wallet/rpc/spend.cpp` are not included as the `sendall`
RPC has not been implemented yet.
…veral code cleanups

Changes to `src/wallet/rpc/spend.cpp` are not included as the `sendall`
RPC has not been implemented yet.
The test suite can run on Windows and improvements in the build system
will allow native builds on Windows. When that happens, we need to be
able to fetch old Windows releases.
Relevant for the upcoming backport, which relies on a version of Dash
before v0.12.2.2 for validating migration code handling databases
created before bitcoin#10195 (which is included in v0.12.2.2, so we must
use one patch version earlier, i.e. v0.12.1.x)
…ower

bitcoin#8811 (eb7a6b0) allowed the RPC framework to parse objects but
this backport first debuted in v0.12.3, which means that nodes of even
lower versions cannot make sense of the blank object sent by default and
error out.

We need to pass a blank array instead. This is a forward-compatible
change.
kwvg added 10 commits July 13, 2025 15:32
Dash used URL unsafe Base64 encoding for their password field until
dash#1454, included in v0.12.2.0. This unfortunately means we have to
make sure we quote our URLs remaining sensitive to the behavior of older
versions.
…t to CreateTransaction and GetNewDestination

includes:
- 7a45c33
…reWallet, and in general via interfaces)

excludes:
- c3e5365
@kwvg kwvg dismissed stale reviews from UdjinM6 and PastaPastaPasta via 175970e July 13, 2025 16:00
@kwvg kwvg requested review from PastaPastaPasta and UdjinM6 July 13, 2025 16:01
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.

Good catch!

utACK 175970e

Copy link
Member

@PastaPastaPasta PastaPastaPasta left a comment

Choose a reason for hiding this comment

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

utACK 175970e

@PastaPastaPasta PastaPastaPasta merged commit 9349b3b into dashpay:develop Jul 14, 2025
34 of 36 checks passed
PastaPastaPasta added a commit that referenced this pull request Jul 23, 2025
…fier for <v0.12.3.x and bail out on macOS, make `feature_unsupported_utxo_db` Linux-only

7ace512 fix: restrict `feature_unsupported_utxo_db` to Linux (Kittywhiskers Van Gogh)
5c38d5c fix: don't download v0.12.2.x on macOS due to missing releases (Kittywhiskers Van Gogh)
722997e fix: avoid exclusion of v0.12.2.3 from platform identifier (Kittywhiskers Van Gogh)
fb2648a fix: compare against lower version first to avoid short-circuiting (Kittywhiskers Van Gogh)

Pull request description:

  ## Motivation

  `feature_unsupported_utxo_db.py` (introduced with [bitcoin#24236](bitcoin#24236) as 79fcd30 in [dash#6733](#6733)) creates problems on macOS for the following reasons:
  * The platform identifier detection code was placed _after_ v20 when it should've been positioned _before_, as the prior condition was met, platform identifier was taken to be `osx64`, which is incorrect ([release](https://github.com/dashpay/dash/releases/tag/v0.12.1.5)).

    <details>

    <summary>Error log:</summary>

    ```
    $ ./test/get_previous_releases.py -b -t "releases" ${PREVIOUS_RELEASES_TO_DOWNLOAD}
    Releases directory: releases
    Fetching: https://github.com/dashpay/dash/releases/download/v0.12.1.5/dashcore-0.12.1.5-osx64.tar.gz
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                    Dload  Upload   Total   Spent    Left  Speed
      0     9    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                    Dload  Upload   Total   Spent    Left  Speed
    100     9  100     9    0     0     34      0 --:--:-- --:--:-- --:--:--    34
    Checksum for given version doesn't exist
    ```

    </details>

  * Dash Core v0.12.2.x and earlier did not include daemon or utility binaries for macOS (i.e. `dashd`, as needed by the functional test suite), shipping only Dash-Qt using a disk image, in comparison to v0.12.3.x which do offer them in a tarbundle ([release](https://github.com/dashpay/dash/releases/tag/v0.12.3.1)).
  * Dash Core v0.12.2.3 was incorrectly excluded from the old platform determination logic due to the _less than_ comparison.

  In light of this, `get_previous_releases.py` will now error out if attempting to download versions <v0.12.3.x as we _cannot_ obtain the binaries needed to run functional tests. Additionally, `feature_unsupported_utxo_db.py` will bail out on non-Linux platforms as previous release tests assume all the versions are populated and will otherwise cause general failure.

  <details>

  <summary>Error log:</summary>

  ```
  $ ./test/functional/feature_unsupported_utxo_db.py
  2025-07-18T10:09:06.884000Z TestFramework (INFO): PRNG seed is: 5491056264691271257
  2025-07-18T10:09:06.884000Z TestFramework (INFO): Initializing test directory /tmp/dash_func_test_dkrhioh0
  2025-07-18T10:09:06.885000Z TestFramework (INFO): Create previous version (v0.12.1.5) utxo db
  2025-07-18T10:09:06.885000Z TestFramework (ERROR): Unexpected exception caught during testing
  Traceback (most recent call last):
    File "/src/dash/test/functional/test_framework/test_framework.py", line 162, in main
      self.run_test()
    File "/src/dash/./test/functional/feature_unsupported_utxo_db.py", line 35, in run_test
      self.start_node(0)
    File "/src/dash/test/functional/test_framework/test_framework.py", line 644, in start_node
      node.start(*args, **kwargs)
    File "/src/dash/test/functional/test_framework/test_node.py", line 249, in start
      self.process = subprocess.Popen(all_args, env=subp_env, stdout=stdout, stderr=stderr, cwd=cwd, **kwargs)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    File "/usr/lib/python3.11/subprocess.py", line 1024, in __init__
      self._execute_child(args, executable, preexec_fn, close_fds,
    File "/usr/lib/python3.11/subprocess.py", line 1901, in _execute_child
      raise child_exception_type(errno_num, err_msg, err_filename)
  FileNotFoundError: [Errno 2] No such file or directory: '/src/dash/releases/v0.12.1.5/bin/dashd'
  2025-07-18T10:09:06.936000Z TestFramework (INFO): Stopping nodes
  [...]
  ```

  </details>

  Special thanks to PastaPastaPasta for flagging this issue!

  ## Breaking Changes

  None expected.

  ## Checklist

  - [x] I have performed a self-review of my own code
  - [x] I have commented my code, particularly in hard-to-understand areas **(note: N/A)**
  - [x] I have added or updated relevant unit/integration/functional/e2e tests
  - [x] I have made corresponding changes to the documentation **(note: N/A)**
  - [x] I have assigned this pull request to a milestone _(for repository code-owners and collaborators only)_

ACKs for top commit:
  UdjinM6:
    utACK 7ace512
  PastaPastaPasta:
    utACK 7ace512

Tree-SHA512: f5dbe033264cc2978ab28419284a737ae932c2b0fcfa6a301c6e738b80e09723760d89e8b1de2ea917ef019e09d832a31b1a6c3127b3e52b65e89d457a0f91ab
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