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(),
"",
334 wallet->LoadWallet(firstRun);
336 wallet->SetupLegacyScriptPubKeyMan();
346 nValueRet, coin_control,
347 coin_selection_params_bnb, bnb_used));
357 CoinSet setCoinsRet, setCoinsRet2;
370 vCoins, setCoinsRet, nValueRet,
378 vCoins, setCoinsRet, nValueRet,
383 vCoins, setCoinsRet, nValueRet,
391 vCoins, setCoinsRet, nValueRet,
396 vCoins, setCoinsRet, nValueRet,
403 add_coin(testWallet, 10 * CENT, 3,
true);
412 vCoins, setCoinsRet, nValueRet,
421 vCoins, setCoinsRet, nValueRet,
426 vCoins, setCoinsRet, nValueRet,
432 vCoins, setCoinsRet, nValueRet,
443 vCoins, setCoinsRet, nValueRet,
451 vCoins, setCoinsRet, nValueRet,
459 vCoins, setCoinsRet, nValueRet,
477 vCoins, setCoinsRet, nValueRet,
480 vCoins, setCoinsRet, nValueRet,
486 vCoins, setCoinsRet, nValueRet,
498 vCoins, setCoinsRet, nValueRet,
510 vCoins, setCoinsRet, nValueRet,
519 vCoins, setCoinsRet, nValueRet,
531 vCoins, setCoinsRet, nValueRet,
538 vCoins, setCoinsRet, nValueRet,
558 vCoins, setCoinsRet, nValueRet,
588 for (
int j = 0; j < 20; j++) {
625 vCoins, setCoinsRet, nValueRet,
660 for (uint16_t j = 0; j < 676; j++) {
673 uint16_t returnSize = std::ceil(
675 Amount returnValue = returnSize * amt;
689 for (
int i2 = 0; i2 < 100; i2++) {
762 m_wallet.SetupLegacyScriptPubKeyMan();
767 for (
int i = 0; i < 1000; i++) {
773 vCoins, setCoinsRet, nValueRet,
789 std::default_random_engine generator;
790 std::exponential_distribution<double> distribution(100);
794 for (
int i = 0; i < 100; ++i) {
798 for (
int j = 0; j < 1000; ++j) {
800 int64_t(10000000 * distribution(generator)) *
SATOSHI);
817 bool bnb_used =
false;
819 vCoins, out_set, out_value,
820 coin_selection_params_bnb, bnb_used) ||
823 out_value, coin_selection_params_knapsack, bnb_used));
824 BOOST_CHECK_GE(out_value, target);
828BOOST_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.