17#include <boost/test/unit_test.hpp> 
   27#define RANDOM_REPEATS 5 
   35static void add_coin(
const CAmount& nValue, 
int nInput, std::vector<CInputCoin>& set)
 
   38    tx.
vout.resize(nInput + 1);
 
   39    tx.
vout[nInput].nValue = nValue;
 
   46    tx.
vout.resize(nInput + 1);
 
   47    tx.
vout[nInput].nValue = nValue;
 
   55static void add_coin(std::vector<COutput>& coins, 
CWallet& 
wallet, 
const CAmount& nValue, 
int nAge = 6*24, 
bool fIsFromMe = 
false, 
int nInput=0, 
bool spendable = 
false)
 
   57    static int nextLockTime = 0;
 
   60    tx.
vout.resize(nInput + 1);
 
   61    tx.
vout[nInput].nValue = nValue;
 
   77    auto ret = 
wallet.mapWallet.emplace(std::piecewise_construct, std::forward_as_tuple(txid), std::forward_as_tuple(
MakeTransactionRef(std::move(tx))));
 
   85    COutput output(
wallet, wtx, nInput, nAge, 
true , 
true , 
true );
 
   86    coins.push_back(output);
 
   91    std::pair<CoinSet::iterator, CoinSet::iterator> ret = mismatch(a.begin(), a.end(), b.begin());
 
   92    return ret.first == a.end() && ret.second == b.end();
 
   99    for (
int i = 0; i < utxos; ++i) {
 
  100        target += (
CAmount)1 << (utxos+i);
 
  107inline std::vector<OutputGroup>& 
GroupCoins(
const std::vector<CInputCoin>& coins)
 
  109    static std::vector<OutputGroup> static_groups;
 
  110    static_groups.clear();
 
  111    for (
auto& coin : coins) {
 
  112        static_groups.emplace_back();
 
  113        static_groups.back().Insert(coin, 0, 
true, 0, 0, 
false);
 
  115    return static_groups;
 
  118inline std::vector<OutputGroup>& 
GroupCoins(
const std::vector<COutput>& coins)
 
  120    static std::vector<OutputGroup> static_groups;
 
  121    static_groups.clear();
 
  122    for (
auto& coin : coins) {
 
  123        static_groups.emplace_back();
 
  126    return static_groups;
 
  135    static std::vector<OutputGroup> static_groups;
 
  137    return static_groups;
 
  144    std::vector<CInputCoin> utxo_pool;
 
  168    actual_selection.clear();
 
  176    actual_selection.clear();
 
  185    actual_selection.clear();
 
  190    actual_selection.clear();
 
  198    actual_selection.clear();
 
  203    actual_selection.clear();
 
  214    actual_selection.clear();
 
  229    actual_selection.clear();
 
  250    for (
int i = 0; i < 50000; ++i) {
 
  262    for (
int i = 5; i <= 20; ++i) {
 
  266    for (
int i = 0; i < 100; ++i) {
 
  280        wallet->SetupDescriptorScriptPubKeyMans();
 
  282        std::vector<COutput> coins;
 
  287        coins.at(0).nInputBytes = 40; 
 
  293        coins.at(0).nInputBytes = 40;
 
  304        wallet->SetupDescriptorScriptPubKeyMans();
 
  306        std::vector<COutput> coins;
 
  315        coin_control.
Select(
COutPoint(coins.at(0).tx->GetHash(), coins.at(0).i));
 
  327    wallet->SetupDescriptorScriptPubKeyMans();
 
  329    CoinSet setCoinsRet, setCoinsRet2;
 
  331    std::vector<COutput> coins;
 
  478        for (
int j = 0; j < 20; j++)
 
  529        for (uint16_t j = 0; j < 676; j++)
 
  538                uint16_t returnSize = std::ceil((2000.0 + 
MIN_CHANGE)/amt);
 
  539                CAmount returnValue = amt * returnSize;
 
  553        for (
int i2 = 0; i2 < 100; i2++)
 
  608    wallet->SetupDescriptorScriptPubKeyMans();
 
  612    std::vector<COutput> coins;
 
  615    for (
int i = 0; i < 1000; i++)
 
  631    wallet->SetupDescriptorScriptPubKeyMans();
 
  634    std::default_random_engine generator;
 
  635    std::exponential_distribution<double> distribution (100);
 
  639    for (
int i = 0; i < 100; ++i)
 
  641        std::vector<COutput> coins;
 
  645        for (
int j = 0; j < 1000; ++j)
 
  647            CAmount val = distribution(generator)*10000000;
 
  667        BOOST_CHECK_GE(out_value, target);
 
  675    const CAmount change_cost{125};
 
  679    const CAmount excess{in_amt - fee * 2 - target};
 
  708    add_coin(1 * 
COIN, 1, selection, fee * 2, fee - fee_diff);
 
  709    add_coin(2 * 
COIN, 2, selection, fee * 2, fee - fee_diff);
 
  711    BOOST_CHECK_GT(waste2, waste1);
 
  720    BOOST_CHECK_LT(waste3, waste1);
 
  729    BOOST_CHECK_LT(waste_nochange2, waste_nochange1);
 
  735    const CAmount exact_target{in_amt - fee * 2};
 
  740    const CAmount new_change_cost{fee_diff * 2};
 
  747    const CAmount new_target{in_amt - fee * 2 - fee_diff * 2};
 
int64_t CAmount
Amount in satoshis (Can be negative)
static constexpr CAmount COIN
The amount of satoshis in one BTC.
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: CAmount / kB.
An outpoint - a combination of a transaction hash and an index n into its vout.
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
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
bool KnapsackSolver(const CAmount &nTargetValue, std::vector< OutputGroup > &groups, std::set< CInputCoin > &setCoinsRet, CAmount &nValueRet)
bool SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const CAmount &selection_target, const CAmount &cost_of_change, std::set< CInputCoin > &out_set, CAmount &value_ret)
static void ApproximateBestSubset(const std::vector< OutputGroup > &groups, const CAmount &nTotalLower, const CAmount &nTargetValue, std::vector< char > &vfBest, CAmount &nBest, int iterations=1000)
CAmount GetSelectionWaste(const std::set< CInputCoin > &inputs, CAmount change_cost, CAmount target, bool use_effective_value)
Compute the waste for this result given the cost of change and the opportunity cost of spending these...
static constexpr CAmount MIN_CHANGE
target minimum change amount
static const CoinEligibilityFilter filter_standard(1, 6, 0)
std::vector< OutputGroup > & KnapsackGroupOutputs(const std::vector< COutput > &coins, CWallet &wallet, const CoinEligibilityFilter &filter)
static void add_coin(const CAmount &nValue, int nInput, std::vector< CInputCoin > &set)
static CAmount make_hard_case(int utxos, std::vector< CInputCoin > &utxo_pool)
BOOST_AUTO_TEST_CASE(bnb_search_test)
static const CoinEligibilityFilter filter_confirmed(1, 1, 0)
static bool equal_sets(CoinSet a, CoinSet b)
std::set< CInputCoin > CoinSet
std::vector< OutputGroup > & GroupCoins(const std::vector< CInputCoin > &coins)
static const CoinEligibilityFilter filter_standard_extra(6, 6, 0)
BOOST_AUTO_TEST_SUITE_END()
#define BOOST_FIXTURE_TEST_SUITE(a, b)
#define BOOST_CHECK_EQUAL(v1, v2)
#define BOOST_CHECK(expr)
static CTransactionRef MakeTransactionRef(Tx &&txIn)
static constexpr CAmount CENT
std::vector< OutputGroup > GroupOutputs(const CWallet &wallet, const std::vector< COutput > &outputs, const CoinSelectionParams &coin_sel_params, const CoinEligibilityFilter &filter, bool positive_only)
bool SelectCoins(const CWallet &wallet, const std::vector< COutput > &vAvailableCoins, const CAmount &nTargetValue, std::set< CInputCoin > &setCoinsRet, CAmount &nValueRet, const CCoinControl &coin_control, CoinSelectionParams &coin_selection_params)
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, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
A mutable version of CTransaction.
uint256 GetHash() const
Compute the hash of this CMutableTransaction.
std::vector< CTxOut > vout
void Set(isminefilter filter, CAmount value)
Parameters for filtering which OutputGroups we may use in coin selection.
Parameters for one iteration of Coin Selection.
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
CAmount m_cost_of_change
Cost of creating the change output + cost of spending the change output in the future.
CFeeRate m_effective_feerate
The targeted feerate of the transaction being built.
std::unique_ptr< interfaces::Chain > chain
Testing setup and teardown for wallet.
bool error(const char *fmt, const Args &... args)
std::unique_ptr< WalletDatabase > CreateMockWalletDatabase()
Return object for accessing temporary in-memory database.
@ WALLET_FLAG_DESCRIPTORS
Indicate that this wallet supports DescriptorScriptPubKeyMan.