From 7eedaefa9c93bcb814472f5b88594b85f81b9c41 Mon Sep 17 00:00:00 2001 From: "James C. Owens" Date: Sun, 18 Feb 2024 12:23:25 -0500 Subject: [PATCH 1/2] Add operator methods to Allocation class This eliminates the requirement to constantly static_cast back to the Allocation class after doing arithmetic operations with Allocations. --- src/gridcoin/sidestake.cpp | 148 ++++++++++++++++++++++++++ src/gridcoin/sidestake.h | 46 ++++++++ src/miner.cpp | 6 +- src/test/gridcoin/sidestake_tests.cpp | 2 +- src/validation.cpp | 4 +- 5 files changed, 200 insertions(+), 6 deletions(-) diff --git a/src/gridcoin/sidestake.cpp b/src/gridcoin/sidestake.cpp index adc324b548..f96bd840db 100644 --- a/src/gridcoin/sidestake.cpp +++ b/src/gridcoin/sidestake.cpp @@ -48,6 +48,14 @@ Allocation::Allocation(const Fraction& f) : Fraction(f) {} +Allocation::Allocation(const int64_t& numerator, const int64_t& denominator) + : Fraction(numerator, denominator) +{} + +Allocation::Allocation(const int64_t& numerator, const int64_t& denominator, const bool& simplify) + : Fraction(numerator, denominator, simplify) +{} + CAmount Allocation::ToCAmount() const { return GetNumerator() / GetDenominator(); @@ -58,6 +66,146 @@ double Allocation::ToPercent() const return ToDouble() * 100.0; } +Allocation Allocation::operator+(const Allocation& rhs) const +{ + return static_cast(Fraction::operator+(rhs)); +} + +Allocation Allocation::operator+(const int64_t& rhs) const +{ + return static_cast(Fraction::operator+(rhs)); +} + +Allocation Allocation::operator-(const Allocation& rhs) const +{ + return static_cast(Fraction::operator-(rhs)); +} + +Allocation Allocation::operator-(const int64_t& rhs) const +{ + return static_cast(Fraction::operator-(rhs)); +} + +Allocation Allocation::operator*(const Allocation& rhs) const +{ + return static_cast(Fraction::operator*(rhs)); +} + +Allocation Allocation::operator*(const int64_t& rhs) const +{ + return static_cast(Fraction::operator*(rhs)); +} + +Allocation Allocation::operator/(const Allocation& rhs) const +{ + return static_cast(Fraction::operator/(rhs)); +} + +Allocation Allocation::operator/(const int64_t& rhs) const +{ + return static_cast(Fraction::operator/(rhs)); +} + +Allocation Allocation::operator+=(const Allocation& rhs) +{ + return static_cast(Fraction::operator+=(rhs)); +} + +Allocation Allocation::operator+=(const int64_t& rhs) +{ + return static_cast(Fraction::operator+=(rhs)); +} + +Allocation Allocation::operator-=(const Allocation& rhs) +{ + return static_cast(Fraction::operator-=(rhs)); +} + +Allocation Allocation::operator-=(const int64_t& rhs) +{ + return static_cast(Fraction::operator-=(rhs)); +} + +Allocation Allocation::operator*=(const Allocation& rhs) +{ + return static_cast(Fraction::operator*=(rhs)); +} + +Allocation Allocation::operator*=(const int64_t& rhs) +{ + return static_cast(Fraction::operator*=(rhs)); +} + +Allocation Allocation::operator/=(const Allocation& rhs) +{ + return static_cast(Fraction::operator/=(rhs)); +} + +Allocation Allocation::operator/=(const int64_t& rhs) +{ + return static_cast(Fraction::operator/=(rhs)); +} + +bool Allocation::operator==(const Allocation& rhs) const +{ + return Fraction::operator==(rhs); +} + +bool Allocation::operator!=(const Allocation& rhs) const +{ + return Fraction::operator!=(rhs); +} + +bool Allocation::operator<=(const Allocation& rhs) const +{ + return Fraction::operator<=(rhs); +} + +bool Allocation::operator>=(const Allocation& rhs) const +{ + return Fraction::operator>=(rhs); +} + +bool Allocation::operator<(const Allocation& rhs) const +{ + return Fraction::operator<(rhs); +} + +bool Allocation::operator>(const Allocation& rhs) const +{ + return Fraction::operator>(rhs); +} + +bool Allocation::operator==(const int64_t& rhs) const +{ + return Fraction::operator==(rhs); +} + +bool Allocation::operator!=(const int64_t& rhs) const +{ + return Fraction::operator!=(rhs); +} + +bool Allocation::operator<=(const int64_t& rhs) const +{ + return Fraction::operator<=(rhs); +} + +bool Allocation::operator>=(const int64_t& rhs) const +{ + return Fraction::operator>=(rhs); +} + +bool Allocation::operator<(const int64_t& rhs) const +{ + return Fraction::operator<(rhs); +} + +bool Allocation::operator>(const int64_t& rhs) const +{ + return Fraction::operator>(rhs); +} + // ----------------------------------------------------------------------------- // Class: LocalSideStake // ----------------------------------------------------------------------------- diff --git a/src/gridcoin/sidestake.h b/src/gridcoin/sidestake.h index 6b001e412d..42613e938c 100644 --- a/src/gridcoin/sidestake.h +++ b/src/gridcoin/sidestake.h @@ -43,6 +43,23 @@ class Allocation : public Fraction //! Allocation(const Fraction& f); + //! + //! \brief Initialize an allocation directly from specifying a numerator and denominator + //! \param numerator + //! \param denominator + //! + Allocation(const int64_t& numerator, const int64_t& denominator); + + //! + //! \brief Initialize an allocation directly from specifying a numerator and denominator, specifying the simplification + //! directive. + //! + //! \param numerator + //! \param denominator + //! \param simplify + //! + Allocation(const int64_t& numerator, const int64_t& denominator, const bool& simplify); + //! //! \brief Allocations extend the Fraction class and can also represent the result of the allocation constructed fraction //! and the result of the multiplication of that fraction times the reward, which is in CAmount (i.e. int64_t). @@ -57,6 +74,35 @@ class Allocation : public Fraction //! \return double percent representation of the allocation fraction. //! double ToPercent() const; + + Allocation operator+(const Allocation& rhs) const; + Allocation operator+(const int64_t& rhs) const; + Allocation operator-(const Allocation& rhs) const; + Allocation operator-(const int64_t& rhs) const; + Allocation operator*(const Allocation& rhs) const; + Allocation operator*(const int64_t& rhs) const; + Allocation operator/(const Allocation& rhs) const; + Allocation operator/(const int64_t& rhs) const; + Allocation operator+=(const Allocation& rhs); + Allocation operator+=(const int64_t& rhs); + Allocation operator-=(const Allocation& rhs); + Allocation operator-=(const int64_t& rhs); + Allocation operator*=(const Allocation& rhs); + Allocation operator*=(const int64_t& rhs); + Allocation operator/=(const Allocation& rhs); + Allocation operator/=(const int64_t& rhs); + bool operator==(const Allocation& rhs) const; + bool operator!=(const Allocation& rhs) const; + bool operator<=(const Allocation& rhs) const; + bool operator>=(const Allocation& rhs) const; + bool operator<(const Allocation& rhs) const; + bool operator>(const Allocation& rhs) const; + bool operator==(const int64_t& rhs) const; + bool operator!=(const int64_t& rhs) const; + bool operator<=(const int64_t& rhs) const; + bool operator>=(const int64_t& rhs) const; + bool operator<(const int64_t& rhs) const; + bool operator>(const int64_t& rhs) const; }; //! diff --git a/src/miner.cpp b/src/miner.cpp index 184d586b2f..bc0ef2deb7 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -968,7 +968,7 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake if (allocation * nReward < CENT) { LogPrintf("WARN: SplitCoinStakeOutput: distribution %f too small to address %s.", - CoinToDouble(static_cast(allocation * nReward).ToCAmount()), + CoinToDouble((allocation * nReward).ToCAmount()), address.ToString() ); continue; @@ -998,7 +998,7 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake // For allocations ending less than 100% assign using sidestake allocation. if (SumAllocation + allocation < 1) - nSideStake = static_cast(allocation * nReward).ToCAmount(); + nSideStake = (allocation * nReward).ToCAmount(); // We need to handle the final sidestake differently in the case it brings the total allocation up to 100%, // because testing showed in corner cases the output return to the staking address could be off by one Halford. else if (SumAllocation + allocation == 1) @@ -1010,7 +1010,7 @@ void SplitCoinStakeOutput(CBlock &blocknew, int64_t &nReward, bool &fEnableStake LogPrintf("SplitCoinStakeOutput: create sidestake UTXO %i value %f to address %s", nOutputsUsed, - CoinToDouble(static_cast(allocation * nReward).ToCAmount()), + CoinToDouble((allocation * nReward).ToCAmount()), address.ToString() ); SumAllocation += allocation; diff --git a/src/test/gridcoin/sidestake_tests.cpp b/src/test/gridcoin/sidestake_tests.cpp index 590d2a43f9..c0caa711f5 100644 --- a/src/test/gridcoin/sidestake_tests.cpp +++ b/src/test/gridcoin/sidestake_tests.cpp @@ -140,7 +140,7 @@ BOOST_AUTO_TEST_CASE(sidestake_Allocation_multiplication_and_derivation_of_alloc CAmount max_accrual = 16384 * COIN; - CAmount actual_output = static_cast(allocation * max_accrual).ToCAmount(); + CAmount actual_output = (allocation * max_accrual).ToCAmount(); BOOST_CHECK_EQUAL(actual_output, int64_t {1638236160000}); } diff --git a/src/validation.cpp b/src/validation.cpp index 53268c936a..f60a215ec1 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -891,8 +891,8 @@ class ClaimValidator if (!mandatory_sidestake.empty()) { CAmount actual_output = coinstake.vout[i].nValue; - CAmount required_output = static_cast(mandatory_sidestake[0]->GetAllocation() - * total_owed_to_staker).ToCAmount(); + CAmount required_output = (mandatory_sidestake[0]->GetAllocation() + * total_owed_to_staker).ToCAmount(); if (actual_output >= required_output) { From 4c14a714156beec13c8f937d233fbc62955099aa Mon Sep 17 00:00:00 2001 From: "James C. Owens" Date: Sun, 18 Feb 2024 12:40:17 -0500 Subject: [PATCH 2/2] Cleanup wallet_tests.cpp and remove the rest of double usage This changes out the rest of the double usage to use the Allocation class in a second attempt to fix the i386 linux compile test errors on GCC 13 with OpenSUSE. --- src/test/wallet_tests.cpp | 144 +++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/src/test/wallet_tests.cpp b/src/test/wallet_tests.cpp index 0b674952d2..c5e390e531 100755 --- a/src/test/wallet_tests.cpp +++ b/src/test/wallet_tests.cpp @@ -67,29 +67,29 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) empty_wallet(); // with an empty wallet we can't even pay one cent - BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, spendTime, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(CENT, spendTime, 1, 6, vCoins, setCoinsRet, nValueRet)); - add_coin(1*CENT, 4); // add a new 1 cent coin + add_coin(CENT, 4); // add a new 1 cent coin // with a new 1 cent coin, we still can't find a mature 1 cent - BOOST_CHECK(!wallet.SelectCoinsMinConf( 1 * CENT, spendTime, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(CENT, spendTime, 1, 6, vCoins, setCoinsRet, nValueRet)); // but we can find a new 1 cent - BOOST_CHECK( wallet.SelectCoinsMinConf( 1 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, CENT); - add_coin(2*CENT); // add a mature 2 cent coin + add_coin(2 * CENT); // add a mature 2 cent coin // we can't make 3 cents of mature coins - BOOST_CHECK(!wallet.SelectCoinsMinConf( 3 * CENT, spendTime, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(3 * CENT, spendTime, 1, 6, vCoins, setCoinsRet, nValueRet)); // we can make 3 cents of new coins - BOOST_CHECK( wallet.SelectCoinsMinConf( 3 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(3 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 3 * CENT); - add_coin(5*CENT); // add a mature 5 cent coin, - add_coin(10*CENT, 3, true); // a new 10 cent coin sent from one of our own addresses - add_coin(20*CENT); // and a mature 20 cent coin + add_coin(5 * CENT); // add a mature 5 cent coin, + add_coin(10 * CENT, 3, true); // a new 10 cent coin sent from one of our own addresses + add_coin(20 * CENT); // and a mature 20 cent coin // now we have new: 1+10=11 (of which 10 was self-sent), and mature: 2+5+20=27. total = 38 @@ -98,109 +98,109 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // we can't even make 37 cents if we don't allow new coins even if they're from us BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, spendTime, 6, 6, vCoins, setCoinsRet, nValueRet)); // but we can make 37 cents if we accept new coins from ourself - BOOST_CHECK( wallet.SelectCoinsMinConf(37 * CENT, spendTime, 1, 6, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(37 * CENT, spendTime, 1, 6, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 37 * CENT); // and we can make 38 cents if we accept all new coins - BOOST_CHECK( wallet.SelectCoinsMinConf(38 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(38 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 38 * CENT); // try making 34 cents from 1,2,5,10,20 - we can't do it exactly - BOOST_CHECK( wallet.SelectCoinsMinConf(34 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_GT(nValueRet, 34 * CENT); // but should get more than 34 cents - BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 3); // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) + BOOST_CHECK(wallet.SelectCoinsMinConf(34 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_GT(nValueRet, 34 * CENT); // but should get more than 34 cents + // the best should be 20+10+5. it's incredibly unlikely the 1 or 2 got included (but possible) + BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 3); // when we try making 7 cents, the smaller coins (1,2,5) are enough. We should see just 2+5 - BOOST_CHECK( wallet.SelectCoinsMinConf( 7 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(7 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 7 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 2); // when we try making 8 cents, the smaller coins (1,2,5) are exactly enough. - BOOST_CHECK( wallet.SelectCoinsMinConf( 8 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(8 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK(nValueRet == 8 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 3); // when we try making 9 cents, no subset of smaller coins is enough, and we get the next bigger coin (10) - BOOST_CHECK( wallet.SelectCoinsMinConf( 9 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(9 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 10 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 1); // 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 * 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 // check that we have 71 and not 72 - BOOST_CHECK( wallet.SelectCoinsMinConf(71 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(71 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, spendTime, 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, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 20 * CENT); // we should get 20 in one coin BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 1); - add_coin( 5*CENT); // now we have 5+6+7+8+20+30 = 75 cents total + add_coin(5 * CENT); // now we have 5+6+7+8+20+30 = 75 cents 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, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 3 coins BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 3); - add_coin( 18*CENT); // now we have 5+6+7+8+18+20+30 + add_coin(18 * CENT); // 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, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 18 * CENT); // we should get 18 in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 1); // 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, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(11 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 11 * CENT); BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 2); // 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, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + 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, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); // we should get 1 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 1); - BOOST_CHECK( wallet.SelectCoinsMinConf(195 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(195 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 2 * COIN); // we should get 2 BTC in 1 coin BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 1); // empty the wallet and start again, now with fractions of a cent, to test sub-cent change avoidance empty_wallet(); - add_coin(0.1*CENT); - add_coin(0.2*CENT); - add_coin(0.3*CENT); - add_coin(0.4*CENT); - add_coin(0.5*CENT); + add_coin((GRC::Allocation(1, 10, true) * CENT).ToCAmount()); + add_coin((GRC::Allocation(2, 10, true) * CENT).ToCAmount()); + add_coin((GRC::Allocation(3, 10, true) * CENT).ToCAmount()); + add_coin((GRC::Allocation(4, 10, true) * CENT).ToCAmount()); + add_coin((GRC::Allocation(5, 10, true) * CENT).ToCAmount()); // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 = 1.5 cents // we'll get sub-cent change whatever happens, so can expect 1.0 exactly - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, CENT); // but if we add a bigger coin, making it possible to avoid sub-cent change, things change: - add_coin(1111*CENT); + add_coin(1111 * CENT); // try making 1 cent from 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 1111 = 1112.5 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount - + BOOST_CHECK(wallet.SelectCoinsMinConf(CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, CENT); // we should get the exact amount // if we add more sub-cent coins: - add_coin(0.6*CENT); - add_coin(0.7*CENT); + add_coin((GRC::Allocation(6, 10, true) * CENT).ToCAmount()); + add_coin((GRC::Allocation(7, 10, true) * CENT).ToCAmount()); // and try again to make 1.0 cents, we can still make 1.0 cents - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + BOOST_CHECK(wallet.SelectCoinsMinConf(CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, CENT); // we should get the exact amount // run the 'mtgox' test (see http://blockexplorer.com/tx/29a3efd3ef04f9153d47a990bd7b048a4b2d213daaa5fb8ed670fb85f13bdbcf) // they tried to consolidate 10 50k coins into one 500k coin, and ended up with 50k in change @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) for (int i = 0; i < 20; i++) add_coin(50000 * COIN); - BOOST_CHECK( wallet.SelectCoinsMinConf(500000 * COIN, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(500000 * COIN, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 10); // in ten coins @@ -217,43 +217,43 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // sometimes it will fail, and so we use the next biggest coin: empty_wallet(); - add_coin(0.5 * CENT); - add_coin(0.6 * CENT); - add_coin(0.7 * CENT); + add_coin((GRC::Allocation(5, 10, true) * CENT).ToCAmount()); + add_coin((GRC::Allocation(6, 10, true) * CENT).ToCAmount()); + add_coin((GRC::Allocation(7, 10, true) * CENT).ToCAmount()); add_coin(1111 * CENT); - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); BOOST_CHECK_EQUAL(nValueRet, 1111 * CENT); // we get the bigger coin BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 1); // but sometimes it's possible, and we use an exact subset (0.4 + 0.6 = 1.0) empty_wallet(); - add_coin(0.4 * CENT); - add_coin(0.6 * CENT); - add_coin(0.8 * CENT); + add_coin((GRC::Allocation(4, 10, true) * CENT).ToCAmount()); + add_coin((GRC::Allocation(6, 10, true) * CENT).ToCAmount()); + add_coin((GRC::Allocation(8, 10, true) * CENT).ToCAmount()); add_coin(1111 * CENT); - BOOST_CHECK( wallet.SelectCoinsMinConf(1 * CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); // we should get the exact amount + BOOST_CHECK(wallet.SelectCoinsMinConf(CENT, spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, CENT); // we should get the exact amount BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 2); // in two coins 0.4+0.6 // test avoiding sub-cent change empty_wallet(); // Use rational arithmetic because the floating point has problems with GCC13 on 32 bit architecture x86. - add_coin(static_cast(Fraction(5, 10000, true) * COIN).ToCAmount()); - add_coin(static_cast(Fraction(1, 100, true) * COIN).ToCAmount()); - add_coin(1 * COIN); + add_coin((GRC::Allocation(5, 10000, true) * COIN).ToCAmount()); + add_coin((GRC::Allocation(1, 100, true) * COIN).ToCAmount()); + add_coin(COIN); // trying to make 1.0001 from these three coins - BOOST_CHECK( wallet.SelectCoinsMinConf(static_cast(Fraction(10001, 10000, true) * COIN).ToCAmount(), + BOOST_CHECK(wallet.SelectCoinsMinConf((GRC::Allocation(10001, 10000, true) * COIN).ToCAmount(), spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); // we should get all coins - BOOST_CHECK(nValueRet == static_cast(Fraction(10105, 10000, true) * COIN).ToCAmount()); + BOOST_CHECK(nValueRet == (GRC::Allocation(10105, 10000, true) * COIN).ToCAmount()); BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 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(static_cast(Fraction(999, 1000, true) * COIN).ToCAmount(), + BOOST_CHECK(wallet.SelectCoinsMinConf((GRC::Allocation(999, 1000, true) * COIN).ToCAmount(), spendTime, 1, 1, vCoins, setCoinsRet, nValueRet)); // we should get 1 + 0.01 - BOOST_CHECK(nValueRet == static_cast(Fraction(101, 100, true) * COIN).ToCAmount()); + BOOST_CHECK(nValueRet == (GRC::Allocation(101, 100, true) * COIN).ToCAmount()); BOOST_CHECK_EQUAL(setCoinsRet.size(), (size_t) 2); // test randomness @@ -283,15 +283,15 @@ BOOST_AUTO_TEST_CASE(coin_selection_tests) // 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); + 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, spendTime, 1, 6, vCoins, setCoinsRet , nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(90*CENT, spendTime, 1, 6, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90 * CENT, spendTime, 1, 6, vCoins, setCoinsRet , nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90 * CENT, spendTime, 1, 6, vCoins, setCoinsRet2, nValueRet)); if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; }