5#include <chainparams.h>
15#include <test/util/setup_common.h>
18#include <boost/test/unit_test.hpp>
32#define RANDOM_REPEATS 5
47 std::vector<CInputCoin> &set) {
49 tx.
vout.resize(nInput + 1);
50 tx.
vout[nInput].nValue = nValue;
56 tx.
vout.resize(nInput + 1);
57 tx.
vout[nInput].nValue = nValue;
62 bool fIsFromMe =
false,
int nInput = 0,
63 bool spendable =
false) {
65 static int nextLockTime = 0;
69 tx.
vout.resize(nInput + 1);
70 tx.
vout[nInput].nValue = nValue;
99 std::pair<CoinSet::iterator, CoinSet::iterator> ret =
100 mismatch(a.begin(), a.end(), b.begin());
101 return ret.first == a.end() && ret.second == b.end();
107 for (
int i = 0; i < utxos; ++i) {
117inline std::vector<OutputGroup> &
119 static std::vector<OutputGroup> static_groups;
120 static_groups.clear();
121 for (
auto &coin : coins) {
122 static_groups.emplace_back();
123 static_groups.back().Insert(coin, 0,
true,
false);
125 return static_groups;
128inline std::vector<OutputGroup> &
GroupCoins(
const std::vector<COutput> &coins) {
129 static std::vector<OutputGroup> static_groups;
130 static_groups.clear();
131 for (
auto &coin : coins) {
138 static_groups.emplace_back();
139 static_groups.back().Insert(coin.GetInputCoin(), coin.nDepth, is_me,
142 return static_groups;
148 m_wallet.SetupLegacyScriptPubKeyMan();
151 std::vector<CInputCoin> utxo_pool;
163 selection, value_ret, not_input_fees));
173 add_coin(1 * CENT, 1, actual_selection);
175 selection, value_ret, not_input_fees));
178 actual_selection.clear();
182 add_coin(2 * CENT, 2, actual_selection);
184 selection, value_ret, not_input_fees));
187 actual_selection.clear();
191 add_coin(4 * CENT, 4, actual_selection);
192 add_coin(1 * CENT, 1, actual_selection);
194 selection, value_ret, not_input_fees));
197 actual_selection.clear();
202 selection, value_ret, not_input_fees));
203 actual_selection.clear();
208 add_coin(1 * CENT, 1, actual_selection);
210 5 * CENT / 10, selection, value_ret,
214 actual_selection.clear();
222 actual_selection.clear();
227 add_coin(5 * CENT, 5, actual_selection);
228 add_coin(4 * CENT, 4, actual_selection);
229 add_coin(1 * CENT, 1, actual_selection);
231 selection, value_ret, not_input_fees));
234 actual_selection.clear();
239 add_coin(5 * CENT, 5, actual_selection);
240 add_coin(3 * CENT, 3, actual_selection);
241 add_coin(2 * CENT, 2, actual_selection);
243 selection, value_ret, not_input_fees));
250 selection, value_ret, not_input_fees));
251 actual_selection.clear();
258 selection, value_ret, not_input_fees));
262 selection, value_ret, not_input_fees));
266 add_coin(7 * CENT, 7, actual_selection);
267 add_coin(7 * CENT, 7, actual_selection);
268 add_coin(7 * CENT, 7, actual_selection);
269 add_coin(7 * CENT, 7, actual_selection);
270 add_coin(2 * CENT, 7, actual_selection);
276 for (
int i = 0; i < 50000; ++i) {
280 selection, value_ret, not_input_fees));
289 for (
int i = 5; i <= 20; ++i) {
293 for (
int i = 0; i < 100; ++i) {
295 selection, value_ret, not_input_fees));
309 vCoins.at(0).nInputBytes = 40;
311 setCoinsRet, nValueRet,
312 coin_selection_params_bnb, bnb_used));
317 vCoins.at(0).nInputBytes = 40;
319 setCoinsRet, nValueRet,
320 coin_selection_params_bnb, bnb_used));
323 setCoinsRet, nValueRet,
324 coin_selection_params_bnb, bnb_used));
330 auto wallet = std::make_unique<CWallet>(
m_node.chain.get(),
"",
334 wallet->SetupLegacyScriptPubKeyMan();
344 nValueRet, coin_control,
345 coin_selection_params_bnb, bnb_used));
355 CoinSet setCoinsRet, setCoinsRet2;
368 vCoins, setCoinsRet, nValueRet,
376 vCoins, setCoinsRet, nValueRet,
381 vCoins, setCoinsRet, nValueRet,
389 vCoins, setCoinsRet, nValueRet,
394 vCoins, setCoinsRet, nValueRet,
401 add_coin(testWallet, 10 * CENT, 3,
true);
410 vCoins, setCoinsRet, nValueRet,
419 vCoins, setCoinsRet, nValueRet,
424 vCoins, setCoinsRet, nValueRet,
430 vCoins, setCoinsRet, nValueRet,
441 vCoins, setCoinsRet, nValueRet,
449 vCoins, setCoinsRet, nValueRet,
457 vCoins, setCoinsRet, nValueRet,
475 vCoins, setCoinsRet, nValueRet,
478 vCoins, setCoinsRet, nValueRet,
484 vCoins, setCoinsRet, nValueRet,
496 vCoins, setCoinsRet, nValueRet,
508 vCoins, setCoinsRet, nValueRet,
517 vCoins, setCoinsRet, nValueRet,
529 vCoins, setCoinsRet, nValueRet,
536 vCoins, setCoinsRet, nValueRet,
556 vCoins, setCoinsRet, nValueRet,
586 for (
int j = 0; j < 20; j++) {
623 vCoins, setCoinsRet, nValueRet,
658 for (uint16_t j = 0; j < 676; j++) {
671 uint16_t returnSize = std::ceil(
673 Amount returnValue = returnSize * amt;
687 for (
int i2 = 0; i2 < 100; i2++) {
760 m_wallet.SetupLegacyScriptPubKeyMan();
765 for (
int i = 0; i < 1000; i++) {
771 vCoins, setCoinsRet, nValueRet,
787 std::default_random_engine generator;
788 std::exponential_distribution<double> distribution(100);
792 for (
int i = 0; i < 100; ++i) {
796 for (
int j = 0; j < 1000; ++j) {
798 int64_t(10000000 * distribution(generator)) *
SATOSHI);
815 bool bnb_used =
false;
817 vCoins, out_set, out_value,
818 coin_selection_params_bnb, bnb_used) ||
821 out_value, coin_selection_params_knapsack, bnb_used));
822 BOOST_CHECK_GE(out_value, target);
826BOOST_AUTO_TEST_SUITE_END()
static constexpr Amount SATOSHI
static constexpr Amount COIN
const CChainParams & Params()
Return the currently selected parameters.
void Select(const COutPoint &output)
bool fAllowOtherInputs
If false, allows unselected inputs, but requires all selected inputs be used.
Fee rate in satoshis per kilobyte: Amount / kB.
A mutable version of CTransaction.
std::vector< CTxOut > vout
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
void SetupLegacyScriptPubKeyMan()
Make a LegacyScriptPubKeyMan and set it for all types, internal, and external.
A transaction with a bunch of additional info that only the owner cares about.
CachableAmount m_amounts[AMOUNTTYPE_ENUM_ELEMENTS]
bool m_is_cache_empty
This flag is true if all m_amounts caches are empty.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
std::set< CInputCoin > CoinSet
static void ApproximateBestSubset(const std::vector< OutputGroup > &groups, const Amount &nTotalLower, const Amount &nTargetValue, std::vector< char > &vfBest, Amount &nBest, int iterations=1000)
bool SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const Amount &target_value, const Amount &cost_of_change, std::set< CInputCoin > &out_set, Amount &value_ret, const Amount not_input_fees)
This is the Branch and Bound Coin Selection algorithm designed by Murch.
static constexpr Amount MIN_CHANGE
target minimum change amount
CoinEligibilityFilter filter_standard_extra(6, 6)
static std::vector< COutput > vCoins
static void empty_wallet()
static node::NodeContext testNode
BOOST_AUTO_TEST_CASE(bnb_search_test)
CoinSelectionParams coin_selection_params(false, 0, 0, CFeeRate(Amount::zero()), 0, false)
static bool equal_sets(CoinSet a, CoinSet b)
std::set< CInputCoin > CoinSet
std::vector< OutputGroup > & GroupCoins(const std::vector< CInputCoin > &coins)
CoinEligibilityFilter filter_standard(1, 6)
CoinEligibilityFilter filter_confirmed(1, 1)
static Amount make_hard_case(int utxos, std::vector< CInputCoin > &utxo_pool)
static void add_coin(const Amount nValue, int nInput, std::vector< CInputCoin > &set)
std::unique_ptr< Chain > MakeChain(node::NodeContext &node, const CChainParams ¶ms)
Return implementation of Chain interface.
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static CTransactionRef MakeTransactionRef()
bool SelectCoinsMinConf(const CWallet &wallet, const Amount nTargetValue, const CoinEligibilityFilter &eligibility_filter, std::vector< COutput > coins, std::set< CInputCoin > &setCoinsRet, Amount &nValueRet, const CoinSelectionParams &coin_selection_params, bool &bnb_used)
Shuffle and select coins until nTargetValue is reached while avoiding small change; This method is st...
bool SelectCoins(const CWallet &wallet, const std::vector< COutput > &vAvailableCoins, const Amount nTargetValue, std::set< CInputCoin > &setCoinsRet, Amount &nValueRet, const CCoinControl &coin_control, CoinSelectionParams &coin_selection_params, bool &bnb_used)
Select a set of coins such that nValueRet >= nTargetValue and at least all coins from coin_control ar...
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
static constexpr Amount zero() noexcept
void Set(isminefilter filter, Amount value)
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
Testing setup and teardown for wallet.
NodeContext struct containing references to chain state and connection state.
std::shared_ptr< CWallet > m_wallet
std::unique_ptr< WalletDatabase > CreateDummyWalletDatabase()
Return object for accessing dummy database with no read/write capabilities.
std::unique_ptr< WalletDatabase > CreateMockWalletDatabase()
Return object for accessing temporary in-memory database.