|
|
@ -9,8 +9,14 @@ |
|
|
|
// enables tests which currently fail, due to code which tries too hard to avoid sub-cent change
|
|
|
|
// enables tests which currently fail, due to code which tries too hard to avoid sub-cent change
|
|
|
|
// #define STRICT
|
|
|
|
// #define STRICT
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// some tests fail 1% of the time due to bad luck.
|
|
|
|
|
|
|
|
// we repeat those tests this many times and only complain if all iterations of the test fail
|
|
|
|
|
|
|
|
#define RANDOM_REPEATS 5 |
|
|
|
|
|
|
|
|
|
|
|
using namespace std; |
|
|
|
using namespace std; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef set<pair<const CWalletTx*,unsigned int> > CoinSet; |
|
|
|
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_SUITE(wallet_tests) |
|
|
|
BOOST_AUTO_TEST_SUITE(wallet_tests) |
|
|
|
|
|
|
|
|
|
|
|
static CWallet wallet; |
|
|
|
static CWallet wallet; |
|
|
@ -44,9 +50,15 @@ static void empty_wallet(void) |
|
|
|
vCoins.clear(); |
|
|
|
vCoins.clear(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool equal_sets(CoinSet a, CoinSet b) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
pair<CoinSet::iterator, CoinSet::iterator> ret = mismatch(a.begin(), a.end(), b.begin()); |
|
|
|
|
|
|
|
return ret.first == a.end() && ret.second == b.end(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(coin_selection_tests) |
|
|
|
BOOST_AUTO_TEST_CASE(coin_selection_tests) |
|
|
|
{ |
|
|
|
{ |
|
|
|
static set<pair<const CWalletTx*,unsigned int> > setCoinsRet; |
|
|
|
static CoinSet setCoinsRet, setCoinsRet2; |
|
|
|
static int64 nValueRet; |
|
|
|
static int64 nValueRet; |
|
|
|
|
|
|
|
|
|
|
|
// test multiple times to allow for differences in the shuffle order
|
|
|
|
// test multiple times to allow for differences in the shuffle order
|
|
|
@ -250,6 +262,64 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) |
|
|
|
BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // but since value of smaller coins < target+cent, we get the bigger coin again
|
|
|
|
BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // but since value of smaller coins < target+cent, we get the bigger coin again
|
|
|
|
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); |
|
|
|
BOOST_CHECK_EQUAL(setCoinsRet.size(), 1); |
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// test avoiding sub-cent change
|
|
|
|
|
|
|
|
empty_wallet(); |
|
|
|
|
|
|
|
add_coin(0.0005 * COIN); |
|
|
|
|
|
|
|
add_coin(0.01 * COIN); |
|
|
|
|
|
|
|
add_coin(1 * 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
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(setCoinsRet.size(), 3); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(setCoinsRet.size(), 2); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// test randomness
|
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
empty_wallet(); |
|
|
|
|
|
|
|
for (int i2 = 0; i2 < 100; i2++) |
|
|
|
|
|
|
|
add_coin(COIN); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// picking 50 from 100 coins doesn't depend on the shuffle,
|
|
|
|
|
|
|
|
// but does depend on randomness in the stochastic approximation code
|
|
|
|
|
|
|
|
BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); |
|
|
|
|
|
|
|
BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); |
|
|
|
|
|
|
|
BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int fails = 0; |
|
|
|
|
|
|
|
for (int i = 0; i < RANDOM_REPEATS; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time
|
|
|
|
|
|
|
|
// run the test RANDOM_REPEATS times and only complain if all of them fail
|
|
|
|
|
|
|
|
BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet , nValueRet)); |
|
|
|
|
|
|
|
BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, vCoins, setCoinsRet2, nValueRet)); |
|
|
|
|
|
|
|
if (equal_sets(setCoinsRet, setCoinsRet2)) |
|
|
|
|
|
|
|
fails++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
BOOST_CHECK_NE(fails, RANDOM_REPEATS); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// add 75 cents in small change. not enough to make 90 cents,
|
|
|
|
|
|
|
|
// then try making 90 cents. there are multiple competing "smallest bigger" coins,
|
|
|
|
|
|
|
|
// one of which should be picked at random
|
|
|
|
|
|
|
|
add_coin( 5*CENT); add_coin(10*CENT); add_coin(15*CENT); add_coin(20*CENT); add_coin(25*CENT); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fails = 0; |
|
|
|
|
|
|
|
for (int i = 0; i < RANDOM_REPEATS; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// selecting 1 from 100 identical coins depends on the shuffle; this test will fail 1% of the time
|
|
|
|
|
|
|
|
// run the test RANDOM_REPEATS times and only complain if all of them fail
|
|
|
|
|
|
|
|
BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet , nValueRet)); |
|
|
|
|
|
|
|
BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, 1, 6, vCoins, setCoinsRet2, nValueRet)); |
|
|
|
|
|
|
|
if (equal_sets(setCoinsRet, setCoinsRet2)) |
|
|
|
|
|
|
|
fails++; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
BOOST_CHECK_NE(fails, RANDOM_REPEATS); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|