26
26
typedef set<pair<const CWalletTx*,unsigned int> > CoinSet;
28
BOOST_FIXTURE_TEST_SUITE(wallet_tests, TestingSetup)
28
BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup)
30
static CWallet wallet;
30
static const CWallet wallet;
31
31
static vector<COutput> vCoins;
33
33
static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = false, int nInput=0)
48
48
wtx->fDebitCached = true;
49
49
wtx->nDebitCached = 1;
51
COutput output(wtx, nInput, nAge, true);
51
COutput output(wtx, nInput, nAge, true, true);
52
52
vCoins.push_back(output);
188
188
// empty the wallet and start again, now with fractions of a cent, to test small change avoidance
191
add_coin(0.1*MIN_CHANGE);
192
add_coin(0.2*MIN_CHANGE);
193
add_coin(0.3*MIN_CHANGE);
194
add_coin(0.4*MIN_CHANGE);
195
add_coin(0.5*MIN_CHANGE);
191
add_coin(MIN_CHANGE * 1 / 10);
192
add_coin(MIN_CHANGE * 2 / 10);
193
add_coin(MIN_CHANGE * 3 / 10);
194
add_coin(MIN_CHANGE * 4 / 10);
195
add_coin(MIN_CHANGE * 5 / 10);
197
197
// try making 1 * MIN_CHANGE from the 1.5 * MIN_CHANGE
198
198
// we'll get change smaller than MIN_CHANGE whatever happens, so can expect MIN_CHANGE exactly
207
207
BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); // we should get the exact amount
209
209
// if we add more small coins:
210
add_coin(0.6*MIN_CHANGE);
211
add_coin(0.7*MIN_CHANGE);
210
add_coin(MIN_CHANGE * 6 / 10);
211
add_coin(MIN_CHANGE * 7 / 10);
213
213
// and try again to make 1.0 * MIN_CHANGE
214
214
BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
230
230
// sometimes it will fail, and so we use the next biggest coin:
232
add_coin(0.5 * MIN_CHANGE);
233
add_coin(0.6 * MIN_CHANGE);
234
add_coin(0.7 * MIN_CHANGE);
232
add_coin(MIN_CHANGE * 5 / 10);
233
add_coin(MIN_CHANGE * 6 / 10);
234
add_coin(MIN_CHANGE * 7 / 10);
235
235
add_coin(1111 * MIN_CHANGE);
236
236
BOOST_CHECK( wallet.SelectCoinsMinConf(1 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
237
237
BOOST_CHECK_EQUAL(nValueRet, 1111 * MIN_CHANGE); // we get the bigger coin
240
240
// but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0)
242
add_coin(0.4 * MIN_CHANGE);
243
add_coin(0.6 * MIN_CHANGE);
244
add_coin(0.8 * MIN_CHANGE);
242
add_coin(MIN_CHANGE * 4 / 10);
243
add_coin(MIN_CHANGE * 6 / 10);
244
add_coin(MIN_CHANGE * 8 / 10);
245
245
add_coin(1111 * MIN_CHANGE);
246
246
BOOST_CHECK( wallet.SelectCoinsMinConf(MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
247
247
BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE); // we should get the exact amount
250
250
// test avoiding small change
252
add_coin(0.05 * MIN_CHANGE);
253
add_coin(1 * MIN_CHANGE);
254
add_coin(100 * MIN_CHANGE);
252
add_coin(MIN_CHANGE * 5 / 100);
253
add_coin(MIN_CHANGE * 1);
254
add_coin(MIN_CHANGE * 100);
256
256
// trying to make 100.01 from these three coins
257
BOOST_CHECK( wallet.SelectCoinsMinConf(100.01 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
258
BOOST_CHECK_EQUAL(nValueRet, 101.05 * MIN_CHANGE); // we should get all coins
257
BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 10001 / 100, 1, 1, vCoins, setCoinsRet, nValueRet));
258
BOOST_CHECK_EQUAL(nValueRet, MIN_CHANGE * 10105 / 100); // we should get all coins
259
259
BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U);
261
261
// but if we try to make 99.9, we should take the bigger of the two small coins to avoid small change
262
BOOST_CHECK( wallet.SelectCoinsMinConf(99.9 * MIN_CHANGE, 1, 1, vCoins, setCoinsRet, nValueRet));
262
BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, 1, 1, vCoins, setCoinsRet, nValueRet));
263
263
BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE);
264
264
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
310
310
// add 75 cents in small change. not enough to make 90 cents,
311
311
// then try making 90 cents. there are multiple competing "smallest bigger" coins,
312
312
// one of which should be picked at random
313
add_coin( 5*CENT); add_coin(10*CENT); add_coin(15*CENT); add_coin(20*CENT); add_coin(25*CENT);
316
320
for (int i = 0; i < RANDOM_REPEATS; i++)
345
349
BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet));
346
350
BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN);
347
351
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U);
352
for (int i = 0; i < 100; i++)
354
for (int i = 0; i < 100; i++)
355
add_coin(1000 * COIN);
357
BOOST_CHECK(wallet.SelectCoinsMinConf(100001 * COIN, 1, 6, vCoins, setCoinsRet, nValueRet));
358
// We need all 100 larger coins and exactly one small coin.
359
// Superfluous small coins must be trimmed from the set:
360
BOOST_CHECK_EQUAL(nValueRet, 100010 * COIN);
361
BOOST_CHECK_EQUAL(setCoinsRet.size(), 101);
364
354
BOOST_AUTO_TEST_SUITE_END()