9 #include <test/util/setup_common.h>
15 #include <boost/test/unit_test.hpp>
25 #define RANDOM_REPEATS 5
40 static void add_coin(
const CAmount& nValue,
int nInput, std::vector<CInputCoin>& set)
43 tx.
vout.resize(nInput + 1);
44 tx.
vout[nInput].nValue = nValue;
51 tx.
vout.resize(nInput + 1);
52 tx.
vout[nInput].nValue = nValue;
56 static void add_coin(
CWallet& wallet,
const CAmount& nValue,
int nAge = 6*24,
bool fIsFromMe =
false,
int nInput=0,
bool spendable =
false)
59 static int nextLockTime = 0;
62 tx.
vout.resize(nInput + 1);
63 tx.
vout[nInput].nValue = nValue;
81 COutput output(wtx, nInput, nAge,
true ,
true ,
true );
82 vCoins.push_back(output);
84 static void add_coin(
const CAmount& nValue,
int nAge = 6*24,
bool fIsFromMe =
false,
int nInput=0,
bool spendable =
false)
97 std::pair<CoinSet::iterator, CoinSet::iterator> ret = mismatch(a.begin(), a.end(), b.begin());
98 return ret.first == a.end() && ret.second == b.end();
105 for (
int i = 0; i < utxos; ++i) {
106 target += (
CAmount)1 << (utxos+i);
113 inline std::vector<OutputGroup>&
GroupCoins(
const std::vector<CInputCoin>& coins)
115 static std::vector<OutputGroup> static_groups;
116 static_groups.clear();
117 for (
auto& coin : coins) static_groups.emplace_back(coin, 0,
true, 0, 0);
118 return static_groups;
121 inline std::vector<OutputGroup>&
GroupCoins(
const std::vector<COutput>& coins)
123 static std::vector<OutputGroup> static_groups;
124 static_groups.clear();
126 return static_groups;
137 std::vector<CInputCoin> utxo_pool;
139 CoinSet actual_selection;
158 add_coin(1 * CENT, 1, actual_selection);
162 actual_selection.clear();
166 add_coin(2 * CENT, 2, actual_selection);
170 actual_selection.clear();
174 add_coin(4 * CENT, 4, actual_selection);
175 add_coin(1 * CENT, 1, actual_selection);
179 actual_selection.clear();
184 actual_selection.clear();
188 add_coin(1 * CENT, 1, actual_selection);
192 actual_selection.clear();
197 actual_selection.clear();
202 add_coin(5 * CENT, 5, actual_selection);
203 add_coin(4 * CENT, 4, actual_selection);
204 add_coin(1 * CENT, 1, actual_selection);
208 actual_selection.clear();
213 add_coin(5 * CENT, 5, actual_selection);
214 add_coin(3 * CENT, 3, actual_selection);
215 add_coin(2 * CENT, 2, actual_selection);
223 actual_selection.clear();
234 add_coin(7 * CENT, 7, actual_selection);
235 add_coin(7 * CENT, 7, actual_selection);
236 add_coin(7 * CENT, 7, actual_selection);
237 add_coin(7 * CENT, 7, actual_selection);
238 add_coin(2 * CENT, 7, actual_selection);
244 for (
int i = 0; i < 50000; ++i) {
256 for (
int i = 5; i <= 20; ++i) {
260 for (
int i = 0; i < 100; ++i) {
271 vCoins.at(0).nInputBytes = 40;
277 vCoins.at(0).nInputBytes = 40;
288 wallet->LoadWallet(firstRun);
289 wallet->SetupLegacyScriptPubKeyMan();
290 LOCK(wallet->cs_wallet);
291 add_coin(*wallet, 5 * CENT, 6 * 24,
false, 0,
true);
292 add_coin(*wallet, 3 * CENT, 6 * 24,
false, 0,
true);
293 add_coin(*wallet, 2 * CENT, 6 * 24,
false, 0,
true);
296 coin_control.
Select(
COutPoint(vCoins.at(0).tx->GetHash(), vCoins.at(0).i));
298 BOOST_CHECK(wallet->SelectCoins(vCoins, 10 * CENT, setCoinsRet, nValueRet, coin_control, coin_selection_params_bnb, bnb_used));
306 CoinSet setCoinsRet, setCoinsRet2;
458 for (
int j = 0; j < 20; j++)
509 for (uint16_t j = 0; j < 676; j++)
518 uint16_t returnSize = std::ceil((2000.0 +
MIN_CHANGE)/amt);
519 CAmount returnValue = amt * returnSize;
533 for (
int i2 = 0; i2 < 100; i2++)
554 BOOST_CHECK_NE(fails, RANDOM_REPEATS);
577 BOOST_CHECK_NE(fails, RANDOM_REPEATS);
596 for (
int i = 0; i < 1000; i++)
613 std::default_random_engine generator;
614 std::exponential_distribution<double> distribution (100);
618 for (
int i = 0; i < 100; ++i)
623 for (
int j = 0; j < 1000; ++j)
639 bool bnb_used =
false;
642 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())
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)
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]
CoinSelectionParams coin_selection_params(false, 0, 0, CFeeRate(0), 0)
#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)