Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/test/coinselector_tests.cpp
// Copyright (c) 2017 The Bitcoin Core developers | // Copyright (c) 2017 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <amount.h> | #include <amount.h> | ||||
#include <primitives/transaction.h> | #include <primitives/transaction.h> | ||||
#include <random.h> | #include <random.h> | ||||
#include <wallet/coincontrol.h> | |||||
#include <wallet/coinselection.h> | #include <wallet/coinselection.h> | ||||
#include <wallet/wallet.h> | #include <wallet/wallet.h> | ||||
#include <test/test_bitcoin.h> | #include <test/test_bitcoin.h> | ||||
#include <wallet/test/wallet_test_fixture.h> | #include <wallet/test/wallet_test_fixture.h> | ||||
#include <boost/test/unit_test.hpp> | #include <boost/test/unit_test.hpp> | ||||
Show All 33 Lines | |||||
static void add_coin(const Amount nValue, int nInput, CoinSet &set) { | static void add_coin(const Amount nValue, int nInput, CoinSet &set) { | ||||
CMutableTransaction tx; | CMutableTransaction tx; | ||||
tx.vout.resize(nInput + 1); | tx.vout.resize(nInput + 1); | ||||
tx.vout[nInput].nValue = nValue; | tx.vout[nInput].nValue = nValue; | ||||
set.emplace(MakeTransactionRef(tx), nInput); | set.emplace(MakeTransactionRef(tx), nInput); | ||||
} | } | ||||
static void add_coin(const CWallet &wallet, const Amount nValue, | static void add_coin(CWallet &wallet, const Amount nValue, int nAge = 6 * 24, | ||||
int nAge = 6 * 24, bool fIsFromMe = false, | bool fIsFromMe = false, int nInput = 0) { | ||||
int nInput = 0) { | |||||
balance += nValue; | balance += nValue; | ||||
static int nextLockTime = 0; | static int nextLockTime = 0; | ||||
CMutableTransaction tx; | CMutableTransaction tx; | ||||
// so all transactions get different hashes | // so all transactions get different hashes | ||||
tx.nLockTime = nextLockTime++; | tx.nLockTime = nextLockTime++; | ||||
tx.vout.resize(nInput + 1); | tx.vout.resize(nInput + 1); | ||||
tx.vout[nInput].nValue = nValue; | tx.vout[nInput].nValue = nValue; | ||||
if (fIsFromMe) { | if (fIsFromMe) { | ||||
// IsFromMe() returns (GetDebit() > 0), and GetDebit() is 0 if | // IsFromMe() returns (GetDebit() > 0), and GetDebit() is 0 if | ||||
// vin.empty(), so stop vin being empty, and cache a non-zero Debit to | // vin.empty(), so stop vin being empty, and cache a non-zero Debit to | ||||
// fake out IsFromMe() | // fake out IsFromMe() | ||||
tx.vin.resize(1); | tx.vin.resize(1); | ||||
} | } | ||||
std::unique_ptr<CWalletTx> wtx( | std::unique_ptr<CWalletTx> wtx( | ||||
new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)))); | new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)))); | ||||
if (fIsFromMe) { | if (fIsFromMe) { | ||||
wtx->fDebitCached = true; | wtx->fDebitCached = true; | ||||
wtx->nDebitCached = SATOSHI; | wtx->nDebitCached = SATOSHI; | ||||
} | } | ||||
COutput output(wtx.get(), nInput, nAge, true /* spendable */, | COutput output(wtx.get(), nInput, nAge, true /* spendable */, | ||||
true /* solvable */, true /* safe */); | true /* solvable */, true /* safe */); | ||||
vCoins.push_back(output); | vCoins.push_back(output); | ||||
wallet.AddToWallet(*wtx.get()); | |||||
wtxn.emplace_back(std::move(wtx)); | wtxn.emplace_back(std::move(wtx)); | ||||
} | } | ||||
static void empty_wallet(void) { | static void empty_wallet(void) { | ||||
vCoins.clear(); | vCoins.clear(); | ||||
wtxn.clear(); | wtxn.clear(); | ||||
balance = Amount::zero(); | balance = Amount::zero(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(bnb_search_test) { | ||||
empty_wallet(); | empty_wallet(); | ||||
add_coin(m_wallet, SATOSHI); | add_coin(m_wallet, SATOSHI); | ||||
// Make sure that it has a negative effective value. The next check should | // Make sure that it has a negative effective value. The next check should | ||||
// assert if this somehow got through. Otherwise it will fail | // assert if this somehow got through. Otherwise it will fail | ||||
vCoins.at(0).nInputBytes = 40; | vCoins.at(0).nInputBytes = 40; | ||||
BOOST_CHECK(!m_wallet.SelectCoinsMinConf( | BOOST_CHECK(!m_wallet.SelectCoinsMinConf( | ||||
1 * CENT, filter_standard, vCoins, setCoinsRet, nValueRet, | 1 * CENT, filter_standard, vCoins, setCoinsRet, nValueRet, | ||||
coin_selection_params_bnb, bnb_used)); | coin_selection_params_bnb, bnb_used)); | ||||
// Make sure that we aren't using BnB when there are preset inputs | |||||
empty_wallet(); | |||||
add_coin(m_wallet, 5 * CENT); | |||||
add_coin(m_wallet, 3 * CENT); | |||||
add_coin(m_wallet, 2 * CENT); | |||||
CCoinControl coin_control; | |||||
coin_control.fAllowOtherInputs = true; | |||||
coin_control.Select(COutPoint(vCoins.at(0).tx->GetId(), vCoins.at(0).i)); | |||||
BOOST_CHECK(m_wallet.SelectCoins(vCoins, 10 * CENT, setCoinsRet, nValueRet, | |||||
coin_control, coin_selection_params_bnb, | |||||
bnb_used)); | |||||
BOOST_CHECK(!bnb_used); | |||||
BOOST_CHECK(!coin_selection_params_bnb.use_bnb); | |||||
} | } | ||||
BOOST_AUTO_TEST_CASE(knapsack_solver_test) { | BOOST_AUTO_TEST_CASE(knapsack_solver_test) { | ||||
CoinSet setCoinsRet, setCoinsRet2; | CoinSet setCoinsRet, setCoinsRet2; | ||||
Amount nValueRet; | Amount nValueRet; | ||||
bool bnb_used; | bool bnb_used; | ||||
LOCK(m_wallet.cs_wallet); | LOCK(m_wallet.cs_wallet); | ||||
▲ Show 20 Lines • Show All 447 Lines • Show Last 20 Lines |