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)