9 #include <test/util/setup_common.h>
15 #include <boost/test/unit_test.hpp>
25 #define RANDOM_REPEATS 5
43 static void add_coin(
const CAmount& nValue,
int nInput, std::vector<CInputCoin>& set)
46 tx.
vout.resize(nInput + 1);
47 tx.
vout[nInput].nValue = nValue;
54 tx.
vout.resize(nInput + 1);
55 tx.
vout[nInput].nValue = nValue;
59 static void add_coin(
CWallet& wallet,
const CAmount& nValue,
int nAge = 6*24,
bool fIsFromMe =
false,
int nInput=0,
bool spendable =
false)
62 static int nextLockTime = 0;
65 tx.
vout.resize(nInput + 1);
66 tx.
vout[nInput].nValue = nValue;
84 COutput output(wtx, nInput, nAge,
true ,
true ,
true );
85 vCoins.push_back(output);
87 static void add_coin(
const CAmount& nValue,
int nAge = 6*24,
bool fIsFromMe =
false,
int nInput=0,
bool spendable =
false)
100 std::pair<CoinSet::iterator, CoinSet::iterator> ret = mismatch(a.begin(), a.end(), b.begin());
101 return ret.first == a.end() && ret.second == b.end();
108 for (
int i = 0; i < utxos; ++i) {
109 target += (
CAmount)1 << (utxos+i);
116 inline std::vector<OutputGroup>&
GroupCoins(
const std::vector<CInputCoin>& coins)
118 static std::vector<OutputGroup> static_groups;
119 static_groups.clear();
120 for (
auto& coin : coins) static_groups.emplace_back(coin, 0,
true, 0, 0);
121 return static_groups;
124 inline std::vector<OutputGroup>&
GroupCoins(
const std::vector<COutput>& coins)
126 static std::vector<OutputGroup> static_groups;
127 static_groups.clear();
129 return static_groups;
140 std::vector<CInputCoin> utxo_pool;
142 CoinSet actual_selection;
161 add_coin(1 * CENT, 1, actual_selection);
165 actual_selection.clear();
169 add_coin(2 * CENT, 2, actual_selection);
173 actual_selection.clear();
177 add_coin(4 * CENT, 4, actual_selection);
178 add_coin(1 * CENT, 1, actual_selection);
182 actual_selection.clear();
187 actual_selection.clear();
191 add_coin(1 * CENT, 1, actual_selection);
195 actual_selection.clear();
200 actual_selection.clear();
205 add_coin(5 * CENT, 5, actual_selection);
206 add_coin(4 * CENT, 4, actual_selection);
207 add_coin(1 * CENT, 1, actual_selection);
211 actual_selection.clear();
216 add_coin(5 * CENT, 5, actual_selection);
217 add_coin(3 * CENT, 3, actual_selection);
218 add_coin(2 * CENT, 2, actual_selection);
226 actual_selection.clear();
237 add_coin(7 * CENT, 7, actual_selection);
238 add_coin(7 * CENT, 7, actual_selection);
239 add_coin(7 * CENT, 7, actual_selection);
240 add_coin(7 * CENT, 7, actual_selection);
241 add_coin(2 * CENT, 7, actual_selection);
247 for (
int i = 0; i < 50000; ++i) {
259 for (
int i = 5; i <= 20; ++i) {
263 for (
int i = 0; i < 100; ++i) {
277 vCoins.at(0).nInputBytes = 40;
283 vCoins.at(0).nInputBytes = 40;
294 wallet->LoadWallet(firstRun);
295 wallet->SetupLegacyScriptPubKeyMan();
296 LOCK(wallet->cs_wallet);
297 add_coin(*wallet, 5 * CENT, 6 * 24,
false, 0,
true);
298 add_coin(*wallet, 3 * CENT, 6 * 24,
false, 0,
true);
299 add_coin(*wallet, 2 * CENT, 6 * 24,
false, 0,
true);
302 coin_control.
Select(
COutPoint(vCoins.at(0).tx->GetHash(), vCoins.at(0).i));
304 BOOST_CHECK(wallet->SelectCoins(vCoins, 10 * CENT, setCoinsRet, nValueRet, coin_control, coin_selection_params_bnb, bnb_used));
312 CoinSet setCoinsRet, setCoinsRet2;
464 for (
int j = 0; j < 20; j++)
515 for (uint16_t j = 0; j < 676; j++)
524 uint16_t returnSize = std::ceil((2000.0 +
MIN_CHANGE)/amt);
525 CAmount returnValue = amt * returnSize;
539 for (
int i2 = 0; i2 < 100; i2++)
560 BOOST_CHECK_NE(fails, RANDOM_REPEATS);
583 BOOST_CHECK_NE(fails, RANDOM_REPEATS);
602 for (
int i = 0; i < 1000; i++)
619 std::default_random_engine generator;
620 std::exponential_distribution<double> distribution (100);
624 for (
int i = 0; i < 100; ++i)
629 for (
int j = 0; j < 1000; ++j)
651 bool bnb_used =
false;
654 BOOST_CHECK_GE(out_value, target);
static CAmount make_hard_case(int utxos, std::vector< CInputCoin > &utxo_pool)
void SetupLegacyScriptPubKeyMan()
Make a LegacyScriptPubKeyMan and set it for all types, internal, and external.
std::unique_ptr< WalletDatabase > CreateMockWalletDatabase()
Return object for accessing temporary in-memory database.
bool m_is_cache_empty
This flag is true if all m_amounts caches are empty.
static CWallet testWallet(testChain.get(),"", CreateDummyWalletDatabase())
CFeeRate m_effective_feerate
static bool equal_sets(CoinSet a, CoinSet b)
static const CAmount COIN
static void empty_wallet(void)
bool SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const CAmount &target_value, const CAmount &cost_of_change, std::set< CInputCoin > &out_set, CAmount &value_ret, CAmount not_input_fees)
static CTransactionRef MakeTransactionRef()
CoinEligibilityFilter filter_standard(1, 6, 0)
static constexpr CAmount MIN_CHANGE
target minimum change amount
static void add_coin(const CAmount &nValue, int nInput, std::vector< CInputCoin > &set)
static NodeContext testNode
BOOST_AUTO_TEST_CASE(bnb_search_test)
std::unique_ptr< Chain > MakeChain(NodeContext &node)
Return implementation of Chain interface.
std::set< CInputCoin > CoinSet
int64_t CAmount
Amount in satoshis (Can be negative)
CoinSelectionParams coin_selection_params(false, 0, 0, CFeeRate(0), CFeeRate(0), CFeeRate(0), 0)
bool error(const char *fmt, const Args &...args)
NodeContext struct containing references to chain state and connection state.
void Set(isminefilter filter, CAmount value)
void Select(const COutPoint &output)
bool fAllowOtherInputs
If false, allows unselected inputs, but requires all selected inputs be used.
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
std::vector< OutputGroup > & GroupCoins(const std::vector< CInputCoin > &coins)
std::unique_ptr< WalletDatabase > CreateDummyWalletDatabase()
Return object for accessing dummy database with no read/write capabilities.
CoinEligibilityFilter filter_confirmed(1, 1, 0)
CWalletTx * AddToWallet(CTransactionRef tx, const CWalletTx::Confirmation &confirm, const UpdateWalletTxFn &update_wtx=nullptr, bool fFlushOnClose=true)
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
An outpoint - a combination of a transaction hash and an index n into its vout.
bool SelectCoinsMinConf(const CAmount &nTargetValue, const CoinEligibilityFilter &eligibility_filter, std::vector< OutputGroup > groups, std::set< CInputCoin > &setCoinsRet, CAmount &nValueRet, const CoinSelectionParams &coin_selection_params, bool &bnb_used) const
Shuffle and select coins until nTargetValue is reached while avoiding small change; This method is st...
std::vector< CTxOut > vout
A transaction with a bunch of additional info that only the owner cares about.
CachableAmount m_amounts[AMOUNTTYPE_ENUM_ELEMENTS]
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Testing setup and teardown for wallet.
#define BOOST_CHECK_EQUAL(v1, v2)
CoinEligibilityFilter filter_standard_extra(6, 6, 0)
#define BOOST_AUTO_TEST_SUITE_END()
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Fee rate in satoshis per kilobyte: CAmount / kB.
A mutable version of CTransaction.
static void ApproximateBestSubset(const std::vector< OutputGroup > &groups, const CAmount &nTotalLower, const CAmount &nTargetValue, std::vector< char > &vfBest, CAmount &nBest, int iterations=1000)
static std::vector< COutput > vCoins
boost::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
bool GetNewDestination(const OutputType type, const std::string label, CTxDestination &dest, std::string &error)
#define BOOST_CHECK(expr)