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;
100 std::pair<CoinSet::iterator, CoinSet::iterator> ret =
101 mismatch(a.begin(), a.end(), b.begin());
102 return ret.first == a.end() && ret.second == b.end();
108 for (
int i = 0; i < utxos; ++i) {
118inline std::vector<OutputGroup> &
120 static std::vector<OutputGroup> static_groups;
121 static_groups.clear();
122 for (
auto &coin : coins) {
123 static_groups.emplace_back();
124 static_groups.back().Insert(coin, 0,
true,
false);
126 return static_groups;
129inline std::vector<OutputGroup> &
GroupCoins(
const std::vector<COutput> &coins) {
130 static std::vector<OutputGroup> static_groups;
131 static_groups.clear();
132 for (
auto &coin : coins) {
139 static_groups.emplace_back();
140 static_groups.back().Insert(coin.GetInputCoin(), coin.nDepth, is_me,
143 return static_groups;
149 m_wallet.SetupLegacyScriptPubKeyMan();
152 std::vector<CInputCoin> utxo_pool;
164 selection, value_ret, not_input_fees));
174 add_coin(1 * CENT, 1, actual_selection);
176 selection, value_ret, not_input_fees));
179 actual_selection.clear();
183 add_coin(2 * CENT, 2, actual_selection);
185 selection, value_ret, not_input_fees));
188 actual_selection.clear();
192 add_coin(4 * CENT, 4, actual_selection);
193 add_coin(1 * CENT, 1, actual_selection);
195 selection, value_ret, not_input_fees));
198 actual_selection.clear();
203 selection, value_ret, not_input_fees));
204 actual_selection.clear();
209 add_coin(1 * CENT, 1, actual_selection);
211 5 * CENT / 10, selection, value_ret,
215 actual_selection.clear();
223 actual_selection.clear();
228 add_coin(5 * CENT, 5, actual_selection);
229 add_coin(4 * CENT, 4, actual_selection);
230 add_coin(1 * CENT, 1, actual_selection);
232 selection, value_ret, not_input_fees));
235 actual_selection.clear();
240 add_coin(5 * CENT, 5, actual_selection);
241 add_coin(3 * CENT, 3, actual_selection);
242 add_coin(2 * CENT, 2, actual_selection);
244 selection, value_ret, not_input_fees));
251 selection, value_ret, not_input_fees));
252 actual_selection.clear();
259 selection, value_ret, not_input_fees));
263 selection, value_ret, not_input_fees));
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(7 * CENT, 7, actual_selection);
271 add_coin(2 * CENT, 7, actual_selection);
277 for (
int i = 0; i < 50000; ++i) {
281 selection, value_ret, not_input_fees));
290 for (
int i = 5; i <= 20; ++i) {
294 for (
int i = 0; i < 100; ++i) {
296 selection, value_ret, not_input_fees));
310 vCoins.at(0).nInputBytes = 40;
312 setCoinsRet, nValueRet,
313 coin_selection_params_bnb, bnb_used));
318 vCoins.at(0).nInputBytes = 40;
320 setCoinsRet, nValueRet,
321 coin_selection_params_bnb, bnb_used));
324 setCoinsRet, nValueRet,
325 coin_selection_params_bnb, bnb_used));
331 auto wallet = std::make_unique<CWallet>(
m_node.chain.get(),
"",
335 wallet->SetupLegacyScriptPubKeyMan();
345 nValueRet, coin_control,
346 coin_selection_params_bnb, bnb_used));
356 CoinSet setCoinsRet, setCoinsRet2;
369 vCoins, setCoinsRet, nValueRet,
377 vCoins, setCoinsRet, nValueRet,
382 vCoins, setCoinsRet, nValueRet,
390 vCoins, setCoinsRet, nValueRet,
395 vCoins, setCoinsRet, nValueRet,
402 add_coin(testWallet, 10 * CENT, 3,
true);
411 vCoins, setCoinsRet, nValueRet,
420 vCoins, setCoinsRet, nValueRet,
425 vCoins, setCoinsRet, nValueRet,
431 vCoins, setCoinsRet, nValueRet,
442 vCoins, setCoinsRet, nValueRet,
450 vCoins, setCoinsRet, nValueRet,
458 vCoins, setCoinsRet, nValueRet,
476 vCoins, setCoinsRet, nValueRet,
479 vCoins, setCoinsRet, nValueRet,
485 vCoins, setCoinsRet, nValueRet,
497 vCoins, setCoinsRet, nValueRet,
509 vCoins, setCoinsRet, nValueRet,
518 vCoins, setCoinsRet, nValueRet,
530 vCoins, setCoinsRet, nValueRet,
537 vCoins, setCoinsRet, nValueRet,
557 vCoins, setCoinsRet, nValueRet,
587 for (
int j = 0; j < 20; j++) {
624 vCoins, setCoinsRet, nValueRet,
659 for (uint16_t j = 0; j < 676; j++) {
672 uint16_t returnSize = std::ceil(
674 Amount returnValue = returnSize * amt;
688 for (
int i2 = 0; i2 < 100; i2++) {
761 m_wallet.SetupLegacyScriptPubKeyMan();
766 for (
int i = 0; i < 1000; i++) {
772 vCoins, setCoinsRet, nValueRet,
788 std::default_random_engine generator;
789 std::exponential_distribution<double> distribution(100);
793 for (
int i = 0; i < 100; ++i) {
797 for (
int j = 0; j < 1000; ++j) {
799 int64_t(10000000 * distribution(generator)) *
SATOSHI);
816 bool bnb_used =
false;
818 vCoins, out_set, out_value,
819 coin_selection_params_bnb, bnb_used) ||
822 out_value, coin_selection_params_knapsack, bnb_used));
823 BOOST_CHECK_GE(out_value, target);
827BOOST_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)
bool error(const char *fmt, const Args &...args)
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.
std::variant< CNoDestination, PKHash, ScriptHash > CTxDestination
A txout script template with a specific destination.
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.