Merge pull request #451 from rnicoll/1.7-dev-tx-fee
Correct unit tests for wallet
This commit is contained in:
commit
9a482a4d62
|
@ -59,7 +59,7 @@ static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
|
|||
/** The pre-allocation chunk size for rev?????.dat files (since 0.8) */
|
||||
static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
|
||||
/** Dust Soft Limit, allowed with additional fee per output */
|
||||
static const int64_t DUST_SOFT_LIMIT = 100000000;
|
||||
static const int64_t DUST_SOFT_LIMIT = COIN;
|
||||
/** Dust Hard Limit, ignored as wallet inputs (mininput default) */
|
||||
static const int64_t DUST_HARD_LIMIT = 1000000;
|
||||
/** Coinbase transaction outputs can only be spent after this number of new blocks (network rule) */
|
||||
|
|
|
@ -130,51 +130,51 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests)
|
|||
// now clear out the wallet and start again to test choosing between subsets of smaller coins and the next biggest coin
|
||||
empty_wallet();
|
||||
|
||||
add_coin( 6*CENT);
|
||||
add_coin( 7*CENT);
|
||||
add_coin( 8*CENT);
|
||||
add_coin(20*CENT);
|
||||
add_coin(30*CENT); // now we have 6+7+8+20+30 = 71 cents total
|
||||
add_coin( 6*COIN);
|
||||
add_coin( 7*COIN);
|
||||
add_coin( 8*COIN);
|
||||
add_coin(20*COIN);
|
||||
add_coin(30*COIN); // now we have 6+7+8+20+30 = 71 coins total
|
||||
|
||||
// check that we have 71 and not 72
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(71 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(71 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
|
||||
// now try making 16 cents. the best smaller coins can do is 6+7+8 = 21; not as good at the next biggest coin, 20
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); // we should get 20 in one coin
|
||||
// now try making 16 coins. the best smaller coins can do is 6+7+8 = 21; not as good at the next biggest coin, 20
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(16 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 20 * COIN); // we should get 20 in one coin
|
||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
|
||||
|
||||
add_coin( 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total
|
||||
add_coin( 5*COIN); // now we have 5+6+7+8+20+30 = 75 coins total
|
||||
|
||||
// now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, better than the next biggest coin, 20
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 3 coins
|
||||
// now if we try making 16 coins again, the smaller coins can make 5+6+7 = 18 coins, better than the next biggest coin, 20
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(16 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 18 * COIN); // we should get 18 in 3 coins
|
||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U);
|
||||
|
||||
add_coin( 18*CENT); // now we have 5+6+7+8+18+20+30
|
||||
add_coin( 18*COIN); // now we have 5+6+7+8+18+20+30
|
||||
|
||||
// and now if we try making 16 cents again, the smaller coins can make 5+6+7 = 18 cents, the same as the next biggest coin, 18
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(16 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 1 coin
|
||||
// and now if we try making 16 coins again, the smaller coins can make 5+6+7 = 18 coins, the same as the next biggest coin, 18
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(16 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 18 * COIN); // we should get 18 in 1 coin
|
||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // because in the event of a tie, the biggest coin wins
|
||||
|
||||
// now try making 11 cents. we should get 5+6
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(11 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 11 * CENT);
|
||||
// now try making 11 coins. we should get 5+6
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(11 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 11 * COIN);
|
||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
|
||||
|
||||
// check that the smallest bigger coin is used
|
||||
add_coin( 1*COIN);
|
||||
add_coin( 2*COIN);
|
||||
add_coin( 3*COIN);
|
||||
add_coin( 4*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(95 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); // we should get 1 BTC in 1 coin
|
||||
add_coin( 100*COIN);
|
||||
add_coin( 200*COIN);
|
||||
add_coin( 300*COIN);
|
||||
add_coin( 400*COIN); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 coins
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(95 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 100 * COIN); // we should get 200 DOGE in 1 coin.
|
||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
|
||||
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(195 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 200 * COIN); // we should get 3 DOGE in 1 coin
|
||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U);
|
||||
|
||||
// empty the wallet and start again, now with fractions of a cent, to test sub-cent change avoidance
|
||||
|
@ -240,18 +240,18 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests)
|
|||
|
||||
// test avoiding sub-cent change
|
||||
empty_wallet();
|
||||
add_coin(0.0005 * COIN);
|
||||
add_coin(0.01 * COIN);
|
||||
add_coin(0.05 * COIN);
|
||||
add_coin(1 * COIN);
|
||||
add_coin(100 * COIN);
|
||||
|
||||
// trying to make 1.0001 from these three coins
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(1.0001 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 1.0105 * COIN); // we should get all coins
|
||||
// trying to make 100.01 from these three coins
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(100.01 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 101.05 * COIN); // we should get all coins
|
||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U);
|
||||
|
||||
// but if we try to make 0.999, we should take the bigger of the two small coins to avoid sub-cent change
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(0.999 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 1.01 * COIN); // we should get 1 + 0.01
|
||||
// but if we try to make 99.9, we should take the bigger of the two small coins to avoid sub-cent change
|
||||
BOOST_CHECK( wallet.SelectCoinsMinConf(99.9 * COIN, 1, 1, vCoins, setCoinsRet, nValueRet));
|
||||
BOOST_CHECK_EQUAL(nValueRet, 101 * COIN); // we should get 100 + 1
|
||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
|
||||
|
||||
// test randomness
|
||||
|
|
|
@ -1226,8 +1226,14 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfT
|
|||
nValueRet += coin.first;
|
||||
return true;
|
||||
}
|
||||
else if (n < nTargetValue + COIN)
|
||||
else if (n < nTargetValue + DUST_SOFT_LIMIT)
|
||||
{
|
||||
// This coin is not sufficient to cover the target plus change above the dust
|
||||
// limit. The dust limit is important here, as we don't want to leave change
|
||||
// which cannot be spent (is below the network transaction fee).
|
||||
|
||||
// Push the coin into an array for potential matching later, but keep trying to find
|
||||
// an exact match
|
||||
vValue.push_back(coin);
|
||||
nTotalLower += n;
|
||||
}
|
||||
|
@ -1262,13 +1268,13 @@ bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfT
|
|||
int64_t nBest;
|
||||
|
||||
ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
|
||||
if (nBest != nTargetValue && nTotalLower >= nTargetValue + COIN)
|
||||
ApproximateBestSubset(vValue, nTotalLower, nTargetValue + COIN, vfBest, nBest, 1000);
|
||||
if (nBest != nTargetValue && nTotalLower >= nTargetValue + DUST_SOFT_LIMIT)
|
||||
ApproximateBestSubset(vValue, nTotalLower, nTargetValue + DUST_SOFT_LIMIT, vfBest, nBest, 1000);
|
||||
|
||||
// If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
|
||||
// or the next bigger coin is closer), return the bigger coin
|
||||
if (coinLowestLarger.second.first &&
|
||||
((nBest != nTargetValue && nBest < nTargetValue + COIN) || coinLowestLarger.first <= nBest))
|
||||
((nBest != nTargetValue && nBest < nTargetValue + DUST_SOFT_LIMIT) || coinLowestLarger.first <= nBest))
|
||||
{
|
||||
setCoinsRet.insert(coinLowestLarger.second);
|
||||
nValueRet += coinLowestLarger.first;
|
||||
|
|
Loading…
Reference in a new issue