11 #include <test/test_bitcoin.h> 14 #include <boost/test/unit_test.hpp> 24 #define RANDOM_REPEATS 5 26 std::vector<std::unique_ptr<CWalletTx>>
wtxn;
30 static std::vector<COutput> vCoins;
39 static void add_coin(
const CAmount& nValue,
int nInput, std::vector<CInputCoin>&
set)
42 tx.
vout.resize(nInput + 1);
43 tx.
vout[nInput].nValue = nValue;
44 set.emplace_back(MakeTransactionRef(tx), nInput);
47 static void add_coin(
const CAmount& nValue,
int nInput,
CoinSet&
set)
50 tx.
vout.resize(nInput + 1);
51 tx.
vout[nInput].nValue = nValue;
52 set.emplace(MakeTransactionRef(tx), nInput);
55 static void add_coin(
const CAmount& nValue,
int nAge = 6*24,
bool fIsFromMe =
false,
int nInput=0)
58 static int nextLockTime = 0;
61 tx.
vout.resize(nInput + 1);
62 tx.
vout[nInput].nValue = nValue;
68 std::unique_ptr<CWalletTx> wtx = MakeUnique<CWalletTx>(&testWallet, MakeTransactionRef(std::move(tx)));
71 wtx->fDebitCached =
true;
72 wtx->nDebitCached = 1;
74 COutput output(wtx.get(), nInput, nAge,
true ,
true ,
true );
75 vCoins.push_back(output);
77 wtxn.emplace_back(std::move(wtx));
80 static void empty_wallet(
void)
89 std::pair<CoinSet::iterator, CoinSet::iterator>
ret = mismatch(a.begin(), a.end(), b.begin());
90 return ret.first == a.end() &&
ret.second == b.end();
93 static CAmount make_hard_case(
int utxos, std::vector<CInputCoin>& utxo_pool)
97 for (
int i = 0; i < utxos; ++i) {
98 target += (
CAmount)1 << (utxos+i);
99 add_coin((
CAmount)1 << (utxos+i), 2*i, utxo_pool);
100 add_coin(((
CAmount)1 << (utxos+i)) + ((
CAmount)1 << (utxos-1-i)), 2*i + 1, utxo_pool);
105 inline std::vector<OutputGroup>&
GroupCoins(
const std::vector<CInputCoin>& coins)
107 static std::vector<OutputGroup> static_groups;
108 static_groups.clear();
109 for (
auto& coin : coins) static_groups.emplace_back(coin, 0,
true, 0, 0);
110 return static_groups;
113 inline std::vector<OutputGroup>&
GroupCoins(
const std::vector<COutput>& coins)
115 static std::vector<OutputGroup> static_groups;
116 static_groups.clear();
117 for (
auto& coin : coins) static_groups.emplace_back(coin.GetInputCoin(), coin.nDepth, coin.tx->fDebitCached && coin.tx->nDebitCached == 1 , 0, 0);
118 return static_groups;
128 std::vector<CInputCoin> utxo_pool;
137 BOOST_TEST_MESSAGE(
"Testing known outcomes");
144 add_coin(1 * CENT, 1, utxo_pool);
145 add_coin(2 * CENT, 2, utxo_pool);
146 add_coin(3 * CENT, 3, utxo_pool);
147 add_coin(4 * CENT, 4, utxo_pool);
150 add_coin(1 * CENT, 1, actual_selection);
152 BOOST_CHECK(equal_sets(selection, actual_selection));
154 actual_selection.clear();
158 add_coin(2 * CENT, 2, actual_selection);
160 BOOST_CHECK(equal_sets(selection, actual_selection));
162 actual_selection.clear();
166 add_coin(3 * CENT, 3, actual_selection);
167 add_coin(2 * CENT, 2, actual_selection);
169 BOOST_CHECK(equal_sets(selection, actual_selection));
171 actual_selection.clear();
176 actual_selection.clear();
180 add_coin(5 * CENT, 5, utxo_pool);
181 add_coin(4 * CENT, 4, actual_selection);
182 add_coin(3 * CENT, 3, actual_selection);
183 add_coin(2 * CENT, 2, actual_selection);
184 add_coin(1 * CENT, 1, actual_selection);
186 BOOST_CHECK(equal_sets(selection, actual_selection));
188 actual_selection.clear();
193 add_coin(5 * CENT, 5, actual_selection);
194 add_coin(3 * CENT, 3, actual_selection);
195 add_coin(2 * CENT, 2, actual_selection);
203 actual_selection.clear();
207 CAmount target = make_hard_case(17, utxo_pool);
209 target = make_hard_case(14, utxo_pool);
214 add_coin(7 * CENT, 7, actual_selection);
215 add_coin(7 * CENT, 7, actual_selection);
216 add_coin(7 * CENT, 7, actual_selection);
217 add_coin(7 * CENT, 7, actual_selection);
218 add_coin(2 * CENT, 7, actual_selection);
219 add_coin(7 * CENT, 7, utxo_pool);
220 add_coin(7 * CENT, 7, utxo_pool);
221 add_coin(7 * CENT, 7, utxo_pool);
222 add_coin(7 * CENT, 7, utxo_pool);
223 add_coin(2 * CENT, 7, utxo_pool);
224 for (
int i = 0; i < 50000; ++i) {
225 add_coin(5 * CENT, 7, utxo_pool);
229 BOOST_CHECK(equal_sets(selection, actual_selection));
236 for (
int i = 5; i <= 20; ++i) {
237 add_coin(i * CENT, i, utxo_pool);
240 for (
int i = 0; i < 100; ++i) {
251 vCoins.at(0).nInputBytes = 40;
261 coin_control.
Select(
COutPoint(vCoins.at(0).tx->GetHash(), vCoins.at(0).i));
262 BOOST_CHECK(testWallet.
SelectCoins(vCoins, 10 * CENT, setCoinsRet, nValueRet, coin_control, coin_selection_params_bnb, bnb_used));
269 CoinSet setCoinsRet, setCoinsRet2;
302 add_coin(10*CENT, 3,
true);
391 add_coin(MIN_CHANGE * 1 / 10);
392 add_coin(MIN_CHANGE * 2 / 10);
393 add_coin(MIN_CHANGE * 3 / 10);
394 add_coin(MIN_CHANGE * 4 / 10);
395 add_coin(MIN_CHANGE * 5 / 10);
403 add_coin(1111*MIN_CHANGE);
410 add_coin(MIN_CHANGE * 6 / 10);
411 add_coin(MIN_CHANGE * 7 / 10);
420 for (
int j = 0; j < 20; j++)
421 add_coin(50000 * COIN);
432 add_coin(MIN_CHANGE * 5 / 10);
433 add_coin(MIN_CHANGE * 6 / 10);
434 add_coin(MIN_CHANGE * 7 / 10);
435 add_coin(1111 * MIN_CHANGE);
442 add_coin(MIN_CHANGE * 4 / 10);
443 add_coin(MIN_CHANGE * 6 / 10);
444 add_coin(MIN_CHANGE * 8 / 10);
445 add_coin(1111 * MIN_CHANGE);
452 add_coin(MIN_CHANGE * 5 / 100);
453 add_coin(MIN_CHANGE * 1);
454 add_coin(MIN_CHANGE * 100);
468 for (
CAmount amt=1500; amt < COIN; amt*=10) {
471 for (uint16_t j = 0; j < 676; j++)
478 if (amt - 2000 < MIN_CHANGE) {
480 uint16_t returnSize = std::ceil((2000.0 + MIN_CHANGE)/amt);
481 CAmount returnValue = amt * returnSize;
495 for (
int i2 = 0; i2 < 100; i2++)
504 BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2));
513 if (equal_sets(setCoinsRet, setCoinsRet2))
536 if (equal_sets(setCoinsRet, setCoinsRet2))
557 for (
int i = 0; i < 1000; i++)
558 add_coin(1000 * COIN);
572 std::default_random_engine generator;
573 std::exponential_distribution<double> distribution (100);
577 for (
int i = 0; i < 100; ++i)
582 for (
int j = 0; j < 1000; ++j)
584 add_coin((
CAmount)(distribution(generator)*10000000));
598 bool bnb_used =
false;
601 BOOST_CHECK_GE(out_value, target);
static std::unique_ptr< BerkeleyDatabase > CreateDummy()
Return object for accessing dummy database with no read/write capabilities.
std::set< CInputCoin > CoinSet
UniValue ret(UniValue::VARR)
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)
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...
uint64_t randrange(uint64_t range)
Generate a random integer in the range [0..range).
CoinEligibilityFilter filter_standard(1, 6, 0)
BOOST_AUTO_TEST_CASE(bnb_search_test)
std::set< CInputCoin > CoinSet
int64_t CAmount
Amount in satoshis (Can be negative)
bool SelectCoins(const std::vector< COutput > &vAvailableCoins, const CAmount &nTargetValue, std::set< CInputCoin > &setCoinsRet, CAmount &nValueRet, const CCoinControl &coin_control, CoinSelectionParams &coin_selection_params, bool &bnb_used) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Select a set of coins such that nValueRet >= nTargetValue and at least all coins from coinControl are...
void Select(const COutPoint &output)
bool fAllowOtherInputs
If false, allows unselected inputs, but requires all selected inputs be used.
std::vector< OutputGroup > & GroupCoins(const std::vector< CInputCoin > &coins)
CoinEligibilityFilter filter_confirmed(1, 1, 0)
An outpoint - a combination of a transaction hash and an index n into its vout.
CCriticalSection cs_wallet
std::vector< CTxOut > vout
bool AddToWallet(const CWalletTx &wtxIn, bool fFlushOnClose=true)
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 is an extension of a keystore, which also maintains a set of transactions and balances...
Fee rate in satoshis per kilobyte: CAmount / kB.
A mutable version of CTransaction.
std::vector< std::unique_ptr< CWalletTx > > wtxn
#define BOOST_CHECK(expr)