Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/test/wallet_tests.cpp
Show First 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | BOOST_AUTO_TEST_CASE(coin_selection_tests) { | ||||
LOCK(wallet.cs_wallet); | LOCK(wallet.cs_wallet); | ||||
// test multiple times to allow for differences in the shuffle order | // test multiple times to allow for differences in the shuffle order | ||||
for (int i = 0; i < RUN_TESTS; i++) { | for (int i = 0; i < RUN_TESTS; i++) { | ||||
empty_wallet(); | empty_wallet(); | ||||
// with an empty wallet we can't even pay one cent | // with an empty wallet we can't even pay one cent | ||||
BOOST_CHECK(!wallet.SelectCoinsMinConf(1 * CENT, 1, 6, 0, vCoins, | BOOST_CHECK(!wallet.SelectCoinsMinConf(1 * CENT.GetSatoshis(), 1, 6, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// add a new 1 cent coin | |||||
add_coin(1 * CENT, 4); // add a new 1 cent coin | add_coin(1 * CENT.GetSatoshis(), 4); | ||||
// with a new 1 cent coin, we still can't find a mature 1 cent | // with a new 1 cent coin, we still can't find a mature 1 cent | ||||
BOOST_CHECK(!wallet.SelectCoinsMinConf(1 * CENT, 1, 6, 0, vCoins, | BOOST_CHECK(!wallet.SelectCoinsMinConf(1 * CENT.GetSatoshis(), 1, 6, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// but we can find a new 1 cent | // but we can find a new 1 cent | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(1 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(1 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 1 * CENT.GetSatoshis()); | ||||
// add a mature 2 cent coin | |||||
add_coin(2 * CENT); // add a mature 2 cent coin | add_coin(2 * CENT.GetSatoshis()); | ||||
// we can't make 3 cents of mature coins | // we can't make 3 cents of mature coins | ||||
BOOST_CHECK(!wallet.SelectCoinsMinConf(3 * CENT, 1, 6, 0, vCoins, | BOOST_CHECK(!wallet.SelectCoinsMinConf(3 * CENT.GetSatoshis(), 1, 6, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// we can make 3 cents of new coins | // we can make 3 cents of new coins | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(3 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(3 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK_EQUAL(nValueRet, 3 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 3 * CENT.GetSatoshis()); | ||||
// add a mature 5 cent coin, | // add a mature 5 cent coin, | ||||
add_coin(5 * CENT); | add_coin(5 * CENT.GetSatoshis()); | ||||
// a new 10 cent coin sent from one of our own addresses | // a new 10 cent coin sent from one of our own addresses | ||||
add_coin(10 * CENT, 3, true); | add_coin(10 * CENT.GetSatoshis(), 3, true); | ||||
// and a mature 20 cent coin | // and a mature 20 cent coin | ||||
add_coin(20 * CENT); | add_coin(20 * CENT.GetSatoshis()); | ||||
// now we have new: 1+10=11 (of which 10 was self-sent), and mature: | // now we have new: 1+10=11 (of which 10 was self-sent), and mature: | ||||
// 2+5+20=27. total = 38 | // 2+5+20=27. total = 38 | ||||
// we can't make 38 cents only if we disallow new coins: | // we can't make 38 cents only if we disallow new coins: | ||||
BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 1, 6, 0, vCoins, | BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT.GetSatoshis(), 1, 6, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// we can't even make 37 cents if we don't allow new coins even if | // we can't even make 37 cents if we don't allow new coins even if | ||||
// they're from us | // they're from us | ||||
BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 6, 6, 0, vCoins, | BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT.GetSatoshis(), 6, 6, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// but we can make 37 cents if we accept new coins from ourself | // but we can make 37 cents if we accept new coins from ourself | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(37 * CENT, 1, 6, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(37 * CENT.GetSatoshis(), 1, 6, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK_EQUAL(nValueRet, 37 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 37 * CENT.GetSatoshis()); | ||||
// and we can make 38 cents if we accept all new coins | // and we can make 38 cents if we accept all new coins | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(38 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(38 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK_EQUAL(nValueRet, 38 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 38 * CENT.GetSatoshis()); | ||||
// try making 34 cents from 1,2,5,10,20 - we can't do it exactly | // try making 34 cents from 1,2,5,10,20 - we can't do it exactly | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(34 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(34 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// but 35 cents is closest | // but 35 cents is closest | ||||
BOOST_CHECK_EQUAL(nValueRet, 35 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 35 * CENT.GetSatoshis()); | ||||
// the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got | // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got | ||||
// included (but possible) | // included (but possible) | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); | ||||
// when we try making 7 cents, the smaller coins (1,2,5) are enough. We | // when we try making 7 cents, the smaller coins (1,2,5) are enough. We | ||||
// should see just 2+5 | // should see just 2+5 | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(7 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(7 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK_EQUAL(nValueRet, 7 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 7 * CENT.GetSatoshis()); | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); | ||||
// when we try making 8 cents, the smaller coins (1,2,5) are exactly | // when we try making 8 cents, the smaller coins (1,2,5) are exactly | ||||
// enough. | // enough. | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(8 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(8 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK(nValueRet == 8 * CENT); | BOOST_CHECK(nValueRet == 8 * CENT.GetSatoshis()); | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); | ||||
// when we try making 9 cents, no subset of smaller coins is enough, and | // when we try making 9 cents, no subset of smaller coins is enough, and | ||||
// we get the next bigger coin (10) | // we get the next bigger coin (10) | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(9 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(9 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK_EQUAL(nValueRet, 10 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 10 * CENT.GetSatoshis()); | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | ||||
// now clear out the wallet and start again to test choosing between | // now clear out the wallet and start again to test choosing between | ||||
// subsets of smaller coins and the next biggest coin | // subsets of smaller coins and the next biggest coin | ||||
empty_wallet(); | empty_wallet(); | ||||
add_coin(6 * CENT); | add_coin(6 * CENT.GetSatoshis()); | ||||
add_coin(7 * CENT); | add_coin(7 * CENT.GetSatoshis()); | ||||
add_coin(8 * CENT); | add_coin(8 * CENT.GetSatoshis()); | ||||
add_coin(20 * CENT); | add_coin(20 * CENT.GetSatoshis()); | ||||
// now we have 6+7+8+20+30 = 71 cents total | // now we have 6+7+8+20+30 = 71 cents total | ||||
add_coin(30 * CENT); | add_coin(30 * CENT.GetSatoshis()); | ||||
// check that we have 71 and not 72 | // check that we have 71 and not 72 | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(71 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(71 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// now try making 16 cents. the best smaller coins can do is 6+7+8 = | // 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 | // 21; not as good at the next biggest coin, 20 | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// we should get 20 in one coin | // we should get 20 in one coin | ||||
BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 20 * CENT.GetSatoshis()); | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | ||||
add_coin(5 * CENT); // now we have 5+6+7+8+20+30 = 75 cents total | // now we have 5+6+7+8+20+30 = 75 cents total | ||||
add_coin(5 * CENT.GetSatoshis()); | |||||
// now if we try making 16 cents again, the smaller coins can make 5+6+7 | // 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 | // = 18 cents, better than the next biggest coin, 20 | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// we should get 18 in 3 coins | // we should get 18 in 3 coins | ||||
BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 18 * CENT.GetSatoshis()); | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); | ||||
add_coin(18 * CENT); // now we have 5+6+7+8+18+20+30 | // now we have 5+6+7+8+18+20+30 | ||||
add_coin(18 * CENT.GetSatoshis()); | |||||
// and now if we try making 16 cents again, the smaller coins can make | // 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 | // 5+6+7 = 18 cents, the same as the next biggest coin, 18 | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// we should get 18 in 1 coin | // we should get 18 in 1 coin | ||||
BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 18 * CENT.GetSatoshis()); | ||||
// because in the event of a tie, the biggest coin wins | // because in the event of a tie, the biggest coin wins | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | ||||
// now try making 11 cents. we should get 5+6 | // now try making 11 cents. we should get 5+6 | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(11 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(11 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK_EQUAL(nValueRet, 11 * CENT); | BOOST_CHECK_EQUAL(nValueRet, 11 * CENT.GetSatoshis()); | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); | ||||
// check that the smallest bigger coin is used | // check that the smallest bigger coin is used | ||||
add_coin(1 * COIN); | add_coin(1 * COIN.GetSatoshis()); | ||||
add_coin(2 * COIN); | add_coin(2 * COIN.GetSatoshis()); | ||||
add_coin(3 * COIN); | add_coin(3 * COIN.GetSatoshis()); | ||||
// now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents | // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents | ||||
add_coin(4 * COIN); | add_coin(4 * COIN.GetSatoshis()); | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(95 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(95 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// we should get 1 BCC in 1 coin | // we should get 1 BCC in 1 coin | ||||
BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); | BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(195 * CENT, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(195 * CENT.GetSatoshis(), 1, 1, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
// we should get 2 BCC in 1 coin | // we should get 2 BCC in 1 coin | ||||
BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); | BOOST_CHECK_EQUAL(nValueRet, 2 * COIN.GetSatoshis()); | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | ||||
// empty the wallet and start again, now with fractions of a cent, to | // empty the wallet and start again, now with fractions of a cent, to | ||||
// test small change avoidance | // test small change avoidance | ||||
empty_wallet(); | empty_wallet(); | ||||
add_coin(MIN_CHANGE * 1 / 10); | add_coin(MIN_CHANGE * 1 / 10); | ||||
add_coin(MIN_CHANGE * 2 / 10); | add_coin(MIN_CHANGE * 2 / 10); | ||||
Show All 28 Lines | for (int i = 0; i < RUN_TESTS; i++) { | ||||
BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); | BOOST_CHECK_EQUAL(nValueRet, 1 * MIN_CHANGE); | ||||
// run the 'mtgox' test (see | // run the 'mtgox' test (see | ||||
// http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) | // http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) | ||||
// they tried to consolidate 10 50k coins into one 500k coin, and ended | // they tried to consolidate 10 50k coins into one 500k coin, and ended | ||||
// up with 50k in change | // up with 50k in change | ||||
empty_wallet(); | empty_wallet(); | ||||
for (int j = 0; j < 20; j++) { | for (int j = 0; j < 20; j++) { | ||||
add_coin(50000 * COIN); | add_coin(50000 * COIN.GetSatoshis()); | ||||
} | } | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(500000 * COIN, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(500000 * COIN.GetSatoshis(), 1, 1, | ||||
setCoinsRet, nValueRet)); | 0, vCoins, setCoinsRet, | ||||
nValueRet)); | |||||
// we should get the exact amount | // we should get the exact amount | ||||
BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); | BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN.GetSatoshis()); | ||||
// in ten coins | // in ten coins | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); | ||||
// if there's not enough in the smaller coins to make at least 1 * | // if there's not enough in the smaller coins to make at least 1 * | ||||
// MIN_CHANGE change (0.5+0.6+0.7 < 1.0+1.0), we need to try finding an | // MIN_CHANGE change (0.5+0.6+0.7 < 1.0+1.0), we need to try finding an | ||||
// exact subset anyway | // exact subset anyway | ||||
// sometimes it will fail, and so we use the next biggest coin: | // sometimes it will fail, and so we use the next biggest coin: | ||||
Show All 38 Lines | for (int i = 0; i < RUN_TESTS; i++) { | ||||
// but if we try to make 99.9, we should take the bigger of the two | // but if we try to make 99.9, we should take the bigger of the two | ||||
// small coins to avoid small change | // small coins to avoid small change | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, 1, 1, 0, | BOOST_CHECK(wallet.SelectCoinsMinConf(MIN_CHANGE * 9990 / 100, 1, 1, 0, | ||||
vCoins, setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); | BOOST_CHECK_EQUAL(nValueRet, 101 * MIN_CHANGE); | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); | ||||
// test with many inputs | // test with many inputs | ||||
for (CAmount amt = 1500; amt < COIN; amt *= 10) { | for (CAmount amt = 1500; amt < COIN.GetSatoshis(); amt *= 10) { | ||||
empty_wallet(); | empty_wallet(); | ||||
// Create 676 inputs (= (old MAX_STANDARD_TX_SIZE == 100000) / 148 | // Create 676 inputs (= (old MAX_STANDARD_TX_SIZE == 100000) / 148 | ||||
// bytes per input) | // bytes per input) | ||||
for (uint16_t j = 0; j < 676; j++) { | for (uint16_t j = 0; j < 676; j++) { | ||||
add_coin(amt); | add_coin(amt); | ||||
} | } | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(2000, 1, 1, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(2000, 1, 1, 0, vCoins, | ||||
setCoinsRet, nValueRet)); | setCoinsRet, nValueRet)); | ||||
Show All 9 Lines | for (int i = 0; i < RUN_TESTS; i++) { | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); | ||||
} | } | ||||
} | } | ||||
// test randomness | // test randomness | ||||
{ | { | ||||
empty_wallet(); | empty_wallet(); | ||||
for (int i2 = 0; i2 < 100; i2++) { | for (int i2 = 0; i2 < 100; i2++) { | ||||
add_coin(COIN); | add_coin(COIN.GetSatoshis()); | ||||
} | } | ||||
// picking 50 from 100 coins doesn't depend on the shuffle, but does | // picking 50 from 100 coins doesn't depend on the shuffle, but does | ||||
// depend on randomness in the stochastic approximation code | // depend on randomness in the stochastic approximation code | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN.GetSatoshis(), 1, 6, | ||||
setCoinsRet, nValueRet)); | 0, vCoins, setCoinsRet, | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, 0, vCoins, | nValueRet)); | ||||
setCoinsRet2, nValueRet)); | BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN.GetSatoshis(), 1, 6, | ||||
0, vCoins, setCoinsRet2, | |||||
nValueRet)); | |||||
BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2)); | BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2)); | ||||
int fails = 0; | int fails = 0; | ||||
for (int j = 0; j < RANDOM_REPEATS; j++) { | for (int j = 0; j < RANDOM_REPEATS; j++) { | ||||
// selecting 1 from 100 identical coins depends on the shuffle; | // selecting 1 from 100 identical coins depends on the shuffle; | ||||
// this test will fail 1% of the time run the test | // this test will fail 1% of the time run the test | ||||
// RANDOM_REPEATS times and only complain if all of them fail | // RANDOM_REPEATS times and only complain if all of them fail | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(COIN.GetSatoshis(), 1, 6, | ||||
setCoinsRet, nValueRet)); | 0, vCoins, setCoinsRet, | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, 0, vCoins, | nValueRet)); | ||||
setCoinsRet2, nValueRet)); | BOOST_CHECK(wallet.SelectCoinsMinConf(COIN.GetSatoshis(), 1, 6, | ||||
0, vCoins, setCoinsRet2, | |||||
nValueRet)); | |||||
if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; | if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; | ||||
} | } | ||||
BOOST_CHECK_NE(fails, RANDOM_REPEATS); | BOOST_CHECK_NE(fails, RANDOM_REPEATS); | ||||
// add 75 cents in small change. not enough to make 90 cents, then | // add 75 cents in small change. not enough to make 90 cents, then | ||||
// try making 90 cents. there are multiple competing "smallest | // try making 90 cents. there are multiple competing "smallest | ||||
// bigger" coins, one of which should be picked at random | // bigger" coins, one of which should be picked at random | ||||
add_coin(5 * CENT); | add_coin(5 * CENT.GetSatoshis()); | ||||
add_coin(10 * CENT); | add_coin(10 * CENT.GetSatoshis()); | ||||
add_coin(15 * CENT); | add_coin(15 * CENT.GetSatoshis()); | ||||
add_coin(20 * CENT); | add_coin(20 * CENT.GetSatoshis()); | ||||
add_coin(25 * CENT); | add_coin(25 * CENT.GetSatoshis()); | ||||
fails = 0; | fails = 0; | ||||
for (int j = 0; j < RANDOM_REPEATS; j++) { | for (int j = 0; j < RANDOM_REPEATS; j++) { | ||||
// selecting 1 from 100 identical coins depends on the shuffle; | // selecting 1 from 100 identical coins depends on the shuffle; | ||||
// this test will fail 1% of the time run the test | // this test will fail 1% of the time run the test | ||||
// RANDOM_REPEATS times and only complain if all of them fail | // RANDOM_REPEATS times and only complain if all of them fail | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf( | BOOST_CHECK(wallet.SelectCoinsMinConf(90 * CENT.GetSatoshis(), | ||||
90 * CENT, 1, 6, 0, vCoins, setCoinsRet, nValueRet)); | 1, 6, 0, vCoins, | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf( | setCoinsRet, nValueRet)); | ||||
90 * CENT, 1, 6, 0, vCoins, setCoinsRet2, nValueRet)); | BOOST_CHECK(wallet.SelectCoinsMinConf(90 * CENT.GetSatoshis(), | ||||
1, 6, 0, vCoins, | |||||
setCoinsRet2, nValueRet)); | |||||
if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; | if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; | ||||
} | } | ||||
BOOST_CHECK_NE(fails, RANDOM_REPEATS); | BOOST_CHECK_NE(fails, RANDOM_REPEATS); | ||||
} | } | ||||
} | } | ||||
empty_wallet(); | empty_wallet(); | ||||
} | } | ||||
BOOST_AUTO_TEST_CASE(ApproximateBestSubset) { | BOOST_AUTO_TEST_CASE(ApproximateBestSubset) { | ||||
CoinSet setCoinsRet; | CoinSet setCoinsRet; | ||||
CAmount nValueRet; | CAmount nValueRet; | ||||
LOCK(wallet.cs_wallet); | LOCK(wallet.cs_wallet); | ||||
empty_wallet(); | empty_wallet(); | ||||
// Test vValue sort order | // Test vValue sort order | ||||
for (int i = 0; i < 1000; i++) { | for (int i = 0; i < 1000; i++) { | ||||
add_coin(1000 * COIN); | add_coin(1000 * COIN.GetSatoshis()); | ||||
} | } | ||||
add_coin(3 * COIN); | add_coin(3 * COIN.GetSatoshis()); | ||||
BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, 0, vCoins, | BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN.GetSatoshis(), 1, 6, 0, | ||||
setCoinsRet, nValueRet)); | vCoins, setCoinsRet, nValueRet)); | ||||
BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); | BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN.GetSatoshis()); | ||||
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); | BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); | ||||
empty_wallet(); | empty_wallet(); | ||||
} | } | ||||
BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) { | BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
// Cap last block file size, and mine new block in a new block file. | // Cap last block file size, and mine new block in a new block file. | ||||
CBlockIndex *oldTip = chainActive.Tip(); | CBlockIndex *oldTip = chainActive.Tip(); | ||||
GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; | GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; | ||||
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); | ||||
CBlockIndex *newTip = chainActive.Tip(); | CBlockIndex *newTip = chainActive.Tip(); | ||||
// Verify ScanForWalletTransactions picks up transactions in both the old | // Verify ScanForWalletTransactions picks up transactions in both the old | ||||
// and new block files. | // and new block files. | ||||
{ | { | ||||
CWallet wallet; | CWallet wallet; | ||||
LOCK(wallet.cs_wallet); | LOCK(wallet.cs_wallet); | ||||
wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); | wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); | ||||
BOOST_CHECK_EQUAL(oldTip, wallet.ScanForWalletTransactions(oldTip)); | BOOST_CHECK_EQUAL(oldTip, wallet.ScanForWalletTransactions(oldTip)); | ||||
BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 100 * COIN); | BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), | ||||
100 * COIN.GetSatoshis()); | |||||
} | } | ||||
// Prune the older block file. | // Prune the older block file. | ||||
PruneOneBlockFile(oldTip->GetBlockPos().nFile); | PruneOneBlockFile(oldTip->GetBlockPos().nFile); | ||||
UnlinkPrunedFiles({oldTip->GetBlockPos().nFile}); | UnlinkPrunedFiles({oldTip->GetBlockPos().nFile}); | ||||
// Verify ScanForWalletTransactions only picks transactions in the new block | // Verify ScanForWalletTransactions only picks transactions in the new block | ||||
// file. | // file. | ||||
{ | { | ||||
CWallet wallet; | CWallet wallet; | ||||
LOCK(wallet.cs_wallet); | LOCK(wallet.cs_wallet); | ||||
wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); | wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); | ||||
BOOST_CHECK_EQUAL(newTip, wallet.ScanForWalletTransactions(oldTip)); | BOOST_CHECK_EQUAL(newTip, wallet.ScanForWalletTransactions(oldTip)); | ||||
BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN); | BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN.GetSatoshis()); | ||||
} | } | ||||
// Verify importmulti RPC returns failure for a key whose creation time is | // Verify importmulti RPC returns failure for a key whose creation time is | ||||
// before the missing block, and success for a key whose creation time is | // before the missing block, and success for a key whose creation time is | ||||
// after. | // after. | ||||
{ | { | ||||
CWallet wallet; | CWallet wallet; | ||||
CWallet *backup = ::pwalletMain; | CWallet *backup = ::pwalletMain; | ||||
Show All 35 Lines |