Refactor BnB tests #29532

pull murchandamus wants to merge 7 commits into bitcoin:master from murchandamus:2024-03-coinselection_tests changing 3 files +218 −162
  1. murchandamus commented at 10:37 pm on March 1, 2024: contributor

    This PR is splitting off some of the improvements made in #28985 and starts addressing the issues raised in #27754.

    I aim to completely replace coinselector_tests with coinselection_tests. The goal is to generally use coins created per a nominal effective value so we can get away from testing with CoinSelectionParams that are non-representative and effectuate counterintuitive behavior such as feerate = 0 or cost_of_change = 0

  2. DrahtBot commented at 10:37 pm on March 1, 2024: 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/29532.

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    Concept ACK jasonribble, ismaelsadeeq, yancyribbens

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    Conflicts

    No conflicts as of last run.

  3. murchandamus force-pushed on Mar 5, 2024
  4. DrahtBot added the label CI failed on Mar 23, 2024
  5. DrahtBot removed the label CI failed on Mar 28, 2024
  6. murchandamus marked this as ready for review on Apr 9, 2024
  7. murchandamus commented at 12:03 pm on April 9, 2024: contributor
    Pinging @furszy, @achow101, @S3RK, as discussed
  8. DrahtBot added the label CI failed on Apr 19, 2024
  9. DrahtBot removed the label CI failed on Apr 23, 2024
  10. in src/wallet/test/coinselection_tests.cpp:69 in 3dff8f0490 outdated
    64+}
    65+
    66+/** Make multiple coins with given effective values */
    67+static void AddCoins(std::vector<COutput>& utxo_pool, std::vector<CAmount> coins, CFeeRate feerate = default_cs_params.m_effective_feerate)
    68+{
    69+    for (int c : coins) {
    


    achow101 commented at 2:55 pm on April 24, 2024:

    In 3dff8f0490b4b92c4adf229a828063dfda6d3a80 “[test] Create coinselection_tests”

    The elements in coins are CAmount, not int.


    murchandamus commented at 7:06 pm on May 31, 2024:
    Thanks, fixed
  11. in src/wallet/test/coinselection_tests.cpp:78 in 3dff8f0490 outdated
    73+
    74+/** Group available coins into OutputGroups */
    75+inline std::vector<OutputGroup>& GroupCoins(const std::vector<COutput>& available_coins, const CoinSelectionParams& cs_params = default_cs_params, bool subtract_fee_outputs = false)
    76+{
    77+    static std::vector<OutputGroup> static_groups;
    78+    static_groups.clear();
    


    achow101 commented at 2:57 pm on April 24, 2024:

    In 3dff8f0490b4b92c4adf229a828063dfda6d3a80 “[test] Create coinselection_tests”

    There doesn’t seem to be a purpose for having a static variable here. We basically treat it as temporary since it’s cleared every time.


    murchandamus commented at 5:01 pm on June 6, 2024:
    Removed the static keyword and the clear as suggested.
  12. in src/wallet/test/coinselection_tests.cpp:75 in 3dff8f0490 outdated
    70+        utxo_pool.push_back(MakeCoin(c, true, 0, feerate));
    71+    }
    72+}
    73+
    74+/** Group available coins into OutputGroups */
    75+inline std::vector<OutputGroup>& GroupCoins(const std::vector<COutput>& available_coins, const CoinSelectionParams& cs_params = default_cs_params, bool subtract_fee_outputs = false)
    


    achow101 commented at 2:58 pm on April 24, 2024:

    In 3dff8f0490b4b92c4adf229a828063dfda6d3a80 “[test] Create coinselection_tests”

    Since the expected pattern is to always GroupCoins(utxo_pool), it might make sense to make utxo_pool a std::vector<OutputGroup> and combine this function with AddCoins.


    murchandamus commented at 3:57 pm on June 27, 2024:
    Amended all the functions to directly create OutputGroups instead.
  13. in src/wallet/test/coinselection_tests.cpp:111 in e286c6470b outdated
    103@@ -104,5 +104,40 @@ static bool EquivalentResult(const SelectionResult& a, const SelectionResult& b)
    104     return ret.first == a_amts.end() && ret.second == b_amts.end();
    105 }
    106 
    107+static void TestBnBSuccess(std::string test_title, std::vector<COutput>& utxo_pool, const CAmount& selection_target, const std::vector<CAmount>& expected_input_amounts, const CFeeRate& feerate = default_cs_params.m_effective_feerate)
    108+{
    109+    SelectionResult expected_result(CAmount(0), SelectionAlgorithm::BNB);
    110+    CAmount expected_amount = 0;
    111+    for (int input_amount : expected_input_amounts) {
    


    achow101 commented at 2:59 pm on April 24, 2024:

    In e286c6470bbaa1358fecb7c5a7e109583d158780 “[test] Recreate simple BnB success tests”

    The elements of expected_input_amounts are CAmount not int.


    murchandamus commented at 8:24 pm on May 31, 2024:
    Thanks, fixed
  14. in src/wallet/test/coinselection_tests.cpp:120 in e286c6470b outdated
    115+        group.Insert(std::make_shared<COutput>(coin), /*ancestors=*/ 0, /*descendants=*/ 0);
    116+        expected_result.AddInput(group);
    117+    }
    118+
    119+    const auto result = SelectCoinsBnB(GroupCoins(utxo_pool), selection_target, /*cost_of_change=*/ default_cs_params.m_cost_of_change, /*max_weight=*/MAX_STANDARD_TX_WEIGHT);
    120+    BOOST_CHECK_MESSAGE(result, "BnB-Success: " + test_title);
    


    achow101 commented at 3:02 pm on April 24, 2024:

    In e286c6470bbaa1358fecb7c5a7e109583d158780 “[test] Recreate simple BnB success tests”

    The *_MESSAGE functions print out the message on failure, not on success. So the message should be something that better indicates what the failure was, not something that might suggest something was successful.


    murchandamus commented at 2:52 pm on June 27, 2024:
    Made all tests output messages indicate what went wrong in the success case.
  15. in src/wallet/test/coinselection_tests.cpp:56 in 3dff8f0490 outdated
    51+}
    52+
    53+static const CoinSelectionParams default_cs_params = init_default_params();
    54+
    55+/** Make one coin that either has a given effective value (default) or a given amount (`is_eff_value = false`). */
    56+static COutput MakeCoin(const CAmount& amount, bool is_eff_value = true, int nInput = 0, CFeeRate feerate = default_cs_params.m_effective_feerate, int custom_spending_vsize = 68)
    


    furszy commented at 7:23 pm on May 1, 2024:
    In 3dff8f0490: As far as I can see, the nInput arg is always 0 in this PR and also in #28985. Can we remove it?

    murchandamus commented at 7:05 pm on May 31, 2024:
    I have removed nInput from the function parameters of MakeCoin(…).

    murchandamus commented at 5:45 pm on June 27, 2024:
    And then actually also removed it as a variable in the function by assuming that there generally is only one output.
  16. in src/wallet/test/coinselection_tests.cpp:23 in 3dff8f0490 outdated
    18+#include <wallet/test/wallet_test_fixture.h>
    19+#include <wallet/wallet.h>
    20+
    21+#include <algorithm>
    22+#include <boost/test/unit_test.hpp>
    23+#include <random>
    


    furszy commented at 7:28 pm on May 1, 2024:

    In https://github.com/bitcoin/bitcoin/commit/3dff8f0490b4b92c4adf229a828063dfda6d3a80:

    I don’t think we need all this includes. For instance, no wallet is used and <wallet/wallet.h> is included, no fee function is used and wallet/fees.h is included, <random.h> and <random> are included.

    Maybe run IOWY to clean this up.


    murchandamus commented at 7:05 pm on May 31, 2024:

    I was able to remove all except for

    0#include <consensus/amount.h>
    1#include <wallet/coinselection.h>
    2#include <wallet/test/wallet_test_fixture.h>
    3
    4#include <boost/test/unit_test.hpp>
    

    I’m not familiar with IOWY and could not turn up anything with a websearch, what is that?


    furszy commented at 4:10 pm on June 27, 2024:

    I’m not familiar with IOWY and could not turn up anything with a websearch, what is that?

    Upps, the acronym is IWYU from include-what-you-use. I wrote it fast as IOWY “include only what you use”. Should stop using acronyms..


    murchandamus commented at 5:45 pm on June 27, 2024:
    I see, thanks for clarifying. I think I cleared out everything that I don’t use.
  17. in src/wallet/test/coinselection_tests.cpp:123 in e286c6470b outdated
    118+
    119+    const auto result = SelectCoinsBnB(GroupCoins(utxo_pool), selection_target, /*cost_of_change=*/ default_cs_params.m_cost_of_change, /*max_weight=*/MAX_STANDARD_TX_WEIGHT);
    120+    BOOST_CHECK_MESSAGE(result, "BnB-Success: " + test_title);
    121+    BOOST_CHECK(EquivalentResult(expected_result, *result));
    122+    BOOST_CHECK_EQUAL(result->GetSelectedValue(), expected_amount);
    123+    expected_result.Clear();
    


    furszy commented at 1:59 pm on May 3, 2024:

    In e286c6470b:

    No need to clear expected_result. It’s created within this function.


    murchandamus commented at 8:25 pm on May 31, 2024:
    Thanks, fixed
  18. furszy commented at 3:08 pm on May 3, 2024: member

    I’m not completely sure about 584e524eb57444d7192df1049cafde9ccc480406. The commit description says

    Originally these tests verified that at a SelectCoins level that a solution with fewer inputs gets preferred at high feerates, and a solution with more inputs gets preferred at low feerates. This outcome relies on the behavior of BnB, so we move these tests under the umbrella of BnB tests.

    It is true that the outcome relies only on the BnB behavior currently but that might not be true in the future. There could be other algorithm clashing with it.

  19. murchandamus force-pushed on Jun 27, 2024
  20. in src/wallet/test/coinselection_tests.cpp:14 in 71606e7bd1 outdated
     9+#include <boost/test/unit_test.hpp>
    10+
    11+namespace wallet {
    12+BOOST_FIXTURE_TEST_SUITE(coinselection_tests, WalletTestingSetup)
    13+
    14+static int nextLockTime = 0;
    


    murchandamus commented at 4:03 pm on June 27, 2024:
    Should be snake_case.
  21. in src/wallet/test/coinselection_tests.cpp:45 in 71606e7bd1 outdated
    40+
    41+/** Make one coin that either has a given effective value (default) or a given amount (`is_eff_value = false`). */
    42+static OutputGroup MakeCoin(const CAmount& amount, bool is_eff_value = true, CoinSelectionParams cs_params = default_cs_params, int custom_spending_vsize = 68)
    43+{
    44+    // Always assume that we only have one input
    45+    const int nInput = 0;
    


    murchandamus commented at 4:04 pm on June 27, 2024:
    nInput is unused, let’s remove it.
  22. in src/wallet/test/coinselection_tests.cpp:52 in 71606e7bd1 outdated
    47+    tx.vout.resize(nInput + 1);
    48+    CAmount fees = cs_params.m_effective_feerate.GetFee(custom_spending_vsize);
    49+    tx.vout[nInput].nValue = amount + int(is_eff_value) * fees;
    50+    tx.nLockTime = nextLockTime++;        // so all transactions get different hashes
    51+    OutputGroup group(cs_params);
    52+    group.Insert(std::make_shared<COutput>(COutPoint(tx.GetHash(), nInput), tx.vout.at(nInput), /*depth=*/ 1, /*input_bytes=*/ custom_spending_vsize, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, /*time=*/ 0, /*from_me=*/ false, /*fees=*/ fees), /*ancestors=*/0, /*descendants=*/0);
    


    murchandamus commented at 4:05 pm on June 27, 2024:
    Remove spaces after comments describing params.
  23. in src/wallet/test/coinselection_tests.cpp:56 in 71606e7bd1 outdated
    51+    OutputGroup group(cs_params);
    52+    group.Insert(std::make_shared<COutput>(COutPoint(tx.GetHash(), nInput), tx.vout.at(nInput), /*depth=*/ 1, /*input_bytes=*/ custom_spending_vsize, /*spendable=*/ true, /*solvable=*/ true, /*safe=*/ true, /*time=*/ 0, /*from_me=*/ false, /*fees=*/ fees), /*ancestors=*/0, /*descendants=*/0);
    53+    return group;
    54+}
    55+
    56+/** Make multiple coins with given effective values */
    


    murchandamus commented at 4:06 pm on June 27, 2024:
    Outdated comment, it’s an OutputGroup not coin now.
  24. in src/wallet/test/coinselection_tests.cpp:84 in e62bf2d346 outdated
    80@@ -80,5 +81,37 @@ static bool EquivalentResult(const SelectionResult& a, const SelectionResult& b)
    81     return ret.first == a_amts.end() && ret.second == b_amts.end();
    82 }
    83 
    84+static void TestBnBSuccess(std::string test_title, std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const std::vector<CAmount>& expected_input_amounts, const CoinSelectionParams cs_params = default_cs_params)
    


    murchandamus commented at 4:07 pm on June 27, 2024:

    Should be a reference.

    0static void TestBnBSuccess(std::string test_title, std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const std::vector<CAmount>& expected_input_amounts, const CoinSelectionParams& cs_params = default_cs_params)
    
  25. in src/wallet/test/coinselection_tests.cpp:94 in e62bf2d346 outdated
    89+        OutputGroup group = MakeCoin(input_amount, true, cs_params);
    90+        expected_amount += group.m_value;
    91+        expected_result.AddInput(group);
    92+    }
    93+
    94+    const auto result = SelectCoinsBnB(utxo_pool, selection_target, /*cost_of_change=*/ default_cs_params.m_cost_of_change, /*max_weight=*/MAX_STANDARD_TX_WEIGHT);
    


    murchandamus commented at 4:08 pm on June 27, 2024:
    0    const auto result = SelectCoinsBnB(utxo_pool, selection_target, /*cost_of_change=*/default_cs_params.m_cost_of_change, /*max_weight=*/MAX_STANDARD_TX_WEIGHT);
    
  26. in src/wallet/test/coinselection_tests.cpp:106 in e62bf2d346 outdated
    101+{
    102+    std::vector<OutputGroup> utxo_pool;
    103+    AddCoins(utxo_pool, {1 * CENT, 3 * CENT, 5 * CENT});
    104+
    105+    // Simple success cases
    106+    TestBnBSuccess("Select smallest UTXO", utxo_pool, /*selection_target=*/ 1 * CENT, /*expected_input_amounts=*/ {1 * CENT});
    


    murchandamus commented at 4:08 pm on June 27, 2024:
    Remove spaces after param comments
  27. in src/wallet/test/coinselection_tests.cpp:113 in e62bf2d346 outdated
    108+    TestBnBSuccess("Select biggest UTXO", utxo_pool, /*selection_target=*/ 5 * CENT, /*expected_input_amounts=*/ {5 * CENT});
    109+    TestBnBSuccess("Select two UTXOs", utxo_pool, /*selection_target=*/ 4 * CENT, /*expected_input_amounts=*/ {1 * CENT, 3 * CENT});
    110+    TestBnBSuccess("Select all UTXOs", utxo_pool, /*selection_target=*/ 9 * CENT, /*expected_input_amounts=*/ {1 * CENT, 3 * CENT, 5 * CENT});
    111+
    112+    // BnB finds changeless solution while overshooting by up to cost_of_change
    113+    TestBnBSuccess("Select upper bound", utxo_pool, /*selection_target=*/ 9 * CENT - default_cs_params.m_cost_of_change, /*expected_input_amounts=*/ {1 * CENT, 3 * CENT, 5 * CENT});
    


    murchandamus commented at 4:10 pm on June 27, 2024:

    Should not overselect, so we could do this with 4×CENT

    0    TestBnBSuccess("Select upper bound", utxo_pool, /*selection_target=*/ 4 * CENT - default_cs_params.m_cost_of_change, /*expected_input_amounts=*/ {1 * CENT, 3 * CENT});
    
  28. in src/wallet/test/coinselection_tests.cpp:199 in dc14005ef1 outdated
    120+    AddCoins(low_feerate_pool, {2 * CENT, 3 * CENT, 5 * CENT, 10 * CENT});
    121+    TestBnBSuccess("Select many inputs at low feerates", low_feerate_pool, /*selection_target=*/ 10 * CENT, /*expected_input_amounts=*/ {2 * CENT, 3 * CENT, 5 * CENT});
    122+
    123+    std::vector<OutputGroup> high_feerate_pool; // 25 sat/vB (greater than long_term_feerate of 10 sat/vB)
    124+    CoinSelectionParams high_feerate_params = init_default_params();
    125+    high_feerate_params.m_effective_feerate = CFeeRate{25'000};
    


    murchandamus commented at 4:11 pm on June 27, 2024:
    0    CoinSelectionParams high_feerate_params = init_default_params();
    1    high_feerate_params.m_effective_feerate = CFeeRate{25'000};
    2    std::vector<OutputGroup> high_feerate_pool; // 25 sat/vB (greater than long_term_feerate of 10 sat/vB)
    
  29. in src/wallet/test/coinselection_tests.cpp:109 in 77e445976a outdated
    103@@ -104,9 +104,18 @@ static void TestBnBSuccess(std::string test_title, std::vector<OutputGroup>& utx
    104     BOOST_CHECK_MESSAGE(result->GetSelectedValue() == expected_amount, "Selected amount mismatch in BnB-Success: " + test_title);
    105 }
    106 
    107+static void TestBnBFail(std::string test_title, std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target)
    108+{
    109+    BOOST_CHECK_MESSAGE(!SelectCoinsBnB(utxo_pool, selection_target, /*cost_of_change=*/ default_cs_params.m_cost_of_change, /*max_weight=*/MAX_STANDARD_TX_WEIGHT), "BnB-Fail: " + test_title);
    


    murchandamus commented at 4:12 pm on June 27, 2024:
    remove spaces
  30. in src/wallet/test/coinselection_tests.cpp:132 in 77e445976a outdated
    127@@ -119,6 +128,14 @@ BOOST_AUTO_TEST_CASE(bnb_test)
    128     // BnB finds changeless solution while overshooting by up to cost_of_change
    129     TestBnBSuccess("Select upper bound", utxo_pool, /*selection_target=*/ 9 * CENT - default_cs_params.m_cost_of_change, /*expected_input_amounts=*/ {1 * CENT, 3 * CENT, 5 * CENT});
    130 
    131+    // BnB fails to find changeless solution when overshooting by cost_of_change + 1 sat
    132+    TestBnBFail("Overshoot upper bound", utxo_pool, /*selection_target=*/ 9 * CENT - default_cs_params.m_cost_of_change - 1);
    


    murchandamus commented at 4:14 pm on June 27, 2024:
    0    TestBnBFail("Overshoot upper bound", utxo_pool, /*selection_target=*/4 * CENT - default_cs_params.m_cost_of_change - 1);
    
  31. in src/wallet/test/coinselection_tests.cpp:117 in 77e445976a outdated
    112 BOOST_AUTO_TEST_CASE(bnb_test)
    113 {
    114     std::vector<OutputGroup> utxo_pool;
    115+
    116+    // Fail for empty UTXO pool
    117+    TestBnBFail("Empty UTXO pool", utxo_pool, /*selection_target=*/ 1 * CENT);
    


    murchandamus commented at 5:04 pm on June 27, 2024:
    Space
  32. murchandamus force-pushed on Jun 27, 2024
  33. murchandamus force-pushed on Jun 27, 2024
  34. murchandamus commented at 5:36 pm on June 27, 2024: contributor
    Alright, should hopefully be ready to review.
  35. murchandamus commented at 5:44 pm on June 27, 2024: contributor

    I’m not completely sure about 584e524. The commit description says

    Originally these tests verified that at a SelectCoins level that a solution with fewer inputs gets preferred at high feerates, and a solution with more inputs gets preferred at low feerates. This outcome relies on the behavior of BnB, so we move these tests under the umbrella of BnB tests.

    It is true that the outcome relies only on the BnB behavior currently but that might not be true in the future. There could be other algorithm clashing with it.

    Yeah, so the old tests assumed that because BnB behaved a certain way, we would get a specific overall outcome. The new tests just check that BnB behaves a certain way. We might still want tests that test the overall outcome as a result from the interaction of multiple coin selection tests, but this one seemed clearly to be testing BnB behavior, and it seemed strange to me to be testing that at the level where the results are combined rather than checking that BnB assumptions are fulfilled by BnB.

  36. hebasto added the label Tests on Aug 16, 2024
  37. hebasto added the label Needs CMake port on Aug 16, 2024
  38. DrahtBot added the label Needs rebase on Sep 2, 2024
  39. maflcko removed the label Needs CMake port on Sep 3, 2024
  40. murchandamus force-pushed on Sep 10, 2024
  41. DrahtBot removed the label Needs rebase on Sep 10, 2024
  42. DrahtBot commented at 11:47 am on September 11, 2024: contributor

    🚧 At least one of the CI tasks failed. Debug: https://github.com/bitcoin/bitcoin/runs/29957535397

    Make sure to run all tests locally, according to the documentation.

    The failure may happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  43. DrahtBot added the label CI failed on Sep 11, 2024
  44. murchandamus force-pushed on Sep 11, 2024
  45. DrahtBot removed the label CI failed on Sep 15, 2024
  46. in src/wallet/test/coinselection_tests.cpp:12 in 3522569d61 outdated
     7+#include <wallet/test/wallet_test_fixture.h>
     8+
     9+#include <boost/test/unit_test.hpp>
    10+
    11+namespace wallet {
    12+BOOST_FIXTURE_TEST_SUITE(coinselection_tests, WalletTestingSetup)
    


    furszy commented at 3:11 pm on September 22, 2024:
    nit: As far as I can see, no test case in this file uses the WalletTestingSetup wallet. So we could save some initialization time on each test case by changing it to TestingSetup. And if any future test requires a wallet, it could be specified in-place.

    murchandamus commented at 6:26 pm on October 31, 2024:
    Thanks, great, taken!
  47. nymius commented at 6:51 pm on October 24, 2024: none
    nit: I have read the test and I don’t have any code related comment yet, but I have noticed that some of the commits are structured with some not written conventions and beside the actual comments about commit message quality in the CONTRIBUTIONS.md file, there are some other conventions used by other contributors too, in a similar fashion to conventional commits with (wallet:, ci:, rpc:). In that spirit, wouldn’t be a good idea to, in case there needs to be a change in some of the commits, to change from [test] to test: or coinselection: to scope the commits a little bit more and move towards a common format? Also, do you think is worth to add these conventions to the CONTRIBUTIONS.md file?
  48. in src/wallet/test/coinselection_tests.cpp:189 in 639a0dd520 outdated
    160+    TestBnBSuccess("Combine smallest 8 of 17 unique UTXOs", doppelganger_pool, /*selection_target=*/8 * CENT, /*expected_input_amounts=*/expected_inputs);
    161+
    162+    // Starting with 18 unique UTXOs of similar effective value we will not find the solution
    163+    AddCoins(doppelganger_pool, {1 * CENT + default_cs_params.m_cost_of_change + 17});
    164+    TestBnBFail("Exhaust looking for smallest 8 of 18 unique UTXOs", doppelganger_pool, /*selection_target=*/8 * CENT);
    165+}
    


    jasonribble commented at 10:28 pm on October 24, 2024:
    nit: perhaps the comment on line 144 can be more descriptive for this part. (or the comments in general can be improved). It’s the strangest test in the group.

    jasonribble commented at 6:19 pm on October 26, 2024:
    maybe you can rename the “18” value as a BnB threshold

    murchandamus commented at 7:07 pm on October 31, 2024:
    I added a longer explanation to this test. Luckily 18 is not generally the limit, it’s just the limit in this artificially crafted case where all of our UTXOs have very similar amounts and we have to pick eight of them to meet the target. Please let me know if the test makes sense now! :)
  49. in src/wallet/test/coinselection_tests.cpp:56 in 639a0dd520 outdated
    51+    OutputGroup group(cs_params);
    52+    group.Insert(std::make_shared<COutput>(COutPoint(tx.GetHash(), 0), tx.vout.at(0), /*depth=*/1, /*input_bytes=*/custom_spending_vsize, /*spendable=*/true, /*solvable=*/true, /*safe=*/true, /*time=*/0, /*from_me=*/false, /*fees=*/fees), /*ancestors=*/0, /*descendants=*/0);
    53+    return group;
    54+}
    55+
    56+/** Make multiple OutpuGroups with the given values as their effective value */
    


    vicariousdrama commented at 5:31 pm on October 28, 2024:
    minor spelling: OutputGroups
  50. in src/wallet/test/coinselection_tests.cpp:35 in 639a0dd520 outdated
    30+        /*tx_noinputs_size=*/11 + 31, //static header size + output size
    31+        /*avoid_partial=*/false,
    32+    };
    33+    dcsp.m_change_fee = /*155 sats=*/dcsp.m_effective_feerate.GetFee(dcsp.change_output_size);
    34+    dcsp.m_cost_of_change = /*204 + 155 sats=*/dcsp.m_discard_feerate.GetFee(dcsp.change_spend_size) + dcsp.m_change_fee;
    35+    dcsp.min_viable_change = /*204 sats=*/dcsp.m_discard_feerate.GetFee(dcsp.change_spend_size);
    


    vicariousdrama commented at 5:33 pm on October 28, 2024:

    Can we eliminate a call to GetFee via reordering assignment?

    0    dcsp.m_change_fee = /*155 sats=*/dcsp.m_effective_feerate.GetFee(dcsp.change_output_size);
    1    dcsp.min_viable_change = /*204 sats=*/dcsp.m_discard_feerate.GetFee(dcsp.change_spend_size);
    2    dcsp.m_cost_of_change = /*204 + 155 sats=*/dcsp.min_viable_change + dcsp.m_change_fee;
    

    murchandamus commented at 6:26 pm on October 31, 2024:
    Thanks, great suggestion. I’ve adopted that change.
  51. in src/wallet/test/CMakeLists.txt:13 in 639a0dd520 outdated
     8@@ -9,6 +9,7 @@ target_sources(test_bitcoin
     9     init_test_fixture.cpp
    10     wallet_test_fixture.cpp
    11     coinselector_tests.cpp
    12+    coinselection_tests.cpp
    


    vicariousdrama commented at 5:56 pm on October 28, 2024:
    Is this name going to set this portion of tests apart enough to be meaningful? It seems only some of the BnB tests that were present in coinselector_tests have been refactored

    vicariousdrama commented at 7:02 pm on October 28, 2024:
    disregard this comment. I skipped your intent in the description

    murchandamus commented at 6:29 pm on October 31, 2024:
    Yeah, as explained, the intention is to rewrite all coinselection tests with transactions that could be encountered in the wild rather than the artificial zero-fee transactions the old tests are using.
  52. in src/wallet/test/coinselection_tests.cpp:188 in 639a0dd520 outdated
    159+    // Among up to 17 unique UTXOs of similar effective value we will find a solution composed of the eight smallest
    160+    TestBnBSuccess("Combine smallest 8 of 17 unique UTXOs", doppelganger_pool, /*selection_target=*/8 * CENT, /*expected_input_amounts=*/expected_inputs);
    161+
    162+    // Starting with 18 unique UTXOs of similar effective value we will not find the solution
    163+    AddCoins(doppelganger_pool, {1 * CENT + default_cs_params.m_cost_of_change + 17});
    164+    TestBnBFail("Exhaust looking for smallest 8 of 18 unique UTXOs", doppelganger_pool, /*selection_target=*/8 * CENT);
    


    vicariousdrama commented at 6:22 pm on October 28, 2024:
    This segment of code appears to me to be intended to refactor the make_hard_case exhaustion tests, but with differing amounts (17,18 vs. 14,17) and construction (amount = iterative CENT + i vs. bitshifting?). Isn’t there double the coins being created in the make_hard_case? I appreciate that this format is more readable, though it’s unclear to me why one should exhaust based on the given coin sizes and quantity. Is this related to src/wallet/coinselection.cpp setting TOTAL_TRIES to 100,000 constraining the useful effective traversal depth?

    murchandamus commented at 6:40 pm on October 31, 2024:
    Yes, this tests that BnB will fail to find the best solution when the attempts exceed the TOTAL_TRIES limit of 100,000. This test follows the same approach but is slightly different than the one in the original tests. I wanted to replace the old test because I found it too difficult to parse, but I came up with my own way of testing it. I have expanded the explanation of what is going on here, and how I created this artificial example that manages to exhaust the limit with only 18 UTXOs.—To be clear, usually we would be able to handle much bigger UTXO pools and still find solutions, this UTXO pool is specifically crafted to cause all possible combinations to be explored.
  53. in src/wallet/test/coinselector_tests.cpp:147 in 639a0dd520 outdated
    133-        add_coin(CAmount{1} << (utxos+i), 2*i, utxo_pool);
    134-        add_coin((CAmount{1} << (utxos+i)) + (CAmount{1} << (utxos-1-i)), 2*i + 1, utxo_pool);
    135-    }
    136-    return target;
    137-}
    138-
    


    vicariousdrama commented at 6:24 pm on October 28, 2024:
    Worth noting that src/bench/coin_selection.cpp makes a copy of the make_hard_case function (commenting as such), so removal here may lead to confusion unless that benchmark is also updated.

    murchandamus commented at 7:10 pm on October 31, 2024:
    Thanks, I’ll make a note to update the benchmark as well.

    yancyribbens commented at 11:51 pm on March 10, 2025:
    I spent a lot of time figuring out how make_hard works. Thanks for replacing it with a version that actually explains itself instead of making it a mensa test.
  54. murchandamus force-pushed on Oct 31, 2024
  55. murchandamus commented at 7:11 pm on October 31, 2024: contributor
    Thanks @furszy, @nymius, @jasonribble, and @vicariousdrama for the review! I updated the commit message names as suggested, adopted all of your proposed changes as indicated, and added more explanation to the test covering the attempt limit.
  56. murchandamus commented at 7:16 pm on October 31, 2024: contributor

    Also, do you think is worth to add these conventions to the CONTRIBUTIONS.md file?

    I don’t know! It would be a good thing to ask in the IRC channel or at the weekly meeting. :)

  57. jasonribble commented at 8:03 pm on November 1, 2024: none

    So C++ noob question. Not sure if this is an appropriate place to ask.

    I’m noticing that you’re calling CFeeRate with an int: https://github.com/bitcoin/bitcoin/blob/280e65d3a7993ea38ba49ae00133a7ba709c193e/src/wallet/test/coinselection_tests.cpp#L20-L38

    Okay that’s cool, clearly it compiles and runs…but how?

    src/policy/feerate.h has the class definition. I don’t see how it’s able to only take an int

    This is my best bet of how it works

    https://github.com/bitcoin/bitcoin/blob/746f88000e8b219b1318839ca1cd7fd9f2057793/src/policy/feerate.h#L38-L43

    it’s using std::integral, maybe doing some weird magic I didn’t know we had. But, I don’t see #include <concepts>.

    Btw, this curiosity all started because my editor highlighted this error

    0no instance of constructor "CFeeRate::CFeeRate" matches the argument listC/C++(289)
    

    Then in src/policy/feerate.h it the IDE says

    namespace "std" has no member "integral"C/C++(135)

    https://github.com/bitcoin/bitcoin/blob/746f88000e8b219b1318839ca1cd7fd9f2057793/src/policy/feerate.h#L38-L76

    I see that it does compile but where does CFeeRate get constructed with only an int?

  58. sipa commented at 8:06 pm on November 1, 2024: member
    @jasonribble template<std::integral I> is the same as template<typename I>, with the added restriction that I must be a type that satisfies the std::integral concept. Since int does satisfy that concept, I can be instantiated as int.
  59. jasonribble commented at 8:21 pm on November 1, 2024: none

    @jasonribble template<std::integral I> is the same as template<typename I>, with the added restriction that I must be a type that satisfies the std::integral concept. Since int does satisfy that concept, I can be instantiated as int.

    Magical. Thank you 🙏

  60. TheCharlatan commented at 8:23 pm on November 1, 2024: contributor

    But, I don’t see #include <concepts>.

    If you check the IWYU logs in the “tidy” CI job you will see that it is indeed missing:

    0[19:28:01.280] /ci_container_base/src/policy/feerate.h should add these lines:
    1[19:28:01.280] #include <concepts>            // for integral
    

    This report is generated on each CI run, but the missing includes are not enforced. This can be confusing, so best to always check the CI output.

  61. jasonribble commented at 0:43 am on November 2, 2024: none

    it is indeed missing

    Oh interesting! Well, I guess not in this important for this PR, but perhaps it should be explicit. Especially so people don’t get those evil red lines

  62. jasonribble approved
  63. jasonribble commented at 11:26 pm on November 2, 2024: none

    ACK

    I went through each of the commits. It is an improvement of the branch and bound selection tests.

  64. ismaelsadeeq commented at 6:53 pm on November 6, 2024: member
    Concept ACK
  65. in src/wallet/test/coinselection_tests.cpp:129 in f3b0593b8b outdated
     97+}
     98+
     99+BOOST_AUTO_TEST_CASE(bnb_test)
    100+{
    101+    std::vector<OutputGroup> utxo_pool;
    102+    AddCoins(utxo_pool, {1 * CENT, 3 * CENT, 5 * CENT});
    


    furszy commented at 10:18 pm on November 8, 2024:
    In f3b0593b8: Can you explain why did you remove the other coins (2 and 4) that were here before? Guess they will be selected and break something if we re-add them because of the algo predilection for unifying utxos?

    murchandamus commented at 10:11 pm on November 13, 2024:
    I just felt that it wasn’t necessary to have four UTXOs to replicate the same coverage. Rather I wanted to be explicit about the cases that are being tested and show that they all work, but I felt that three UTXOs were sufficient to achieve that.
  66. in src/wallet/test/coinselection_tests.cpp:96 in f3b0593b8b outdated
    91+    }
    92+
    93+    const auto result = SelectCoinsBnB(utxo_pool, selection_target, /*cost_of_change=*/default_cs_params.m_cost_of_change, /*max_selection_weight=*/MAX_STANDARD_TX_WEIGHT);
    94+    BOOST_CHECK_MESSAGE(result, "Falsy result in BnB-Success: " + test_title);
    95+    BOOST_CHECK_MESSAGE(EquivalentResult(expected_result, *result), "Result mismatch in BnB-Success: " + test_title);
    96+    BOOST_CHECK_MESSAGE(result->GetSelectedValue() == expected_amount, "Selected amount mismatch in BnB-Success: " + test_title);
    


    furszy commented at 10:21 pm on November 8, 2024:

    In https://github.com/bitcoin/bitcoin/commit/f3b0593b8bd67bc919b21cd636a01813fc5538c8:

    This could output a bit more detailed error message:

    0BOOST_CHECK_MESSAGE(EquivalentResult(expected_result, *result), strprintf("Result mismatch in BnB-Success: %s. Expected %s vs %s", test_title, InputsToString(expected_result), InputsToString(*result)));
    1BOOST_CHECK_MESSAGE(result->GetSelectedValue() == expected_amount, strprintf("Selected amount mismatch in BnB-Success: %s. Expected %d vs %d", test_title, expected_amount, result->GetSelectedValue()));
    

    But you would need something like this too:

    0static std::string InputsToString(const SelectionResult& selection)
    1{
    2    std::string res = "[";
    3    for (const auto& input : selection.GetInputSet()) {
    4        res += util::ToString(input->txout.nValue);
    5    }
    6    return res + "]";
    7}
    

    murchandamus commented at 4:04 pm on February 27, 2025:
    Thanks, great suggestion.
  67. in src/wallet/test/coinselection_tests.cpp:25 in a8bf940ae2 outdated
    18+ * parameters when a diverging value is relevant in the context of a test. */
    19+static CoinSelectionParams init_default_params()
    20+{
    21+    CoinSelectionParams dcsp{
    22+        /*rng_fast*/default_rand,
    23+        /*change_output_size=*/31,
    


    ismaelsadeeq commented at 8:26 pm on November 12, 2024:

    In a8bf940ae20ed5a03a1cc328212fcac3c3462b43 A comment explaining why you selected these magic numbers would be helpful. similar to tx_noinputs_size or an indication if they are just random.

    i.e values when initializing default CSP, and some defaults in MakeCoin


    murchandamus commented at 10:19 pm on November 13, 2024:
    I wanted to use representative values, but also avoid using values whose multiples overlap. So, I used the vsize of P2WPKH inputs and outputs.

    murchandamus commented at 9:51 pm on March 14, 2025:
    I added to the description that the change weights are taken from the P2WPKH output type.

    yancyribbens commented at 7:07 pm on March 15, 2025:

    could also use a const for these magic numbers.

    0P2WPKH_VB_SIZE = 31
    
  68. in src/wallet/test/coinselection_tests.cpp:26 in a8bf940ae2 outdated
    19+static CoinSelectionParams init_default_params()
    20+{
    21+    CoinSelectionParams dcsp{
    22+        /*rng_fast*/default_rand,
    23+        /*change_output_size=*/31,
    24+        /*change_spend_size=*/68,
    


    ismaelsadeeq commented at 8:32 pm on November 12, 2024:
    After this PR, we will have two coin selection test files. Is there a reason why? Wouldn’t it be better to add a commit that renames coinselector_tests to coinselection_tests and modify the test name to coinselection_tests?

    murchandamus commented at 10:22 pm on November 13, 2024:

    As mentioned in the opening comment, I’m looking to completely change the approach. Instead of using absolute values and feerates of zero, transactions in the new tests use real feerates, and spend UTXOs whose effective values are round amounts. Since there are a ton of tests, I expected that it would be too much to get reviewed in a single PR, and migrating from the old test suite to the new test suite would make it obvious which ones had been updated already.

    It could have also been done by renaming first and then updating in place, but this seemed easier to understand, especially because it was going to use a different framework in parallel. Having even more “MakeCoin” and “AddCoin” etc. functions in the same test suite would have been pretty confusing.

  69. in src/wallet/test/coinselection_tests.cpp:65 in a8bf940ae2 outdated
    60+    }
    61+}
    62+
    63+/** Check if SelectionResult a is equivalent to SelectionResult b.
    64+ * Equivalent means same input values, but maybe different inputs (i.e. same value, different prevout) */
    65+static bool EquivalentResult(const SelectionResult& a, const SelectionResult& b)
    


    ismaelsadeeq commented at 9:06 pm on November 12, 2024:
    Since we are checking for Value equivalence, this can just be CheckValueEquivalence for clarity

    murchandamus commented at 3:51 pm on February 27, 2025:
    Okay, I renamed it to “HaveEquivalentValues”
  70. in src/wallet/test/coinselection_tests.cpp:78 in a8bf940ae2 outdated
    73+        b_amts.push_back(coin->txout.nValue);
    74+    }
    75+    std::sort(a_amts.begin(), a_amts.end());
    76+    std::sort(b_amts.begin(), b_amts.end());
    77+
    78+    std::pair<std::vector<CAmount>::iterator, std::vector<CAmount>::iterator> ret = std::mismatch(a_amts.begin(), a_amts.end(), b_amts.begin());
    


    ismaelsadeeq commented at 9:07 pm on November 12, 2024:
    0    auto ret = std::mismatch(a_amts.begin(), a_amts.end(), b_amts.begin());
    
  71. murchandamus force-pushed on Feb 27, 2025
  72. in src/wallet/test/coinselection_tests.cpp:113 in 2787a4fe98 outdated
    108+    }
    109+
    110+    const auto result = SelectCoinsBnB(utxo_pool, selection_target, /*cost_of_change=*/default_cs_params.m_cost_of_change, /*max_selection_weight=*/MAX_STANDARD_TX_WEIGHT);
    111+    BOOST_CHECK_MESSAGE(result, "Falsy result in BnB-Success: " + test_title);
    112+    BOOST_CHECK_MESSAGE(HaveEquivalentValues(expected_result, *result), strprintf("Result mismatch in BnB-Success: %s. Expected %s, but got %s", test_title, InputsToString(expected_result), InputsToString(*result)));
    113+BOOST_CHECK_MESSAGE(result->GetSelectedValue() == expected_amount, strprintf("Selected amount mismatch in BnB-Success: %s. Expected %d, but got %d", test_title, expected_amount, result->GetSelectedValue()));
    


    yancyribbens commented at 6:51 pm on March 10, 2025:
    nit - this should be indented. Right now it’s mis-aligned.
  73. in src/wallet/test/coinselection_tests.cpp:106 in 2787a4fe98 outdated
    100+static void TestBnBSuccess(std::string test_title, std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const std::vector<CAmount>& expected_input_amounts, const CoinSelectionParams& cs_params = default_cs_params)
    101+{
    102+    SelectionResult expected_result(CAmount(0), SelectionAlgorithm::BNB);
    103+    CAmount expected_amount = 0;
    104+    for (CAmount input_amount : expected_input_amounts) {
    105+        OutputGroup group = MakeCoin(input_amount, true, cs_params);
    


    yancyribbens commented at 11:30 pm on March 10, 2025:
    nit - you can simplify this line slightly by using the default arguments instead of passing them explicitly.

    yancyribbens commented at 11:30 pm on March 10, 2025:
    0        OutputGroup group = MakeCoin(input_amount);
    

    murchandamus commented at 9:45 pm on March 14, 2025:

    nit - you can simplify this line slightly by using the default arguments instead of passing them explicitly.

    No, the way this method is written, it is possible to pass in a custom CoinSelectionParams object and it will be passed through to MakeCoin. If I adopted the change you propose, the MakeCoin call here would be limited to the default parameters.


    yancyribbens commented at 11:20 pm on March 14, 2025:
    Ah I see, even though that wouldn’t cause any test failures, that would limit the functions behavior in the future. My mistake.
  74. yancyribbens commented at 11:47 pm on March 10, 2025: contributor

    Concept ACK to refactor the tests. TestBnBSuccess and TestBnBFail are much better and easier to read. Thanks!

    non-representative and effectuate counterintuitive behavior such as feerate = 0 or cost_of_change = 0

    I’m still trying to sus out what the tests are doing now that’s better than before. Most of the current tests use a cost_of_change = 0.5 * COIN, for example. I personally added a test five years ago to test cost_of_change. Also, there are some that do test with varying feerates here that you replaced. Although I do agree that every test should have feerate above zero and existing tests have feerate of zero which means that effective_value == value which is never the case in practice.

  75. murchandamus force-pushed on Mar 14, 2025
  76. murchandamus commented at 10:18 pm on March 14, 2025: contributor

    Concept ACK to refactor the tests. TestBnBSuccess and TestBnBFail are much better and easier to read. Thanks!

    I’m glad to read that.

    non-representative and effectuate counterintuitive behavior such as feerate = 0 or cost_of_change = 0

    I’m still trying to sus out what the tests are doing now that’s better than before.

    For example, our waste calculation used to assume that cost_of_change being zero indicated that the transaction is changeless and any excess should be dropped to fees even when there were enough funds left to create a change output. This can lead to unexpected outcomes when we are comparing two selections with change. We would expect at low feerates the input set with more inputs to be preferred, but instead the selection with the smaller change budget is preferred.

    My motivation for this PR was that I was debugging issues several times and lost hours due to expecting other outcomes than the ones exhibited in the tests, because setting values to zero that should never be zero leads to all sorts of quirky outcomes. Using values that can actually appear in production makes these tests much easier to follow.

    Most of the current tests use a cost_of_change = 0.5 * COIN, for example.

    These new tests do not exhibit the behavior you point out. Which commit is this that you are linking to? As mentioned, this is just the first PR of an attempt to completely replace the old tests, to be followed by more refactors if/when this ever gets merged.

    Also, there are some that do test with varying feerates here that you replaced.

    Yes, I believe that these tests have been replaced with new tests that introduce equivalent coverage. Please see the commit “test: Move BnB feerate sensitivity tests” and the commit message of the commit.

  77. yancyribbens commented at 11:21 pm on March 14, 2025: contributor

    Which commit is this that you are linking to?

    This is master from only a few days ago when I submitted the review feedback.

  78. in src/wallet/test/coinselection_tests.cpp:151 in 29b5efd2a4 outdated
    127@@ -121,6 +128,12 @@ BOOST_AUTO_TEST_CASE(bnb_test)
    128 
    129     // BnB finds changeless solution while overshooting by up to cost_of_change
    130     TestBnBSuccess("Select upper bound", utxo_pool, /*selection_target=*/4 * CENT - default_cs_params.m_cost_of_change, /*expected_input_amounts=*/{1 * CENT, 3 * CENT});
    131+
    132+    // Test skipping of equivalent input sets
    133+    std::vector<OutputGroup> clone_pool;
    134+    AddCoins(clone_pool, {2 * CENT, 7 * CENT, 7 * CENT});
    


    yancyribbens commented at 11:33 pm on March 14, 2025:
    Good idea to simplify this by reducing the size of the set. Two sevens here with a reduced target amount serves the same purpose as five sevens.
  79. in src/wallet/test/coinselection_tests.cpp:127 in 327a989b1c outdated
    122 BOOST_AUTO_TEST_CASE(bnb_test)
    123 {
    124     std::vector<OutputGroup> utxo_pool;
    125+
    126+    // Fail for empty UTXO pool
    127+    TestBnBFail("Empty UTXO pool", utxo_pool, /*selection_target=*/1 * CENT);
    


    yancyribbens commented at 11:38 pm on March 14, 2025:
    This is really minor nit, although I find the /*selection_target=* comments to be more distracting than helpful personally.
  80. in src/wallet/test/coinselection_tests.cpp:155 in 644335ac3d outdated
    150@@ -151,6 +151,41 @@ BOOST_AUTO_TEST_CASE(bnb_test)
    151     AddCoins(clone_pool, {2 * CENT, 7 * CENT, 7 * CENT});
    152     AddDuplicateCoins(clone_pool, 50'000, 5 * CENT);
    153     TestBnBSuccess("Skip equivalent input sets", clone_pool, /*selection_target=*/16 * CENT, /*expected_input_amounts=*/{2 * CENT, 7 * CENT, 7 * CENT});
    154+
    155+    /* Test BnB attempt limit (`TOTAL_TRIES`)
    


    yancyribbens commented at 11:48 pm on March 14, 2025:
    It would be nice if BnB returned the total_tries, like coin_grinder. I recently added that to the rust implementation since I think it’s useful for regression testing. If BnB was ever refactored or had changes it would come in handy imo.

    murchandamus commented at 7:52 pm on March 24, 2025:
    That seems like a good idea, but that’s out of scope for this PR. I have had a refactor of BnB on my todo list for a long time, and it would be part of that, probably.

  81. yancyribbens commented at 0:00 am on March 15, 2025: contributor

    We would expect at low feerates the input set with more inputs to be preferred, but instead the selection with the smaller change budget is preferred.

    I’m familiar with change_budget as it exists in coin-grinder. Beyond that, I’m not sure how that ties in to BnB and SRD.

    Please see the commit “test: Move BnB feerate sensitivity tests” and the commit message of the commit.

    I reviewed the commits, and it appears that the test coverage is equivalent. It might be helpful to document a baseline of what we want to be sure is tested for each algorithm at some point, understanding that extended coverage is handled by fuzz testing/mutation testing/property testing.

  82. test: Create coinselection_tests
    Adds a Test Suite, default coin selection parameters as well as helper
    functions for creating available coins and to check results.
    9773192b83
  83. test: Recreate simple BnB success tests 66200b3ffa
  84. in src/wallet/test/coinselection_tests.cpp:194 in 644335ac3d outdated
    189+}
    190+
    191+BOOST_AUTO_TEST_CASE(bnb_feerate_sensitivity_test)
    192+{
    193+    // Create sets of UTXOs with the same effective amounts at different feerates (but different absolute amounts)
    194+    std::vector<OutputGroup> low_feerate_pool; // 5 sat/vB (default, and lower than long_term_feerate of 10 sat/vB)
    


    yancyribbens commented at 7:40 pm on March 24, 2025:

    This file has some strange formatting that does not show up in Github. My editor (Vim) just shows a character that seems like a translation error.

    5 sat

    I opened the file with xxd and the translation is 35e2 80af 7361 742f. 35 is the hex for 5 in ascii, and 73 is the hex for s. It looks like 80 is extended hex for the euro sign and e2 and af also have extended hex meanings. There are more of these weird encodings thought the file.


    murchandamus commented at 8:55 pm on March 25, 2025:
    0xe280af is the UTF-8 encoding for a narrow no-break space: https://www.fileformat.info/info/unicode/char/202f/index.htm

    yancyribbens commented at 3:13 pm on March 26, 2025:
    Thanks. It’s sort of interesting that this sort of thing doesn’t even appear in the Github review. This implies that if one only reviews by Github diff, there is hidden characters that can go in un-noticed. Presumably in this case, there is some editors that can translated this UTF-8 encoding.
  85. murchandamus force-pushed on Mar 24, 2025
  86. DrahtBot added the label CI failed on Mar 24, 2025
  87. DrahtBot commented at 8:01 pm on March 24, 2025: contributor

    🚧 At least one of the CI tasks failed. Debug: https://github.com/bitcoin/bitcoin/runs/39320450081

    Try to run the tests locally, according to the documentation. However, a CI failure may still happen due to a number of reasons, for example:

    • Possibly due to a silent merge conflict (the changes in this pull request being incompatible with the current code in the target branch). If so, make sure to rebase on the latest commit of the target branch.

    • A sanitizer issue, which can only be found by compiling with the sanitizer and running the affected test.

    • An intermittent issue.

    Leave a comment here, if you need help tracking down a confusing failure.

  88. test: Move BnB feerate sensitivity tests
    Originally these tests verified that at a SelectCoins level that a
    solution with fewer inputs gets preferred at high feerates, and a
    solution with more inputs gets preferred at low feerates. This outcome
    relies on the behavior of BnB, so we move these tests under the umbrella
    of BnB tests.
    
    Originally these tests relied on SFFO to work.
    afd4b807ff
  89. test: Recreate BnB clone skipping test 9d7db26b7b
  90. test: Recreate simple BnB failure tests 65521465da
  91. test: Remove redundant repeated test
    We do not need to repeat the same test multiple times because BnB is
    deterministic and will therefore always have the same outcome.
    Additionally, this test was redundant because it repeats the "Smallest
    combination too big" test.
    28574e2c4f
  92. murchandamus force-pushed on Mar 24, 2025
  93. DrahtBot removed the label CI failed on Mar 24, 2025
  94. in src/wallet/test/coinselection_tests.cpp:162 in 0f39b6b919 outdated
    157+     * Generally, on a diverse UTXO pool BnB will quickly pass over UTXOs bigger than the target and then start
    158+     * combining small counts of UTXOs that in sum remain under the selection_target+cost_of_change. When there are
    159+     * multiple UTXOs that have matching amount and cost, combinations with equivalent input sets are skipped. The UTXO
    160+     * pool for this test is specifically crafted to create as much branching as possible. The selection target is
    161+     * 8 CENT while all UTXOs are slightly bigger than 1 CENT. The smallest eight are 100,000…100,007 sats, while the larger
    162+     * ten are 100,009,…,100,018 sats plus cost_of_change.
    


    murchandamus commented at 8:18 pm on March 31, 2025:
    0     * nine are 100,008,…,100,016 sats plus cost_of_change.
    
  95. test: Recreate BnB iteration exhaustion test 1fb24c68a1
  96. murchandamus force-pushed on Mar 31, 2025
  97. yancyribbens referenced this in commit f3c74578ed on Apr 4, 2025
  98. yancyribbens referenced this in commit 3cb837c78f on Apr 4, 2025
  99. yancyribbens referenced this in commit 7f8271a60e on Apr 4, 2025
  100. yancyribbens referenced this in commit 25fc7b8a01 on Apr 4, 2025
  101. yancyribbens referenced this in commit c9f17d0a4b on Apr 4, 2025
  102. yancyribbens referenced this in commit ada4dc6f55 on Apr 4, 2025
  103. yancyribbens referenced this in commit e92aa70950 on Apr 5, 2025
  104. yancyribbens referenced this in commit ffa9b3f1fb on Apr 5, 2025
  105. yancyribbens referenced this in commit 34acfb0585 on Apr 5, 2025
  106. yancyribbens referenced this in commit fe8867ee33 on Apr 5, 2025
  107. yancyribbens referenced this in commit e52eaf99a4 on Apr 5, 2025
  108. yancyribbens referenced this in commit e87213779f on Apr 5, 2025
  109. yancyribbens referenced this in commit 44ed25f893 on Apr 5, 2025
  110. yancyribbens referenced this in commit c474a99a31 on Apr 5, 2025
  111. yancyribbens referenced this in commit c86b45ec3c on Apr 5, 2025
  112. yancyribbens referenced this in commit cb6973bead on Apr 5, 2025
  113. yancyribbens referenced this in commit 11c984d81b on Apr 5, 2025
  114. yancyribbens referenced this in commit 8fdf264412 on Apr 5, 2025
  115. yancyribbens referenced this in commit 0734ae9ef8 on Apr 5, 2025
  116. yancyribbens referenced this in commit faccbb23e4 on Apr 5, 2025
  117. yancyribbens referenced this in commit 915b200b73 on Apr 5, 2025
  118. yancyribbens referenced this in commit fe661d4fed on Apr 5, 2025
  119. yancyribbens referenced this in commit e4812122f8 on Apr 5, 2025
  120. yancyribbens referenced this in commit 4edcdf04bf on Apr 5, 2025
  121. yancyribbens referenced this in commit 7645727e7c on Apr 5, 2025
  122. yancyribbens referenced this in commit 2fc202628a on Apr 5, 2025
  123. yancyribbens referenced this in commit 0a2dc99f03 on Apr 5, 2025
  124. yancyribbens referenced this in commit 7327327fe3 on Apr 6, 2025
  125. yancyribbens referenced this in commit 26b576d724 on Apr 6, 2025
  126. yancyribbens referenced this in commit 2066bbb55a on Apr 6, 2025
  127. yancyribbens referenced this in commit b2fff77f3d on Apr 6, 2025
  128. yancyribbens referenced this in commit c2976ec6ef on Apr 6, 2025
  129. yancyribbens referenced this in commit 06e641dc78 on Apr 6, 2025
  130. yancyribbens referenced this in commit 1a1fb6cac6 on Apr 6, 2025
  131. yancyribbens referenced this in commit c54f2afad0 on Apr 6, 2025
  132. yancyribbens referenced this in commit 54d2aff1c9 on Apr 6, 2025
  133. yancyribbens referenced this in commit 7ae6424a8b on Apr 6, 2025
  134. yancyribbens referenced this in commit bd1d3a49f5 on Apr 6, 2025
  135. yancyribbens referenced this in commit d4f6e2601c on Apr 7, 2025
  136. yancyribbens referenced this in commit 87e8fccd7f on Apr 8, 2025
  137. yancyribbens referenced this in commit 2decd06fc1 on Apr 8, 2025
  138. yancyribbens referenced this in commit 92a9e9fac0 on Apr 8, 2025
  139. yancyribbens referenced this in commit a0c8a14a39 on Apr 8, 2025
  140. yancyribbens referenced this in commit 6e78d745ff on Apr 8, 2025
  141. yancyribbens referenced this in commit 707e4c6b70 on Apr 9, 2025
  142. yancyribbens referenced this in commit 93ed143f12 on Apr 10, 2025
  143. monlovesmango commented at 6:09 pm on April 16, 2025: contributor

    As discussed during Bitcoin Core Review Club, at least one test with 0 fee rate should probably be added to avoid test coverage regression.

    Thanks for hosting Murch!

  144. in src/wallet/test/CMakeLists.txt:13 in 1fb24c68a1
     9@@ -10,6 +10,7 @@ target_sources(test_bitcoin
    10     wallet_test_fixture.cpp
    11     db_tests.cpp
    12     coinselector_tests.cpp
    13+    coinselection_tests.cpp
    


    w0xlt commented at 0:39 am on April 17, 2025:
    nit: Since coinselection_tests.cpp is introduced in the first commit, this change may be there as well.
  145. in src/wallet/test/coinselection_tests.cpp:91 in 1fb24c68a1
    86+
    87+    auto ret = std::mismatch(a_amts.begin(), a_amts.end(), b_amts.begin());
    88+    return ret.first == a_amts.end() && ret.second == b_amts.end();
    89+}
    90+
    91+static std::string InputsToString(const SelectionResult& selection)
    


    w0xlt commented at 0:42 am on April 17, 2025:

    nit: Just for clarity

    0static std::string InputAmountsToString(const SelectionResult& selection)
    
  146. in src/wallet/test/coinselection_tests.cpp:101 in 1fb24c68a1
     96+        res += " ";
     97+    }
     98+    return res + "]";
     99+}
    100+
    101+static void TestBnBSuccess(std::string test_title, std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const std::vector<CAmount>& expected_input_amounts, const CoinSelectionParams& cs_params = default_cs_params, int custom_spending_vsize = 68)
    


    w0xlt commented at 0:46 am on April 17, 2025:
    nit: This function is added in the commit https://github.com/bitcoin/bitcoin/pull/29532/commits/66200b3ffa21605fc3234ccbda7b424381f3319a and then modified in the commit https://github.com/bitcoin/bitcoin/pull/29532/commits/afd4b807ff1300e4f74ceab6a683f3ff1376369d. It can be added directly as it is in the latest commit.
  147. w0xlt commented at 0:50 am on April 17, 2025: contributor
    nit: Perhaps the commit descriptions (“BnB rate sensitivity tests”, “simple BnB failure tests”, and “BnB iteration exhaustion test”, for example) could become functions for clarity (not necessarily new test cases).
  148. w0xlt commented at 0:51 am on April 17, 2025: contributor
    nit: Some commits can be squashed to avoid warnings like “unused function”.

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: 2025-04-19 03:12 UTC

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