wallet: skip APS when no partial spend exists #34405

pull 8144225309 wants to merge 1 commits into bitcoin:master from 8144225309:aps-skip-no-partial-spend changing 3 files +62 −16
  1. 8144225309 commented at 4:36 am on January 26, 2026: none

    Fixes #25150

    APS (Avoid Partial Spends) runs a second coin selection pass to fully spend UTXOs sharing a scriptPubKey. This currently runs unconditionally, even when the first selection has no partial spend. Running APS unnecessarily wastes computation and can produce a worse result when there was nothing to fix.

    Detect partial spends by comparing selected vs available UTXO counts per scriptPubKey, reusing available_coins. Skip APS if none found.

    Test updated to create partial spend scenarios so tracepoints fire.


    Supersedes #34362 which was corrupted by a shallow clone force-push.

  2. DrahtBot added the label Wallet on Jan 26, 2026
  3. DrahtBot commented at 4:37 am on January 26, 2026: contributor

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/34405.

    Reviews

    See the guideline for information on the review process. A summary of reviews will appear here.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #34075 (fees: Introduce Mempool Based Fee Estimation to reduce overestimation by ismaelsadeeq)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  4. 8144225309 force-pushed on Jan 26, 2026
  5. 8144225309 force-pushed on Jan 26, 2026
  6. 8144225309 force-pushed on Jan 26, 2026
  7. 8144225309 force-pushed on Jan 26, 2026
  8. in src/wallet/spend.cpp:1459 in 53de94fb82
    1453@@ -1432,8 +1454,11 @@ util::Result<CreatedTransactionResult> CreateTransaction(
    1454            res && res->change_pos.has_value() ? int32_t(*res->change_pos) : -1);
    1455     if (!res) return res;
    1456     const auto& txr_ungrouped = *res;
    1457-    // try with avoidpartialspends unless it's enabled already
    1458+    // try with avoidpartialspends unless it's enabled already, or if there's no partial spend to avoid
    1459     if (txr_ungrouped.fee > 0 /* 0 means non-functional fee rate estimation */ && wallet.m_max_aps_fee > -1 && !coin_control.m_avoid_partial_spends) {
    1460+        if (!txr_ungrouped.has_partial_spend) {
    


    achow101 commented at 9:25 pm on February 2, 2026:
    This condition can be grouped with the others in the line above, there’s no need to separate it with it’s own return statement.

    8144225309 commented at 2:54 am on February 3, 2026:
    Done, combined.
  9. in test/functional/interface_usdt_coinselection.py:122 in 53de94fb82 outdated
    118@@ -119,12 +119,14 @@ def skip_test_if_missing_module(self):
    119         self.skip_if_no_wallet()
    120         self.skip_if_running_under_valgrind()
    121 
    122-    def get_tracepoints(self, expected_types):
    123+    def get_tracepoints(self, expected_types, wallet_name=None):
    


    achow101 commented at 9:36 pm on February 2, 2026:
    The default for wallet_name is essentially self.default_wallet_name, so set it to that instead of using None.

    8144225309 commented at 2:55 am on February 3, 2026:
    self isn’t available at function definition time in Python. The =None with internal check matches the pattern used elsewhere in the test framework (e.g., extra_args in add_nodes()).
  10. 8144225309 force-pushed on Feb 3, 2026
  11. DrahtBot added the label Needs rebase on Feb 10, 2026
  12. 8144225309 force-pushed on Feb 11, 2026
  13. DrahtBot removed the label Needs rebase on Feb 11, 2026
  14. DrahtBot added the label CI failed on Feb 14, 2026
  15. wallet: skip APS when no partial spend exists
    APS runs a second coin selection to fully spend UTXOs sharing a
    scriptPubKey. Currently runs unconditionally, even when the first
    selection has no partial spend and APS cannot help.
    
    Detect partial spends by comparing selected vs available UTXO counts
    per scriptPubKey inside CreateTransactionInternal, reusing available_coins.
    Add has_partial_spend to CreatedTransactionResult. Skip APS if false.
    
    Update interface_usdt_coinselection test to create partial spend scenarios
    so tracepoints fire as expected.
    
    Fixes #25150
    b6319c62db
  16. 8144225309 force-pushed on Feb 15, 2026

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-02-17 12:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me