aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/test')
-rw-r--r--src/wallet/test/coinselector_tests.cpp394
-rw-r--r--src/wallet/test/db_tests.cpp4
-rw-r--r--src/wallet/test/fuzz/notifications.cpp2
-rw-r--r--src/wallet/test/init_test_fixture.cpp6
-rw-r--r--src/wallet/test/init_test_fixture.h6
-rw-r--r--src/wallet/test/init_tests.cpp18
-rw-r--r--src/wallet/test/ismine_tests.cpp4
-rw-r--r--src/wallet/test/psbt_wallet_tests.cpp4
-rw-r--r--src/wallet/test/scriptpubkeyman_tests.cpp4
-rw-r--r--src/wallet/test/spend_tests.cpp2
-rw-r--r--src/wallet/test/util.cpp2
-rw-r--r--src/wallet/test/util.h5
-rw-r--r--src/wallet/test/wallet_crypto_tests.cpp2
-rw-r--r--src/wallet/test/wallet_test_fixture.cpp6
-rw-r--r--src/wallet/test/wallet_test_fixture.h6
-rw-r--r--src/wallet/test/wallet_tests.cpp15
-rw-r--r--src/wallet/test/wallet_transaction_tests.cpp2
-rw-r--r--src/wallet/test/walletdb_tests.cpp2
18 files changed, 290 insertions, 194 deletions
diff --git a/src/wallet/test/coinselector_tests.cpp b/src/wallet/test/coinselector_tests.cpp
index 0acd8a811f..b9f12158ca 100644
--- a/src/wallet/test/coinselector_tests.cpp
+++ b/src/wallet/test/coinselector_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2020 The Bitcoin Core developers
+// Copyright (c) 2017-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -14,9 +14,11 @@
#include <wallet/test/wallet_test_fixture.h>
#include <wallet/wallet.h>
+#include <algorithm>
#include <boost/test/unit_test.hpp>
#include <random>
+namespace wallet {
BOOST_FIXTURE_TEST_SUITE(coinselector_tests, WalletTestingSetup)
// how many times to run all the tests to have a chance to catch errors that only show up with particular random shuffles
@@ -31,20 +33,35 @@ typedef std::set<CInputCoin> CoinSet;
static const CoinEligibilityFilter filter_standard(1, 6, 0);
static const CoinEligibilityFilter filter_confirmed(1, 1, 0);
static const CoinEligibilityFilter filter_standard_extra(6, 6, 0);
+static int nextLockTime = 0;
static void add_coin(const CAmount& nValue, int nInput, std::vector<CInputCoin>& set)
{
CMutableTransaction tx;
tx.vout.resize(nInput + 1);
tx.vout[nInput].nValue = nValue;
+ tx.nLockTime = nextLockTime++; // so all transactions get different hashes
set.emplace_back(MakeTransactionRef(tx), nInput);
}
+static void add_coin(const CAmount& nValue, int nInput, SelectionResult& result)
+{
+ CMutableTransaction tx;
+ tx.vout.resize(nInput + 1);
+ tx.vout[nInput].nValue = nValue;
+ tx.nLockTime = nextLockTime++; // so all transactions get different hashes
+ CInputCoin coin(MakeTransactionRef(tx), nInput);
+ OutputGroup group;
+ group.Insert(coin, 1, false, 0, 0, true);
+ result.AddInput(group);
+}
+
static void add_coin(const CAmount& nValue, int nInput, CoinSet& set, CAmount fee = 0, CAmount long_term_fee = 0)
{
CMutableTransaction tx;
tx.vout.resize(nInput + 1);
tx.vout[nInput].nValue = nValue;
+ tx.nLockTime = nextLockTime++; // so all transactions get different hashes
CInputCoin coin(MakeTransactionRef(tx), nInput);
coin.effective_value = nValue - fee;
coin.m_fee = fee;
@@ -54,7 +71,6 @@ static void add_coin(const CAmount& nValue, int nInput, CoinSet& set, CAmount fe
static void add_coin(std::vector<COutput>& coins, CWallet& wallet, const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0, bool spendable = false)
{
- static int nextLockTime = 0;
CMutableTransaction tx;
tx.nLockTime = nextLockTime++; // so all transactions get different hashes
tx.vout.resize(nInput + 1);
@@ -86,10 +102,30 @@ static void add_coin(std::vector<COutput>& coins, CWallet& wallet, const CAmount
coins.push_back(output);
}
-static bool equal_sets(CoinSet a, CoinSet b)
+/** Check if SelectionResult a is equivalent to SelectionResult b.
+ * Equivalent means same input values, but maybe different inputs (i.e. same value, different prevout) */
+static bool EquivalentResult(const SelectionResult& a, const SelectionResult& b)
+{
+ std::vector<CAmount> a_amts;
+ std::vector<CAmount> b_amts;
+ for (const auto& coin : a.GetInputSet()) {
+ a_amts.push_back(coin.txout.nValue);
+ }
+ for (const auto& coin : b.GetInputSet()) {
+ b_amts.push_back(coin.txout.nValue);
+ }
+ std::sort(a_amts.begin(), a_amts.end());
+ std::sort(b_amts.begin(), b_amts.end());
+
+ std::pair<std::vector<CAmount>::iterator, std::vector<CAmount>::iterator> ret = std::mismatch(a_amts.begin(), a_amts.end(), b_amts.begin());
+ return ret.first == a_amts.end() && ret.second == b_amts.end();
+}
+
+/** Check if this selection is equal to another one. Equal means same inputs (i.e same value and prevout) */
+static bool EqualResult(const SelectionResult& a, const SelectionResult& b)
{
- std::pair<CoinSet::iterator, CoinSet::iterator> ret = mismatch(a.begin(), a.end(), b.begin());
- return ret.first == a.end() && ret.second == b.end();
+ std::pair<CoinSet::iterator, CoinSet::iterator> ret = std::mismatch(a.GetInputSet().begin(), a.GetInputSet().end(), b.GetInputSet().begin());
+ return ret.first == a.GetInputSet().end() && ret.second == b.GetInputSet().end();
}
static CAmount make_hard_case(int utxos, std::vector<CInputCoin>& utxo_pool)
@@ -142,17 +178,14 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
{
// Setup
std::vector<CInputCoin> utxo_pool;
- CoinSet selection;
- CoinSet actual_selection;
- CAmount value_ret = 0;
+ SelectionResult expected_result(CAmount(0));
/////////////////////////
// Known Outcome tests //
/////////////////////////
// Empty utxo pool
- BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 1 * CENT, 0.5 * CENT, selection, value_ret));
- selection.clear();
+ BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 1 * CENT, 0.5 * CENT));
// Add utxos
add_coin(1 * CENT, 1, utxo_pool);
@@ -161,87 +194,86 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
add_coin(4 * CENT, 4, utxo_pool);
// Select 1 Cent
- add_coin(1 * CENT, 1, actual_selection);
- BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 1 * CENT, 0.5 * CENT, selection, value_ret));
- BOOST_CHECK(equal_sets(selection, actual_selection));
- BOOST_CHECK_EQUAL(value_ret, 1 * CENT);
- actual_selection.clear();
- selection.clear();
+ add_coin(1 * CENT, 1, expected_result);
+ const auto result1 = SelectCoinsBnB(GroupCoins(utxo_pool), 1 * CENT, 0.5 * CENT);
+ BOOST_CHECK(result1);
+ BOOST_CHECK(EquivalentResult(expected_result, *result1));
+ BOOST_CHECK_EQUAL(result1->GetSelectedValue(), 1 * CENT);
+ expected_result.Clear();
// Select 2 Cent
- add_coin(2 * CENT, 2, actual_selection);
- BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 2 * CENT, 0.5 * CENT, selection, value_ret));
- BOOST_CHECK(equal_sets(selection, actual_selection));
- BOOST_CHECK_EQUAL(value_ret, 2 * CENT);
- actual_selection.clear();
- selection.clear();
+ add_coin(2 * CENT, 2, expected_result);
+ const auto result2 = SelectCoinsBnB(GroupCoins(utxo_pool), 2 * CENT, 0.5 * CENT);
+ BOOST_CHECK(result2);
+ BOOST_CHECK(EquivalentResult(expected_result, *result2));
+ BOOST_CHECK_EQUAL(result2->GetSelectedValue(), 2 * CENT);
+ expected_result.Clear();
// Select 5 Cent
- add_coin(4 * CENT, 4, actual_selection);
- add_coin(1 * CENT, 1, actual_selection);
- BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 5 * CENT, 0.5 * CENT, selection, value_ret));
- BOOST_CHECK(equal_sets(selection, actual_selection));
- BOOST_CHECK_EQUAL(value_ret, 5 * CENT);
- actual_selection.clear();
- selection.clear();
+ add_coin(4 * CENT, 4, expected_result);
+ add_coin(1 * CENT, 1, expected_result);
+ const auto result3 = SelectCoinsBnB(GroupCoins(utxo_pool), 5 * CENT, 0.5 * CENT);
+ BOOST_CHECK(result3);
+ BOOST_CHECK(EquivalentResult(expected_result, *result3));
+ BOOST_CHECK_EQUAL(result3->GetSelectedValue(), 5 * CENT);
+ expected_result.Clear();
// Select 11 Cent, not possible
- BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 11 * CENT, 0.5 * CENT, selection, value_ret));
- actual_selection.clear();
- selection.clear();
+ BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 11 * CENT, 0.5 * CENT));
+ expected_result.Clear();
// Cost of change is greater than the difference between target value and utxo sum
- add_coin(1 * CENT, 1, actual_selection);
- BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 0.9 * CENT, 0.5 * CENT, selection, value_ret));
- BOOST_CHECK_EQUAL(value_ret, 1 * CENT);
- BOOST_CHECK(equal_sets(selection, actual_selection));
- actual_selection.clear();
- selection.clear();
+ add_coin(1 * CENT, 1, expected_result);
+ const auto result4 = SelectCoinsBnB(GroupCoins(utxo_pool), 0.9 * CENT, 0.5 * CENT);
+ BOOST_CHECK(result4);
+ BOOST_CHECK_EQUAL(result4->GetSelectedValue(), 1 * CENT);
+ BOOST_CHECK(EquivalentResult(expected_result, *result4));
+ expected_result.Clear();
// Cost of change is less than the difference between target value and utxo sum
- BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 0.9 * CENT, 0, selection, value_ret));
- actual_selection.clear();
- selection.clear();
+ BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 0.9 * CENT, 0));
+ expected_result.Clear();
// Select 10 Cent
add_coin(5 * CENT, 5, utxo_pool);
- add_coin(5 * CENT, 5, actual_selection);
- add_coin(4 * CENT, 4, actual_selection);
- add_coin(1 * CENT, 1, actual_selection);
- BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 10 * CENT, 0.5 * CENT, selection, value_ret));
- BOOST_CHECK(equal_sets(selection, actual_selection));
- BOOST_CHECK_EQUAL(value_ret, 10 * CENT);
- actual_selection.clear();
- selection.clear();
+ add_coin(5 * CENT, 5, expected_result);
+ add_coin(4 * CENT, 4, expected_result);
+ add_coin(1 * CENT, 1, expected_result);
+ const auto result5 = SelectCoinsBnB(GroupCoins(utxo_pool), 10 * CENT, 0.5 * CENT);
+ BOOST_CHECK(result5);
+ BOOST_CHECK(EquivalentResult(expected_result, *result5));
+ BOOST_CHECK_EQUAL(result5->GetSelectedValue(), 10 * CENT);
+ expected_result.Clear();
// Negative effective value
// Select 10 Cent but have 1 Cent not be possible because too small
- add_coin(5 * CENT, 5, actual_selection);
- add_coin(3 * CENT, 3, actual_selection);
- add_coin(2 * CENT, 2, actual_selection);
- BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 10 * CENT, 5000, selection, value_ret));
- BOOST_CHECK_EQUAL(value_ret, 10 * CENT);
+ add_coin(5 * CENT, 5, expected_result);
+ add_coin(3 * CENT, 3, expected_result);
+ add_coin(2 * CENT, 2, expected_result);
+ const auto result6 = SelectCoinsBnB(GroupCoins(utxo_pool), 10 * CENT, 5000);
+ BOOST_CHECK(result6);
+ BOOST_CHECK_EQUAL(result6->GetSelectedValue(), 10 * CENT);
// FIXME: this test is redundant with the above, because 1 Cent is selected, not "too small"
- // BOOST_CHECK(equal_sets(selection, actual_selection));
+ // BOOST_CHECK(EquivalentResult(expected_result, *result));
// Select 0.25 Cent, not possible
- BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 0.25 * CENT, 0.5 * CENT, selection, value_ret));
- actual_selection.clear();
- selection.clear();
+ BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 0.25 * CENT, 0.5 * CENT));
+ expected_result.Clear();
// Iteration exhaustion test
CAmount target = make_hard_case(17, utxo_pool);
- BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), target, 0, selection, value_ret)); // Should exhaust
+ BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), target, 0)); // Should exhaust
target = make_hard_case(14, utxo_pool);
- BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), target, 0, selection, value_ret)); // Should not exhaust
+ const auto result7 = SelectCoinsBnB(GroupCoins(utxo_pool), target, 0); // Should not exhaust
+ BOOST_CHECK(result7);
// Test same value early bailout optimization
utxo_pool.clear();
- add_coin(7 * CENT, 7, actual_selection);
- add_coin(7 * CENT, 7, actual_selection);
- add_coin(7 * CENT, 7, actual_selection);
- add_coin(7 * CENT, 7, actual_selection);
- add_coin(2 * CENT, 7, actual_selection);
+ add_coin(7 * CENT, 7, expected_result);
+ add_coin(7 * CENT, 7, expected_result);
+ add_coin(7 * CENT, 7, expected_result);
+ add_coin(7 * CENT, 7, expected_result);
+ add_coin(2 * CENT, 7, expected_result);
add_coin(7 * CENT, 7, utxo_pool);
add_coin(7 * CENT, 7, utxo_pool);
add_coin(7 * CENT, 7, utxo_pool);
@@ -250,9 +282,10 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
for (int i = 0; i < 50000; ++i) {
add_coin(5 * CENT, 7, utxo_pool);
}
- BOOST_CHECK(SelectCoinsBnB(GroupCoins(utxo_pool), 30 * CENT, 5000, selection, value_ret));
- BOOST_CHECK_EQUAL(value_ret, 30 * CENT);
- BOOST_CHECK(equal_sets(selection, actual_selection));
+ const auto result8 = SelectCoinsBnB(GroupCoins(utxo_pool), 30 * CENT, 5000);
+ BOOST_CHECK(result8);
+ BOOST_CHECK_EQUAL(result8->GetSelectedValue(), 30 * CENT);
+ BOOST_CHECK(EquivalentResult(expected_result, *result8));
////////////////////
// Behavior tests //
@@ -264,7 +297,7 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
}
// Run 100 times, to make sure it is never finding a solution
for (int i = 0; i < 100; ++i) {
- BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 1 * CENT, 2 * CENT, selection, value_ret));
+ BOOST_CHECK(!SelectCoinsBnB(GroupCoins(utxo_pool), 1 * CENT, 2 * CENT));
}
// Make sure that effective value is working in AttemptSelection when BnB is used
@@ -280,20 +313,19 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
wallet->SetupDescriptorScriptPubKeyMans();
std::vector<COutput> coins;
- CoinSet setCoinsRet;
- CAmount nValueRet;
add_coin(coins, *wallet, 1);
coins.at(0).nInputBytes = 40; // Make sure that it has a negative effective value. The next check should assert if this somehow got through. Otherwise it will fail
- BOOST_CHECK(!SelectCoinsBnB(GroupCoins(coins), 1 * CENT, coin_selection_params_bnb.m_cost_of_change, setCoinsRet, nValueRet));
+ BOOST_CHECK(!SelectCoinsBnB(GroupCoins(coins), 1 * CENT, coin_selection_params_bnb.m_cost_of_change));
// Test fees subtracted from output:
coins.clear();
add_coin(coins, *wallet, 1 * CENT);
coins.at(0).nInputBytes = 40;
coin_selection_params_bnb.m_subtract_fee_outputs = true;
- BOOST_CHECK(SelectCoinsBnB(GroupCoins(coins), 1 * CENT, coin_selection_params_bnb.m_cost_of_change, setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1 * CENT);
+ const auto result9 = SelectCoinsBnB(GroupCoins(coins), 1 * CENT, coin_selection_params_bnb.m_cost_of_change);
+ BOOST_CHECK(result9);
+ BOOST_CHECK_EQUAL(result9->GetSelectedValue(), 1 * CENT);
}
{
@@ -304,8 +336,6 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
wallet->SetupDescriptorScriptPubKeyMans();
std::vector<COutput> coins;
- CoinSet setCoinsRet;
- CAmount nValueRet;
add_coin(coins, *wallet, 5 * CENT, 6 * 24, false, 0, true);
add_coin(coins, *wallet, 3 * CENT, 6 * 24, false, 0, true);
@@ -314,7 +344,8 @@ BOOST_AUTO_TEST_CASE(bnb_search_test)
coin_control.fAllowOtherInputs = true;
coin_control.Select(COutPoint(coins.at(0).tx->GetHash(), coins.at(0).i));
coin_selection_params_bnb.m_effective_feerate = CFeeRate(0);
- BOOST_CHECK(SelectCoins(*wallet, coins, 10 * CENT, setCoinsRet, nValueRet, coin_control, coin_selection_params_bnb));
+ const auto result10 = SelectCoins(*wallet, coins, 10 * CENT, coin_control, coin_selection_params_bnb);
+ BOOST_CHECK(result10);
}
}
@@ -326,8 +357,6 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
wallet->SetupDescriptorScriptPubKeyMans();
- CoinSet setCoinsRet, setCoinsRet2;
- CAmount nValueRet;
std::vector<COutput> coins;
// test multiple times to allow for differences in the shuffle order
@@ -336,25 +365,27 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
coins.clear();
// with an empty wallet we can't even pay one cent
- BOOST_CHECK(!KnapsackSolver(1 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_standard), setCoinsRet, nValueRet));
+ BOOST_CHECK(!KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_standard), 1 * CENT));
add_coin(coins, *wallet, 1*CENT, 4); // add a new 1 cent coin
// with a new 1 cent coin, we still can't find a mature 1 cent
- BOOST_CHECK(!KnapsackSolver(1 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_standard), setCoinsRet, nValueRet));
+ BOOST_CHECK(!KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_standard), 1 * CENT));
// but we can find a new 1 cent
- BOOST_CHECK(KnapsackSolver(1 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1 * CENT);
+ const auto result1 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 1 * CENT);
+ BOOST_CHECK(result1);
+ BOOST_CHECK_EQUAL(result1->GetSelectedValue(), 1 * CENT);
add_coin(coins, *wallet, 2*CENT); // add a mature 2 cent coin
// we can't make 3 cents of mature coins
- BOOST_CHECK(!KnapsackSolver(3 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_standard), setCoinsRet, nValueRet));
+ BOOST_CHECK(!KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_standard), 3 * CENT));
// we can make 3 cents of new coins
- BOOST_CHECK(KnapsackSolver(3 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 3 * CENT);
+ const auto result2 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 3 * CENT);
+ BOOST_CHECK(result2);
+ BOOST_CHECK_EQUAL(result2->GetSelectedValue(), 3 * CENT);
add_coin(coins, *wallet, 5*CENT); // add a mature 5 cent coin,
add_coin(coins, *wallet, 10*CENT, 3, true); // a new 10 cent coin sent from one of our own addresses
@@ -363,35 +394,41 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
// now we have new: 1+10=11 (of which 10 was self-sent), and mature: 2+5+20=27. total = 38
// we can't make 38 cents only if we disallow new coins:
- BOOST_CHECK(!KnapsackSolver(38 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_standard), setCoinsRet, nValueRet));
+ BOOST_CHECK(!KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_standard), 38 * CENT));
// we can't even make 37 cents if we don't allow new coins even if they're from us
- BOOST_CHECK(!KnapsackSolver(38 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_standard_extra), setCoinsRet, nValueRet));
+ BOOST_CHECK(!KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_standard_extra), 38 * CENT));
// but we can make 37 cents if we accept new coins from ourself
- BOOST_CHECK(KnapsackSolver(37 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_standard), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 37 * CENT);
+ const auto result3 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_standard), 37 * CENT);
+ BOOST_CHECK(result3);
+ BOOST_CHECK_EQUAL(result3->GetSelectedValue(), 37 * CENT);
// and we can make 38 cents if we accept all new coins
- BOOST_CHECK(KnapsackSolver(38 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 38 * CENT);
+ const auto result4 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 38 * CENT);
+ BOOST_CHECK(result4);
+ BOOST_CHECK_EQUAL(result4->GetSelectedValue(), 38 * CENT);
// try making 34 cents from 1,2,5,10,20 - we can't do it exactly
- BOOST_CHECK(KnapsackSolver(34 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 35 * CENT); // but 35 cents is closest
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible)
+ const auto result5 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 34 * CENT);
+ BOOST_CHECK(result5);
+ BOOST_CHECK_EQUAL(result5->GetSelectedValue(), 35 * CENT); // but 35 cents is closest
+ BOOST_CHECK_EQUAL(result5->GetInputSet().size(), 3U); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible)
// when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5
- BOOST_CHECK(KnapsackSolver(7 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 7 * CENT);
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
+ const auto result6 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 7 * CENT);
+ BOOST_CHECK(result6);
+ BOOST_CHECK_EQUAL(result6->GetSelectedValue(), 7 * CENT);
+ BOOST_CHECK_EQUAL(result6->GetInputSet().size(), 2U);
// when we try making 8 cents, the smaller coins (1,2,5) are exactly enough.
- BOOST_CHECK(KnapsackSolver(8 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK(nValueRet == 8 * CENT);
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U);
+ const auto result7 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 8 * CENT);
+ BOOST_CHECK(result7);
+ BOOST_CHECK(result7->GetSelectedValue() == 8 * CENT);
+ BOOST_CHECK_EQUAL(result7->GetInputSet().size(), 3U);
// when we try making 9 cents, no subset of smaller coins is enough, and we get the next bigger coin (10)
- BOOST_CHECK(KnapsackSolver(9 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 10 * CENT);
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
+ const auto result8 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 9 * CENT);
+ BOOST_CHECK(result8);
+ BOOST_CHECK_EQUAL(result8->GetSelectedValue(), 10 * CENT);
+ BOOST_CHECK_EQUAL(result8->GetInputSet().size(), 1U);
// now clear out the wallet and start again to test choosing between subsets of smaller coins and the next biggest coin
coins.clear();
@@ -403,45 +440,52 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
add_coin(coins, *wallet, 30*CENT); // now we have 6+7+8+20+30 = 71 cents total
// check that we have 71 and not 72
- BOOST_CHECK(KnapsackSolver(71 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK(!KnapsackSolver(72 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
+ const auto result9 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 71 * CENT);
+ BOOST_CHECK(result9);
+ BOOST_CHECK(!KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 72 * CENT));
// now try making 16 cents. the best smaller coins can do is 6+7+8 = 21; not as good at the next biggest coin, 20
- BOOST_CHECK(KnapsackSolver(16 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); // we should get 20 in one coin
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
+ const auto result10 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 16 * CENT);
+ BOOST_CHECK(result10);
+ BOOST_CHECK_EQUAL(result10->GetSelectedValue(), 20 * CENT); // we should get 20 in one coin
+ BOOST_CHECK_EQUAL(result10->GetInputSet().size(), 1U);
add_coin(coins, *wallet, 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total
// now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, better than the next biggest coin, 20
- BOOST_CHECK(KnapsackSolver(16 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 3 coins
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U);
+ const auto result11 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 16 * CENT);
+ BOOST_CHECK(result11);
+ BOOST_CHECK_EQUAL(result11->GetSelectedValue(), 18 * CENT); // we should get 18 in 3 coins
+ BOOST_CHECK_EQUAL(result11->GetInputSet().size(), 3U);
add_coin(coins, *wallet, 18*CENT); // now we have 5+6+7+8+18+20+30
// and now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, the same as the next biggest coin, 18
- BOOST_CHECK(KnapsackSolver(16 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 1 coin
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // because in the event of a tie, the biggest coin wins
+ const auto result12 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 16 * CENT);
+ BOOST_CHECK(result12);
+ BOOST_CHECK_EQUAL(result12->GetSelectedValue(), 18 * CENT); // we should get 18 in 1 coin
+ BOOST_CHECK_EQUAL(result12->GetInputSet().size(), 1U); // because in the event of a tie, the biggest coin wins
// now try making 11 cents. we should get 5+6
- BOOST_CHECK(KnapsackSolver(11 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 11 * CENT);
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
+ const auto result13 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 11 * CENT);
+ BOOST_CHECK(result13);
+ BOOST_CHECK_EQUAL(result13->GetSelectedValue(), 11 * CENT);
+ BOOST_CHECK_EQUAL(result13->GetInputSet().size(), 2U);
// check that the smallest bigger coin is used
add_coin(coins, *wallet, 1*COIN);
add_coin(coins, *wallet, 2*COIN);
add_coin(coins, *wallet, 3*COIN);
add_coin(coins, *wallet, 4*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents
- BOOST_CHECK(KnapsackSolver(95 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); // we should get 1 BTC in 1 coin
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
+ const auto result14 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 95 * CENT);
+ BOOST_CHECK(result14);
+ BOOST_CHECK_EQUAL(result14->GetSelectedValue(), 1 * COIN); // we should get 1 BTC in 1 coin
+ BOOST_CHECK_EQUAL(result14->GetInputSet().size(), 1U);
- BOOST_CHECK(KnapsackSolver(195 * CENT, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
+ const auto result15 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 195 * CENT);
+ BOOST_CHECK(result15);
+ BOOST_CHECK_EQUAL(result15->GetSelectedValue(), 2 * COIN); // we should get 2 BTC in 1 coin
+ BOOST_CHECK_EQUAL(result15->GetInputSet().size(), 1U);
// empty the wallet and start again, now with fractions of a cent, to test small change avoidance
@@ -454,23 +498,26 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
// try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE
// we'll get change smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE exactly
- BOOST_CHECK(KnapsackSolver(MIN_CHANGE, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE);
+ const auto result16 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), MIN_CHANGE);
+ BOOST_CHECK(result16);
+ BOOST_CHECK_EQUAL(result16->GetSelectedValue(), MIN_CHANGE);
// but if we add a bigger coin, small change is avoided
add_coin(coins, *wallet, 1111*MIN_CHANGE);
// try making 1 from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5
- BOOST_CHECK(KnapsackSolver(1 * MIN_CHANGE, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount
+ const auto result17 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 1 * MIN_CHANGE);
+ BOOST_CHECK(result17);
+ BOOST_CHECK_EQUAL(result17->GetSelectedValue(), 1 * MIN_CHANGE); // we should get the exact amount
// if we add more small coins:
add_coin(coins, *wallet, MIN_CHANGE * 6 / 10);
add_coin(coins, *wallet, MIN_CHANGE * 7 / 10);
// and try again to make 1.0 * MIN_CHANGE
- BOOST_CHECK(KnapsackSolver(1 * MIN_CHANGE, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount
+ const auto result18 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 1 * MIN_CHANGE);
+ BOOST_CHECK(result18);
+ BOOST_CHECK_EQUAL(result18->GetSelectedValue(), 1 * MIN_CHANGE); // we should get the exact amount
// run the 'mtgox' test (see https://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf)
// they tried to consolidate 10 50k coins into one 500k coin, and ended up with 50k in change
@@ -478,9 +525,10 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
for (int j = 0; j < 20; j++)
add_coin(coins, *wallet, 50000 * COIN);
- BOOST_CHECK(KnapsackSolver(500000 * COIN, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); // in ten coins
+ const auto result19 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 500000 * COIN);
+ BOOST_CHECK(result19);
+ BOOST_CHECK_EQUAL(result19->GetSelectedValue(), 500000 * COIN); // we should get the exact amount
+ BOOST_CHECK_EQUAL(result19->GetInputSet().size(), 10U); // in ten coins
// if there's not enough in the smaller coins to make at least 1 * MIN_CHANGE change (0.5+0.6+0.7 < 1.0+1.0),
// we need to try finding an exact subset anyway
@@ -491,9 +539,10 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
add_coin(coins, *wallet, MIN_CHANGE * 6 / 10);
add_coin(coins, *wallet, MIN_CHANGE * 7 / 10);
add_coin(coins, *wallet, 1111 * MIN_CHANGE);
- BOOST_CHECK(KnapsackSolver(1 * MIN_CHANGE, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1111 * MIN_CHANGE); // we get the bigger coin
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
+ const auto result20 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 1 * MIN_CHANGE);
+ BOOST_CHECK(result20);
+ BOOST_CHECK_EQUAL(result20->GetSelectedValue(), 1111 * MIN_CHANGE); // we get the bigger coin
+ BOOST_CHECK_EQUAL(result20->GetInputSet().size(), 1U);
// but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0)
coins.clear();
@@ -501,9 +550,10 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
add_coin(coins, *wallet, MIN_CHANGE * 6 / 10);
add_coin(coins, *wallet, MIN_CHANGE * 8 / 10);
add_coin(coins, *wallet, 1111 * MIN_CHANGE);
- BOOST_CHECK(KnapsackSolver(MIN_CHANGE, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // we should get the exact amount
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // in two coins 0.4+0.6
+ const auto result21 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), MIN_CHANGE);
+ BOOST_CHECK(result21);
+ BOOST_CHECK_EQUAL(result21->GetSelectedValue(), MIN_CHANGE); // we should get the exact amount
+ BOOST_CHECK_EQUAL(result21->GetInputSet().size(), 2U); // in two coins 0.4+0.6
// test avoiding small change
coins.clear();
@@ -512,14 +562,16 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
add_coin(coins, *wallet, MIN_CHANGE * 100);
// trying to make 100.01 from these three coins
- BOOST_CHECK(KnapsackSolver(MIN_CHANGE * 10001 / 100, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE * 10105 / 100); // we should get all coins
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U);
+ const auto result22 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), MIN_CHANGE * 10001 / 100);
+ BOOST_CHECK(result22);
+ BOOST_CHECK_EQUAL(result22->GetSelectedValue(), MIN_CHANGE * 10105 / 100); // we should get all coins
+ BOOST_CHECK_EQUAL(result22->GetInputSet().size(), 3U);
// but if we try to make 99.9, we should take the bigger of the two small coins to avoid small change
- BOOST_CHECK(KnapsackSolver(MIN_CHANGE * 9990 / 100, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE);
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
+ const auto result23 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), MIN_CHANGE * 9990 / 100);
+ BOOST_CHECK(result23);
+ BOOST_CHECK_EQUAL(result23->GetSelectedValue(), 101 * MIN_CHANGE);
+ BOOST_CHECK_EQUAL(result23->GetInputSet().size(), 2U);
}
// test with many inputs
@@ -531,18 +583,19 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
// We only create the wallet once to save time, but we still run the coin selection RUN_TESTS times.
for (int i = 0; i < RUN_TESTS; i++) {
- BOOST_CHECK(KnapsackSolver(2000, KnapsackGroupOutputs(coins, *wallet, filter_confirmed), setCoinsRet, nValueRet));
+ const auto result24 = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_confirmed), 2000);
+ BOOST_CHECK(result24);
if (amt - 2000 < MIN_CHANGE) {
// needs more than one input:
uint16_t returnSize = std::ceil((2000.0 + MIN_CHANGE)/amt);
CAmount returnValue = amt * returnSize;
- BOOST_CHECK_EQUAL(nValueRet, returnValue);
- BOOST_CHECK_EQUAL(setCoinsRet.size(), returnSize);
+ BOOST_CHECK_EQUAL(result24->GetSelectedValue(), returnValue);
+ BOOST_CHECK_EQUAL(result24->GetInputSet().size(), returnSize);
} else {
// one input is sufficient:
- BOOST_CHECK_EQUAL(nValueRet, amt);
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
+ BOOST_CHECK_EQUAL(result24->GetSelectedValue(), amt);
+ BOOST_CHECK_EQUAL(result24->GetInputSet().size(), 1U);
}
}
}
@@ -557,9 +610,11 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
for (int i = 0; i < RUN_TESTS; i++) {
// picking 50 from 100 coins doesn't depend on the shuffle,
// but does depend on randomness in the stochastic approximation code
- BOOST_CHECK(KnapsackSolver(50 * COIN, GroupCoins(coins), setCoinsRet, nValueRet));
- BOOST_CHECK(KnapsackSolver(50 * COIN, GroupCoins(coins), setCoinsRet2, nValueRet));
- BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2));
+ const auto result25 = KnapsackSolver(GroupCoins(coins), 50 * COIN);
+ BOOST_CHECK(result25);
+ const auto result26 = KnapsackSolver(GroupCoins(coins), 50 * COIN);
+ BOOST_CHECK(result26);
+ BOOST_CHECK(!EqualResult(*result25, *result26));
int fails = 0;
for (int j = 0; j < RANDOM_REPEATS; j++)
@@ -568,9 +623,11 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
// When choosing 1 from 100 identical coins, 1% of the time, this test will choose the same coin twice
// which will cause it to fail.
// To avoid that issue, run the test RANDOM_REPEATS times and only complain if all of them fail
- BOOST_CHECK(KnapsackSolver(COIN, GroupCoins(coins), setCoinsRet, nValueRet));
- BOOST_CHECK(KnapsackSolver(COIN, GroupCoins(coins), setCoinsRet2, nValueRet));
- if (equal_sets(setCoinsRet, setCoinsRet2))
+ const auto result27 = KnapsackSolver(GroupCoins(coins), COIN);
+ BOOST_CHECK(result27);
+ const auto result28 = KnapsackSolver(GroupCoins(coins), COIN);
+ BOOST_CHECK(result28);
+ if (EqualResult(*result27, *result28))
fails++;
}
BOOST_CHECK_NE(fails, RANDOM_REPEATS);
@@ -589,9 +646,11 @@ BOOST_AUTO_TEST_CASE(knapsack_solver_test)
int fails = 0;
for (int j = 0; j < RANDOM_REPEATS; j++)
{
- BOOST_CHECK(KnapsackSolver(90*CENT, GroupCoins(coins), setCoinsRet, nValueRet));
- BOOST_CHECK(KnapsackSolver(90*CENT, GroupCoins(coins), setCoinsRet2, nValueRet));
- if (equal_sets(setCoinsRet, setCoinsRet2))
+ const auto result29 = KnapsackSolver(GroupCoins(coins), 90 * CENT);
+ BOOST_CHECK(result29);
+ const auto result30 = KnapsackSolver(GroupCoins(coins), 90 * CENT);
+ BOOST_CHECK(result30);
+ if (EqualResult(*result29, *result30))
fails++;
}
BOOST_CHECK_NE(fails, RANDOM_REPEATS);
@@ -607,8 +666,6 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset)
wallet->SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
wallet->SetupDescriptorScriptPubKeyMans();
- CoinSet setCoinsRet;
- CAmount nValueRet;
std::vector<COutput> coins;
// Test vValue sort order
@@ -616,9 +673,10 @@ BOOST_AUTO_TEST_CASE(ApproximateBestSubset)
add_coin(coins, *wallet, 1000 * COIN);
add_coin(coins, *wallet, 3 * COIN);
- BOOST_CHECK(KnapsackSolver(1003 * COIN, KnapsackGroupOutputs(coins, *wallet, filter_standard), setCoinsRet, nValueRet));
- BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN);
- BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
+ const auto result = KnapsackSolver(KnapsackGroupOutputs(coins, *wallet, filter_standard), 1003 * COIN);
+ BOOST_CHECK(result);
+ BOOST_CHECK_EQUAL(result->GetSelectedValue(), 1003 * COIN);
+ BOOST_CHECK_EQUAL(result->GetInputSet().size(), 2U);
}
// Tests that with the ideal conditions, the coin selector will always be able to find a solution that can pay the target value
@@ -660,11 +718,10 @@ BOOST_AUTO_TEST_CASE(SelectCoins_test)
/* change_spend_size= */ 148, /* effective_feerate= */ CFeeRate(0),
/* long_term_feerate= */ CFeeRate(0), /* discard_feerate= */ CFeeRate(0),
/* tx_noinputs_size= */ 0, /* avoid_partial= */ false);
- CoinSet out_set;
- CAmount out_value = 0;
CCoinControl cc;
- BOOST_CHECK(SelectCoins(*wallet, coins, target, out_set, out_value, cc, cs_params));
- BOOST_CHECK_GE(out_value, target);
+ const auto result = SelectCoins(*wallet, coins, target, cc, cs_params);
+ BOOST_CHECK(result);
+ BOOST_CHECK_GE(result->GetSelectedValue(), target);
}
}
@@ -751,3 +808,4 @@ BOOST_AUTO_TEST_CASE(waste_test)
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet
diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp
index dba3f35025..825382fe59 100644
--- a/src/wallet/test/db_tests.cpp
+++ b/src/wallet/test/db_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2018-2020 The Bitcoin Core developers
+// Copyright (c) 2018-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -11,6 +11,7 @@
#include <wallet/bdb.h>
+namespace wallet {
BOOST_FIXTURE_TEST_SUITE(db_tests, BasicTestingSetup)
static std::shared_ptr<BerkeleyEnvironment> GetWalletEnv(const fs::path& path, std::string& database_filename)
@@ -77,3 +78,4 @@ BOOST_AUTO_TEST_CASE(getwalletenv_g_dbenvs_free_instance)
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet
diff --git a/src/wallet/test/fuzz/notifications.cpp b/src/wallet/test/fuzz/notifications.cpp
index 0601c492cd..1c16da25bd 100644
--- a/src/wallet/test/fuzz/notifications.cpp
+++ b/src/wallet/test/fuzz/notifications.cpp
@@ -18,6 +18,7 @@
#include <string>
#include <vector>
+namespace wallet {
namespace {
const TestingSetup* g_setup;
@@ -168,3 +169,4 @@ FUZZ_TARGET_INIT(wallet_notifications, initialize_setup)
}
}
} // namespace
+} // namespace wallet
diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp
index 170675c035..b455ab9d9e 100644
--- a/src/wallet/test/init_test_fixture.cpp
+++ b/src/wallet/test/init_test_fixture.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2018-2020 The Bitcoin Core developers
+// Copyright (c) 2018-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -9,9 +9,10 @@
#include <wallet/test/init_test_fixture.h>
+namespace wallet {
InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainName) : BasicTestingSetup(chainName)
{
- m_wallet_client = MakeWalletClient(*m_node.chain, *Assert(m_node.args));
+ m_wallet_loader = MakeWalletLoader(*m_node.chain, *Assert(m_node.args));
std::string sep;
sep += fs::path::preferred_separator;
@@ -48,3 +49,4 @@ void InitWalletDirTestingSetup::SetWalletDir(const fs::path& walletdir_path)
{
gArgs.ForceSetArg("-walletdir", fs::PathToString(walletdir_path));
}
+} // namespace wallet
diff --git a/src/wallet/test/init_test_fixture.h b/src/wallet/test/init_test_fixture.h
index 37ae907de5..df5819fd1d 100644
--- a/src/wallet/test/init_test_fixture.h
+++ b/src/wallet/test/init_test_fixture.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2018-2020 The Bitcoin Core developers
+// Copyright (c) 2018-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -11,6 +11,7 @@
#include <test/util/setup_common.h>
+namespace wallet {
struct InitWalletDirTestingSetup: public BasicTestingSetup {
explicit InitWalletDirTestingSetup(const std::string& chainName = CBaseChainParams::MAIN);
~InitWalletDirTestingSetup();
@@ -19,7 +20,8 @@ struct InitWalletDirTestingSetup: public BasicTestingSetup {
fs::path m_datadir;
fs::path m_cwd;
std::map<std::string, fs::path> m_walletdir_path_cases;
- std::unique_ptr<interfaces::WalletClient> m_wallet_client;
+ std::unique_ptr<interfaces::WalletLoader> m_wallet_loader;
};
#endif // BITCOIN_WALLET_TEST_INIT_TEST_FIXTURE_H
+} // namespace wallet
diff --git a/src/wallet/test/init_tests.cpp b/src/wallet/test/init_tests.cpp
index 222c2bf4b7..c1cae5c5f6 100644
--- a/src/wallet/test/init_tests.cpp
+++ b/src/wallet/test/init_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2018-2020 The Bitcoin Core developers
+// Copyright (c) 2018-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -10,12 +10,13 @@
#include <util/system.h>
#include <wallet/test/init_test_fixture.h>
+namespace wallet {
BOOST_FIXTURE_TEST_SUITE(init_tests, InitWalletDirTestingSetup)
BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_default)
{
SetWalletDir(m_walletdir_path_cases["default"]);
- bool result = m_wallet_client->verify();
+ bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
fs::path walletdir = fs::PathFromString(gArgs.GetArg("-walletdir", ""));
fs::path expected_path = fs::canonical(m_walletdir_path_cases["default"]);
@@ -25,7 +26,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_default)
BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_custom)
{
SetWalletDir(m_walletdir_path_cases["custom"]);
- bool result = m_wallet_client->verify();
+ bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
fs::path walletdir = fs::PathFromString(gArgs.GetArg("-walletdir", ""));
fs::path expected_path = fs::canonical(m_walletdir_path_cases["custom"]);
@@ -37,7 +38,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_does_not_exist)
SetWalletDir(m_walletdir_path_cases["nonexistent"]);
{
ASSERT_DEBUG_LOG("does not exist");
- bool result = m_wallet_client->verify();
+ bool result = m_wallet_loader->verify();
BOOST_CHECK(result == false);
}
}
@@ -47,7 +48,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_is_not_directory)
SetWalletDir(m_walletdir_path_cases["file"]);
{
ASSERT_DEBUG_LOG("is not a directory");
- bool result = m_wallet_client->verify();
+ bool result = m_wallet_loader->verify();
BOOST_CHECK(result == false);
}
}
@@ -57,7 +58,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_is_not_relative)
SetWalletDir(m_walletdir_path_cases["relative"]);
{
ASSERT_DEBUG_LOG("is a relative path");
- bool result = m_wallet_client->verify();
+ bool result = m_wallet_loader->verify();
BOOST_CHECK(result == false);
}
}
@@ -65,7 +66,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_is_not_relative)
BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing)
{
SetWalletDir(m_walletdir_path_cases["trailing"]);
- bool result = m_wallet_client->verify();
+ bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
fs::path walletdir = fs::PathFromString(gArgs.GetArg("-walletdir", ""));
fs::path expected_path = fs::canonical(m_walletdir_path_cases["default"]);
@@ -75,7 +76,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing)
BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing2)
{
SetWalletDir(m_walletdir_path_cases["trailing2"]);
- bool result = m_wallet_client->verify();
+ bool result = m_wallet_loader->verify();
BOOST_CHECK(result == true);
fs::path walletdir = fs::PathFromString(gArgs.GetArg("-walletdir", ""));
fs::path expected_path = fs::canonical(m_walletdir_path_cases["default"]);
@@ -83,3 +84,4 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing2)
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet
diff --git a/src/wallet/test/ismine_tests.cpp b/src/wallet/test/ismine_tests.cpp
index dda202d55e..dd5cd0af46 100644
--- a/src/wallet/test/ismine_tests.cpp
+++ b/src/wallet/test/ismine_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2020 The Bitcoin Core developers
+// Copyright (c) 2017-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -13,6 +13,7 @@
#include <boost/test/unit_test.hpp>
+namespace wallet {
BOOST_FIXTURE_TEST_SUITE(ismine_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(ismine_standard)
@@ -417,3 +418,4 @@ BOOST_AUTO_TEST_CASE(ismine_standard)
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet
diff --git a/src/wallet/test/psbt_wallet_tests.cpp b/src/wallet/test/psbt_wallet_tests.cpp
index 7bc2bb5583..b953f402a2 100644
--- a/src/wallet/test/psbt_wallet_tests.cpp
+++ b/src/wallet/test/psbt_wallet_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2020 The Bitcoin Core developers
+// Copyright (c) 2017-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -11,6 +11,7 @@
#include <test/util/setup_common.h>
#include <wallet/test/wallet_test_fixture.h>
+namespace wallet {
BOOST_FIXTURE_TEST_SUITE(psbt_wallet_tests, WalletTestingSetup)
static void import_descriptor(CWallet& wallet, const std::string& descriptor)
@@ -145,3 +146,4 @@ BOOST_AUTO_TEST_CASE(parse_hd_keypath)
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet
diff --git a/src/wallet/test/scriptpubkeyman_tests.cpp b/src/wallet/test/scriptpubkeyman_tests.cpp
index 0e78855ced..a524b85ccb 100644
--- a/src/wallet/test/scriptpubkeyman_tests.cpp
+++ b/src/wallet/test/scriptpubkeyman_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2020 The Bitcoin Core developers
+// Copyright (c) 2020-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -10,6 +10,7 @@
#include <boost/test/unit_test.hpp>
+namespace wallet {
BOOST_FIXTURE_TEST_SUITE(scriptpubkeyman_tests, BasicTestingSetup)
// Test LegacyScriptPubKeyMan::CanProvide behavior, making sure it returns true
@@ -39,3 +40,4 @@ BOOST_AUTO_TEST_CASE(CanProvide)
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet
diff --git a/src/wallet/test/spend_tests.cpp b/src/wallet/test/spend_tests.cpp
index 926f28686d..b2a0697c21 100644
--- a/src/wallet/test/spend_tests.cpp
+++ b/src/wallet/test/spend_tests.cpp
@@ -12,6 +12,7 @@
#include <boost/test/unit_test.hpp>
+namespace wallet {
BOOST_FIXTURE_TEST_SUITE(spend_tests, WalletTestingSetup)
BOOST_FIXTURE_TEST_CASE(SubtractFee, TestChain100Setup)
@@ -63,3 +64,4 @@ BOOST_FIXTURE_TEST_CASE(SubtractFee, TestChain100Setup)
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet
diff --git a/src/wallet/test/util.cpp b/src/wallet/test/util.cpp
index 93a3404d2c..aa3121511d 100644
--- a/src/wallet/test/util.cpp
+++ b/src/wallet/test/util.cpp
@@ -15,6 +15,7 @@
#include <memory>
+namespace wallet {
std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cchain, ArgsManager& args, const CKey& key)
{
auto wallet = std::make_unique<CWallet>(&chain, "", args, CreateMockWalletDatabase());
@@ -44,3 +45,4 @@ std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cc
BOOST_CHECK(result.last_failed_block.IsNull());
return wallet;
}
+} // namespace wallet
diff --git a/src/wallet/test/util.h b/src/wallet/test/util.h
index 3adb82b85f..712d0251cd 100644
--- a/src/wallet/test/util.h
+++ b/src/wallet/test/util.h
@@ -10,11 +10,14 @@
class ArgsManager;
class CChain;
class CKey;
-class CWallet;
namespace interfaces {
class Chain;
} // namespace interfaces
+namespace wallet {
+class CWallet;
+
std::unique_ptr<CWallet> CreateSyncedWallet(interfaces::Chain& chain, CChain& cchain, ArgsManager& args, const CKey& key);
+} // namespace wallet
#endif // BITCOIN_WALLET_TEST_UTIL_H
diff --git a/src/wallet/test/wallet_crypto_tests.cpp b/src/wallet/test/wallet_crypto_tests.cpp
index 5b421840e0..166e27bab9 100644
--- a/src/wallet/test/wallet_crypto_tests.cpp
+++ b/src/wallet/test/wallet_crypto_tests.cpp
@@ -10,6 +10,7 @@
#include <boost/test/unit_test.hpp>
+namespace wallet {
BOOST_FIXTURE_TEST_SUITE(wallet_crypto_tests, BasicTestingSetup)
class TestCrypter
@@ -124,3 +125,4 @@ BOOST_AUTO_TEST_CASE(decrypt) {
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet
diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp
index 762702522e..cb006dea3a 100644
--- a/src/wallet/test/wallet_test_fixture.cpp
+++ b/src/wallet/test/wallet_test_fixture.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2020 The Bitcoin Core developers
+// Copyright (c) 2016-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -6,16 +6,18 @@
#include <scheduler.h>
+namespace wallet {
WalletTestingSetup::WalletTestingSetup(const std::string& chainName)
: TestingSetup(chainName),
m_wallet(m_node.chain.get(), "", m_args, CreateMockWalletDatabase())
{
m_wallet.LoadWallet();
m_chain_notifications_handler = m_node.chain->handleNotifications({ &m_wallet, [](CWallet*) {} });
- m_wallet_client->registerRpcs();
+ m_wallet_loader->registerRpcs();
}
WalletTestingSetup::~WalletTestingSetup()
{
if (m_node.scheduler) m_node.scheduler->stop();
}
+} // namespace wallet
diff --git a/src/wallet/test/wallet_test_fixture.h b/src/wallet/test/wallet_test_fixture.h
index 8bf2d36227..d4b855b145 100644
--- a/src/wallet/test/wallet_test_fixture.h
+++ b/src/wallet/test/wallet_test_fixture.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2016-2020 The Bitcoin Core developers
+// Copyright (c) 2016-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -15,15 +15,17 @@
#include <memory>
+namespace wallet {
/** Testing setup and teardown for wallet.
*/
struct WalletTestingSetup : public TestingSetup {
explicit WalletTestingSetup(const std::string& chainName = CBaseChainParams::MAIN);
~WalletTestingSetup();
- std::unique_ptr<interfaces::WalletClient> m_wallet_client = interfaces::MakeWalletClient(*m_node.chain, *Assert(m_node.args));
+ std::unique_ptr<interfaces::WalletLoader> m_wallet_loader = interfaces::MakeWalletLoader(*m_node.chain, *Assert(m_node.args));
CWallet m_wallet;
std::unique_ptr<interfaces::Handler> m_chain_notifications_handler;
};
+} // namespace wallet
#endif // BITCOIN_WALLET_TEST_WALLET_TEST_FIXTURE_H
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
index 8cb3cede9b..bb6021b857 100644
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2012-2020 The Bitcoin Core developers
+// Copyright (c) 2012-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -30,6 +30,10 @@
#include <boost/test/unit_test.hpp>
#include <univalue.h>
+using node::MAX_BLOCKFILE_SIZE;
+using node::UnlinkPrunedFiles;
+
+namespace wallet {
RPCHelpMan importmulti();
RPCHelpMan dumpwallet();
RPCHelpMan importwallet();
@@ -92,7 +96,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
{
// Cap last block file size, and mine new block in a new block file.
CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip();
- GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE;
+ WITH_LOCK(::cs_main, m_node.chainman->m_blockman.GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE);
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip();
@@ -193,7 +197,7 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
{
// Cap last block file size, and mine new block in a new block file.
CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip();
- GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE;
+ WITH_LOCK(::cs_main, m_node.chainman->m_blockman.GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE);
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip();
@@ -289,7 +293,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
request.params.setArray();
request.params.push_back(backup_file);
- ::dumpwallet().HandleRequest(request);
+ wallet::dumpwallet().HandleRequest(request);
RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt);
}
@@ -308,7 +312,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
request.params.push_back(backup_file);
AddWallet(context, wallet);
wallet->SetLastBlockProcessed(m_node.chainman->ActiveChain().Height(), m_node.chainman->ActiveChain().Tip()->GetBlockHash());
- ::importwallet().HandleRequest(request);
+ wallet::importwallet().HandleRequest(request);
RemoveWallet(context, wallet, /* load_on_start= */ std::nullopt);
BOOST_CHECK_EQUAL(wallet->mapWallet.size(), 3U);
@@ -851,3 +855,4 @@ BOOST_FIXTURE_TEST_CASE(ZapSelectTx, TestChain100Setup)
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet
diff --git a/src/wallet/test/wallet_transaction_tests.cpp b/src/wallet/test/wallet_transaction_tests.cpp
index 5ef2904f66..9f56248614 100644
--- a/src/wallet/test/wallet_transaction_tests.cpp
+++ b/src/wallet/test/wallet_transaction_tests.cpp
@@ -8,6 +8,7 @@
#include <boost/test/unit_test.hpp>
+namespace wallet {
BOOST_FIXTURE_TEST_SUITE(wallet_transaction_tests, WalletTestingSetup)
BOOST_AUTO_TEST_CASE(roundtrip)
@@ -22,3 +23,4 @@ BOOST_AUTO_TEST_CASE(roundtrip)
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet
diff --git a/src/wallet/test/walletdb_tests.cpp b/src/wallet/test/walletdb_tests.cpp
index 558121ae42..e251a3a0e4 100644
--- a/src/wallet/test/walletdb_tests.cpp
+++ b/src/wallet/test/walletdb_tests.cpp
@@ -9,6 +9,7 @@
#include <boost/test/unit_test.hpp>
+namespace wallet {
BOOST_FIXTURE_TEST_SUITE(walletdb_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(walletdb_readkeyvalue)
@@ -27,3 +28,4 @@ BOOST_AUTO_TEST_CASE(walletdb_readkeyvalue)
}
BOOST_AUTO_TEST_SUITE_END()
+} // namespace wallet