diff --git a/src/amount.h b/src/amount.h --- a/src/amount.h +++ b/src/amount.h @@ -9,13 +9,98 @@ #include "serialize.h" #include +#include #include +#include + +struct Amount { +private: + int64_t amount; + +public: + Amount() : amount(0) {} + template ::value), + T>::type = 0> + Amount(T _camount) : amount(_camount) {} + Amount(const Amount &_camount) : amount(_camount.amount) {} + + // Allow access to underlying value for non-monetary operations + int64_t GetSatoshis() const { return amount; } + + /* + * Implement standard operators + */ + Amount &operator+=(const Amount a) { + amount += a.amount; + return *this; + } + Amount &operator-=(const Amount a) { + amount -= a.amount; + return *this; + } + friend bool operator<(const Amount a, const Amount b) { + return a.amount < b.amount; + } + friend bool operator==(const Amount a, const Amount b) { + return a.amount == b.amount; + } + friend bool operator>(const Amount a, const Amount b) { + return b.amount < a.amount; + } + friend bool operator!=(const Amount a, const Amount b) { + return !(a.amount == b.amount); + } + friend bool operator<=(const Amount a, const Amount b) { + return !(a.amount > b.amount); + } + friend bool operator>=(const Amount a, const Amount b) { + return !(a.amount < b.amount); + } + friend Amount operator+(const Amount a, const Amount b) { + return Amount(a.amount + b.amount); + } + friend Amount operator-(const Amount a, const Amount b) { + return Amount(a.amount - b.amount); + } + // Implemented for allowing COIN as a base unit. + template ::value), + T>::type = 0> + friend Amount operator*(const T a, const Amount b) { + return Amount(a * b.amount); + } + // Used for converting to a string + template ::value), + T>::type = 0> + friend T operator/(const Amount a, const T b) { + return T(a.amount) / b; + } + // Used for converting to a string + template ::value), + T>::type = 0> + friend T operator%(const Amount a, const T b) { + return T(a.amount) % b; + } + + // ostream support + friend std::ostream &operator<<(std::ostream &stream, const Amount &ca) { + return stream << ca.amount; + } + std::string ToString() const; + + // serialization support + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream &s, Operation ser_action) { + READWRITE(amount); + } +}; /** Amount in satoshis (Can be negative) */ typedef int64_t CAmount; -static const CAmount COIN = 100000000; -static const CAmount CENT = 1000000; +static const Amount COIN = 100000000; +static const Amount CENT = 1000000; extern const std::string CURRENCY_UNIT; @@ -29,7 +114,7 @@ * critical; in unusual circumstances like a(nother) overflow bug that allowed * for the creation of coins out of thin air modification could lead to a fork. */ -static const CAmount MAX_MONEY = 21000000 * COIN; +static const Amount MAX_MONEY = 21000000 * COIN; inline bool MoneyRange(const CAmount &nValue) { return (nValue >= 0 && nValue <= MAX_MONEY); } diff --git a/src/amount.cpp b/src/amount.cpp --- a/src/amount.cpp +++ b/src/amount.cpp @@ -9,6 +9,11 @@ const std::string CURRENCY_UNIT = "BCC"; +std::string Amount::ToString() const { + return strprintf("%d.%08d %s", amount / COIN.GetSatoshis(), + amount % COIN.GetSatoshis(), CURRENCY_UNIT); +} + CFeeRate::CFeeRate(const CAmount &nFeePaid, size_t nBytes_) { assert(nBytes_ <= uint64_t(std::numeric_limits::max())); int64_t nSize = int64_t(nBytes_); @@ -39,6 +44,6 @@ } std::string CFeeRate::ToString() const { - return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN, - nSatoshisPerK % COIN, CURRENCY_UNIT); + return strprintf("%d.%08d %s/kB", nSatoshisPerK / COIN.GetSatoshis(), + nSatoshisPerK % COIN.GetSatoshis(), CURRENCY_UNIT); } diff --git a/src/bench/ccoins_caching.cpp b/src/bench/ccoins_caching.cpp --- a/src/bench/ccoins_caching.cpp +++ b/src/bench/ccoins_caching.cpp @@ -30,19 +30,19 @@ // Create some dummy input transactions dummyTransactions[0].vout.resize(2); - dummyTransactions[0].vout[0].nValue = 11 * CENT; + dummyTransactions[0].vout[0].nValue = 11 * CENT.GetSatoshis(); dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG; - dummyTransactions[0].vout[1].nValue = 50 * CENT; + dummyTransactions[0].vout[1].nValue = 50 * CENT.GetSatoshis(); dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG; AddCoins(coinsRet, dummyTransactions[0], 0); dummyTransactions[1].vout.resize(2); - dummyTransactions[1].vout[0].nValue = 21 * CENT; + dummyTransactions[1].vout[0].nValue = 21 * CENT.GetSatoshis(); dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID()); - dummyTransactions[1].vout[1].nValue = 22 * CENT; + dummyTransactions[1].vout[1].nValue = 22 * CENT.GetSatoshis(); dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID()); AddCoins(coinsRet, dummyTransactions[1], 0); @@ -77,7 +77,7 @@ t1.vin[2].scriptSig << std::vector(65, 0) << std::vector(33, 4); t1.vout.resize(2); - t1.vout[0].nValue = 90 * CENT; + t1.vout[0].nValue = 90 * CENT.GetSatoshis(); t1.vout[0].scriptPubKey << OP_1; // Benchmark. @@ -85,7 +85,7 @@ bool success = AreInputsStandard(t1, coins); assert(success); CAmount value = coins.GetValueIn(t1); - assert(value == (50 + 21 + 22) * CENT); + assert(value == (50 + 21 + 22) * CENT.GetSatoshis()); } } diff --git a/src/bench/coin_selection.cpp b/src/bench/coin_selection.cpp --- a/src/bench/coin_selection.cpp +++ b/src/bench/coin_selection.cpp @@ -46,13 +46,13 @@ // Add coins. for (int i = 0; i < 1000; i++) - addCoin(1000 * COIN, wallet, vCoins); - addCoin(3 * COIN, wallet, vCoins); + addCoin(1000 * COIN.GetSatoshis(), wallet, vCoins); + addCoin(3 * COIN.GetSatoshis(), wallet, vCoins); std::set> setCoinsRet; CAmount nValueRet; - bool success = wallet.SelectCoinsMinConf(1003 * COIN, 1, 6, 0, vCoins, - setCoinsRet, nValueRet); + bool success = wallet.SelectCoinsMinConf( + 1003 * COIN.GetSatoshis(), 1, 6, 0, vCoins, setCoinsRet, nValueRet); assert(success); assert(nValueRet == 1003 * COIN); assert(setCoinsRet.size() == 2); diff --git a/src/bench/mempool_eviction.cpp b/src/bench/mempool_eviction.cpp --- a/src/bench/mempool_eviction.cpp +++ b/src/bench/mempool_eviction.cpp @@ -32,14 +32,14 @@ tx1.vin[0].scriptSig = CScript() << OP_1; tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; - tx1.vout[0].nValue = 10 * COIN; + tx1.vout[0].nValue = 10 * COIN.GetSatoshis(); CMutableTransaction tx2 = CMutableTransaction(); tx2.vin.resize(1); tx2.vin[0].scriptSig = CScript() << OP_2; tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL; - tx2.vout[0].nValue = 10 * COIN; + tx2.vout[0].nValue = 10 * COIN.GetSatoshis(); CMutableTransaction tx3 = CMutableTransaction(); tx3.vin.resize(1); @@ -47,7 +47,7 @@ tx3.vin[0].scriptSig = CScript() << OP_2; tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL; - tx3.vout[0].nValue = 10 * COIN; + tx3.vout[0].nValue = 10 * COIN.GetSatoshis(); CMutableTransaction tx4 = CMutableTransaction(); tx4.vin.resize(2); @@ -57,9 +57,9 @@ tx4.vin[1].scriptSig = CScript() << OP_4; tx4.vout.resize(2); tx4.vout[0].scriptPubKey = CScript() << OP_4 << OP_EQUAL; - tx4.vout[0].nValue = 10 * COIN; + tx4.vout[0].nValue = 10 * COIN.GetSatoshis(); tx4.vout[1].scriptPubKey = CScript() << OP_4 << OP_EQUAL; - tx4.vout[1].nValue = 10 * COIN; + tx4.vout[1].nValue = 10 * COIN.GetSatoshis(); CMutableTransaction tx5 = CMutableTransaction(); tx5.vin.resize(2); @@ -69,9 +69,9 @@ tx5.vin[1].scriptSig = CScript() << OP_5; tx5.vout.resize(2); tx5.vout[0].scriptPubKey = CScript() << OP_5 << OP_EQUAL; - tx5.vout[0].nValue = 10 * COIN; + tx5.vout[0].nValue = 10 * COIN.GetSatoshis(); tx5.vout[1].scriptPubKey = CScript() << OP_5 << OP_EQUAL; - tx5.vout[1].nValue = 10 * COIN; + tx5.vout[1].nValue = 10 * COIN.GetSatoshis(); CMutableTransaction tx6 = CMutableTransaction(); tx6.vin.resize(2); @@ -81,9 +81,9 @@ tx6.vin[1].scriptSig = CScript() << OP_6; tx6.vout.resize(2); tx6.vout[0].scriptPubKey = CScript() << OP_6 << OP_EQUAL; - tx6.vout[0].nValue = 10 * COIN; + tx6.vout[0].nValue = 10 * COIN.GetSatoshis(); tx6.vout[1].scriptPubKey = CScript() << OP_6 << OP_EQUAL; - tx6.vout[1].nValue = 10 * COIN; + tx6.vout[1].nValue = 10 * COIN.GetSatoshis(); CMutableTransaction tx7 = CMutableTransaction(); tx7.vin.resize(2); @@ -93,9 +93,9 @@ tx7.vin[1].scriptSig = CScript() << OP_6; tx7.vout.resize(2); tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL; - tx7.vout[0].nValue = 10 * COIN; + tx7.vout[0].nValue = 10 * COIN.GetSatoshis(); tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL; - tx7.vout[1].nValue = 10 * COIN; + tx7.vout[1].nValue = 10 * COIN.GetSatoshis(); CTxMemPool pool(CFeeRate(1000)); diff --git a/src/chainparams.cpp b/src/chainparams.cpp --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -160,7 +160,7 @@ nPruneAfterHeight = 100000; genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, - 50 * COIN); + 50 * COIN.GetSatoshis()); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3" @@ -320,8 +320,8 @@ nDefaultPort = 18333; nPruneAfterHeight = 1000; - genesis = - CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN); + genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, + 50 * COIN.GetSatoshis()); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f4087195" @@ -443,7 +443,8 @@ nDefaultPort = 18444; nPruneAfterHeight = 1000; - genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN); + genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, + 50 * COIN.GetSatoshis()); consensus.hashGenesisBlock = genesis.GetHash(); assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b" diff --git a/src/policy/fees.h b/src/policy/fees.h --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -200,8 +200,8 @@ // Minimum and Maximum values for tracking feerates static constexpr double MIN_FEERATE = 10; static const double MAX_FEERATE = 1e7; -static const double INF_FEERATE = MAX_MONEY; -static const double INF_PRIORITY = 1e9 * MAX_MONEY; +static const double INF_FEERATE = MAX_MONEY.GetSatoshis(); +static const double INF_PRIORITY = 1e9 * MAX_MONEY.GetSatoshis(); // We have to lump transactions into buckets based on feerate, but we want to be // able to give accurate estimates over a large range of potential feerates. diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -46,8 +46,9 @@ } std::string CTxOut::ToString() const { - return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, - nValue % COIN, HexStr(scriptPubKey).substr(0, 30)); + return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", + nValue / COIN.GetSatoshis(), nValue % COIN.GetSatoshis(), + HexStr(scriptPubKey).substr(0, 30)); } CMutableTransaction::CMutableTransaction() diff --git a/src/qt/bitcoinunits.cpp b/src/qt/bitcoinunits.cpp --- a/src/qt/bitcoinunits.cpp +++ b/src/qt/bitcoinunits.cpp @@ -212,5 +212,5 @@ } CAmount BitcoinUnits::maxMoney() { - return MAX_MONEY; + return MAX_MONEY.GetSatoshis(); } diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -806,7 +806,7 @@ "of allowed range (%2, allowed 0 - %3).") .arg(__func__) .arg(requestAmount) - .arg(MAX_MONEY); + .arg(MAX_MONEY.GetSatoshis()); } return fVerified; } diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -126,8 +126,8 @@ UniValue ValueFromAmount(const CAmount &amount) { bool sign = amount < 0; int64_t n_abs = (sign ? -amount : amount); - int64_t quotient = n_abs / COIN; - int64_t remainder = n_abs % COIN; + int64_t quotient = n_abs / COIN.GetSatoshis(); + int64_t remainder = n_abs % COIN.GetSatoshis(); return UniValue(UniValue::VNUM, strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder)); } diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -155,7 +155,7 @@ tx.vin[0].prevout.hash = GetRandHash(); tx.vin[0].scriptSig << OP_1; tx.vout.resize(1); - tx.vout[0].nValue = 1 * CENT; + tx.vout[0].nValue = 1 * CENT.GetSatoshis(); tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); @@ -171,7 +171,7 @@ tx.vin[0].prevout.n = 0; tx.vin[0].prevout.hash = txPrev->GetId(); tx.vout.resize(1); - tx.vout[0].nValue = 1 * CENT; + tx.vout[0].nValue = 1 * CENT.GetSatoshis(); tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); SignSignature(keystore, *txPrev, tx, 0, SIGHASH_ALL); @@ -185,7 +185,7 @@ CMutableTransaction tx; tx.vout.resize(1); - tx.vout[0].nValue = 1 * CENT; + tx.vout[0].nValue = 1 * CENT.GetSatoshis(); tx.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); tx.vin.resize(2777); diff --git a/src/test/amount_tests.cpp b/src/test/amount_tests.cpp --- a/src/test/amount_tests.cpp +++ b/src/test/amount_tests.cpp @@ -7,8 +7,81 @@ #include +// Snippit to allow compile time introspection for multiplication operator +// Used to ensure that certain operations are not implemented on Amount +namespace Check { +class No { +public: + bool b[2]; +}; +template No operator*(const T &, const Arg &); + +bool Check(...); +No &Check(const No &); + +template struct MultiplicationExists { + enum { value = (sizeof(Check(*(T *)(0) * *(Arg *)(0))) != sizeof(No)) }; +}; +} // namespace Check + BOOST_FIXTURE_TEST_SUITE(amount_tests, BasicTestingSetup) +BOOST_AUTO_TEST_CASE(CAmountTests) { + BOOST_CHECK(Amount(2) <= Amount(2)); + BOOST_CHECK(Amount(2) <= Amount(3)); + + BOOST_CHECK(Amount(2) >= Amount(2)); + BOOST_CHECK(Amount(3) >= Amount(2)); + + BOOST_CHECK(Amount(1) < Amount(2)); + BOOST_CHECK(Amount(-1) < Amount(0)); + + BOOST_CHECK(Amount(2) > Amount(1)); + BOOST_CHECK(Amount(0) > Amount(-1)); + + BOOST_CHECK(Amount(1) < Amount(2)); + BOOST_CHECK(Amount(-1) < Amount(0)); + + BOOST_CHECK(Amount(2) > Amount(1)); + BOOST_CHECK(Amount(0) > Amount(-1)); + + BOOST_CHECK(Amount(0) == Amount(0)); + BOOST_CHECK(Amount(0) != Amount(1)); + + Amount amount(0); + BOOST_CHECK_EQUAL(amount += Amount(1), Amount(1)); + BOOST_CHECK_EQUAL(amount += Amount(-1), Amount(0)); + BOOST_CHECK_EQUAL(amount -= Amount(1), Amount(-1)); + BOOST_CHECK_EQUAL(amount -= Amount(-1), Amount(0)); + + BOOST_CHECK_EQUAL(COIN + COIN, Amount(2 * COIN)); + BOOST_CHECK_EQUAL(2 * COIN + COIN, Amount(3 * COIN)); + BOOST_CHECK_EQUAL(-1 * COIN + COIN, Amount(0)); + + BOOST_CHECK_EQUAL(COIN - COIN, Amount(0)); + BOOST_CHECK_EQUAL(COIN - 2 * COIN, -1 * COIN); + + BOOST_CHECK_EQUAL(10 * Amount(10), Amount(100)); + BOOST_CHECK_EQUAL(-1 * Amount(1), Amount(-1)); + + // The C preprocessor will now allow passing a template type into a macro + // directly, so we must define these aliases. + using impl_int = Check::MultiplicationExists; + using impl_float = Check::MultiplicationExists; + BOOST_CHECK(impl_int::value); + BOOST_CHECK(!impl_float::value); + + BOOST_CHECK_EQUAL(Amount(100) / 10, 10); + // This should probably be Banker's rounding, + // but that's a large change + BOOST_CHECK_EQUAL(Amount(100) / 3, 33); + BOOST_CHECK_EQUAL(Amount(101) / 3, 33); + + // Modulus + BOOST_CHECK_EQUAL(COIN % 1, Amount(0)); + BOOST_CHECK_EQUAL((3 * COIN) % (2 * COIN.GetSatoshis()), COIN); +} + BOOST_AUTO_TEST_CASE(GetFeeTest) { CFeeRate feeRate; @@ -66,7 +139,8 @@ BOOST_CHECK(CFeeRate(CAmount(26), 789) == CFeeRate(32)); BOOST_CHECK(CFeeRate(CAmount(27), 789) == CFeeRate(34)); // Maximum size in bytes, should not crash - CFeeRate(MAX_MONEY, std::numeric_limits::max() >> 1).GetFeePerK(); + CFeeRate(MAX_MONEY.GetSatoshis(), std::numeric_limits::max() >> 1) + .GetFeePerK(); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/compress_tests.cpp b/src/test/compress_tests.cpp --- a/src/test/compress_tests.cpp +++ b/src/test/compress_tests.cpp @@ -42,25 +42,25 @@ BOOST_AUTO_TEST_CASE(compress_amounts) { BOOST_CHECK(TestPair(0, 0x0)); BOOST_CHECK(TestPair(1, 0x1)); - BOOST_CHECK(TestPair(CENT, 0x7)); - BOOST_CHECK(TestPair(COIN, 0x9)); - BOOST_CHECK(TestPair(50 * COIN, 0x32)); - BOOST_CHECK(TestPair(21000000 * COIN, 0x1406f40)); + BOOST_CHECK(TestPair(CENT.GetSatoshis(), 0x7)); + BOOST_CHECK(TestPair(COIN.GetSatoshis(), 0x9)); + BOOST_CHECK(TestPair(50 * COIN.GetSatoshis(), 0x32)); + BOOST_CHECK(TestPair(21000000 * COIN.GetSatoshis(), 0x1406f40)); for (uint64_t i = 1; i <= NUM_MULTIPLES_UNIT; i++) { BOOST_CHECK(TestEncode(i)); } for (uint64_t i = 1; i <= NUM_MULTIPLES_CENT; i++) { - BOOST_CHECK(TestEncode(i * CENT)); + BOOST_CHECK(TestEncode(i * CENT.GetSatoshis())); } for (uint64_t i = 1; i <= NUM_MULTIPLES_1BCC; i++) { - BOOST_CHECK(TestEncode(i * COIN)); + BOOST_CHECK(TestEncode(i * COIN.GetSatoshis())); } for (uint64_t i = 1; i <= NUM_MULTIPLES_50BCC; i++) { - BOOST_CHECK(TestEncode(i * 50 * COIN)); + BOOST_CHECK(TestEncode(i * 50 * COIN.GetSatoshis())); } for (uint64_t i = 0; i < 100000; i++) { diff --git a/src/test/main_tests.cpp b/src/test/main_tests.cpp --- a/src/test/main_tests.cpp +++ b/src/test/main_tests.cpp @@ -15,7 +15,7 @@ static void TestBlockSubsidyHalvings(const Consensus::Params &consensusParams) { int maxHalvings = 64; - CAmount nInitialSubsidy = 50 * COIN; + CAmount nInitialSubsidy = 50 * COIN.GetSatoshis(); CAmount nPreviousSubsidy = nInitialSubsidy * 2; // for height == 0 BOOST_CHECK_EQUAL(nPreviousSubsidy, nInitialSubsidy * 2); diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -155,7 +155,7 @@ CMutableTransaction tx1 = CMutableTransaction(); tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx1.vout[0].nValue = 10 * COIN; + tx1.vout[0].nValue = 10 * COIN.GetSatoshis(); pool.addUnchecked(tx1.GetId(), entry.Fee(10000LL).Priority(10.0).FromTx(tx1)); @@ -163,7 +163,7 @@ CMutableTransaction tx2 = CMutableTransaction(); tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx2.vout[0].nValue = 2 * COIN; + tx2.vout[0].nValue = 2 * COIN.GetSatoshis(); pool.addUnchecked(tx2.GetId(), entry.Fee(20000LL).Priority(9.0).FromTx(tx2)); @@ -171,14 +171,14 @@ CMutableTransaction tx3 = CMutableTransaction(); tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx3.vout[0].nValue = 5 * COIN; + tx3.vout[0].nValue = 5 * COIN.GetSatoshis(); pool.addUnchecked(tx3.GetId(), entry.Fee(0LL).Priority(100.0).FromTx(tx3)); /* 2nd highest fee */ CMutableTransaction tx4 = CMutableTransaction(); tx4.vout.resize(1); tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx4.vout[0].nValue = 6 * COIN; + tx4.vout[0].nValue = 6 * COIN.GetSatoshis(); pool.addUnchecked(tx4.GetId(), entry.Fee(15000LL).Priority(1.0).FromTx(tx4)); @@ -186,7 +186,7 @@ CMutableTransaction tx5 = CMutableTransaction(); tx5.vout.resize(1); tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx5.vout[0].nValue = 11 * COIN; + tx5.vout[0].nValue = 11 * COIN.GetSatoshis(); entry.nTime = 1; entry.dPriority = 10.0; pool.addUnchecked(tx5.GetId(), entry.Fee(10000LL).FromTx(tx5)); @@ -206,7 +206,7 @@ CMutableTransaction tx6 = CMutableTransaction(); tx6.vout.resize(1); tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx6.vout[0].nValue = 20 * COIN; + tx6.vout[0].nValue = 20 * COIN.GetSatoshis(); pool.addUnchecked(tx6.GetId(), entry.Fee(0LL).FromTx(tx6)); BOOST_CHECK_EQUAL(pool.size(), 6); // Check that at this point, tx6 is sorted low @@ -221,9 +221,9 @@ tx7.vin[0].scriptSig = CScript() << OP_11; tx7.vout.resize(2); tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx7.vout[0].nValue = 10 * COIN; + tx7.vout[0].nValue = 10 * COIN.GetSatoshis(); tx7.vout[1].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx7.vout[1].nValue = 1 * COIN; + tx7.vout[1].nValue = 1 * COIN.GetSatoshis(); CTxMemPool::setEntries setAncestorsCalculated; std::string dummy; @@ -250,7 +250,7 @@ tx8.vin[0].scriptSig = CScript() << OP_11; tx8.vout.resize(1); tx8.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx8.vout[0].nValue = 10 * COIN; + tx8.vout[0].nValue = 10 * COIN.GetSatoshis(); setAncestors.insert(pool.mapTx.find(tx7.GetId())); pool.addUnchecked(tx8.GetId(), entry.Fee(0LL).Time(2).FromTx(tx8), setAncestors); @@ -266,7 +266,7 @@ tx9.vin[0].scriptSig = CScript() << OP_11; tx9.vout.resize(1); tx9.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx9.vout[0].nValue = 1 * COIN; + tx9.vout[0].nValue = 1 * COIN.GetSatoshis(); pool.addUnchecked(tx9.GetId(), entry.Fee(0LL).Time(3).FromTx(tx9), setAncestors); @@ -288,7 +288,7 @@ tx10.vin[1].scriptSig = CScript() << OP_11; tx10.vout.resize(1); tx10.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx10.vout[0].nValue = 10 * COIN; + tx10.vout[0].nValue = 10 * COIN.GetSatoshis(); setAncestorsCalculated.clear(); BOOST_CHECK_EQUAL( @@ -371,7 +371,7 @@ CMutableTransaction tx1 = CMutableTransaction(); tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx1.vout[0].nValue = 10 * COIN; + tx1.vout[0].nValue = 10 * COIN.GetSatoshis(); pool.addUnchecked(tx1.GetId(), entry.Fee(10000LL).Priority(10.0).FromTx(tx1)); @@ -379,7 +379,7 @@ CMutableTransaction tx2 = CMutableTransaction(); tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx2.vout[0].nValue = 2 * COIN; + tx2.vout[0].nValue = 2 * COIN.GetSatoshis(); pool.addUnchecked(tx2.GetId(), entry.Fee(20000LL).Priority(9.0).FromTx(tx2)); uint64_t tx2Size = GetTransactionSize(tx2); @@ -388,14 +388,14 @@ CMutableTransaction tx3 = CMutableTransaction(); tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx3.vout[0].nValue = 5 * COIN; + tx3.vout[0].nValue = 5 * COIN.GetSatoshis(); pool.addUnchecked(tx3.GetId(), entry.Fee(0LL).Priority(100.0).FromTx(tx3)); /* 2nd highest fee */ CMutableTransaction tx4 = CMutableTransaction(); tx4.vout.resize(1); tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx4.vout[0].nValue = 6 * COIN; + tx4.vout[0].nValue = 6 * COIN.GetSatoshis(); pool.addUnchecked(tx4.GetId(), entry.Fee(15000LL).Priority(1.0).FromTx(tx4)); @@ -403,7 +403,7 @@ CMutableTransaction tx5 = CMutableTransaction(); tx5.vout.resize(1); tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx5.vout[0].nValue = 11 * COIN; + tx5.vout[0].nValue = 11 * COIN.GetSatoshis(); pool.addUnchecked(tx5.GetId(), entry.Fee(10000LL).FromTx(tx5)); BOOST_CHECK_EQUAL(pool.size(), 5); @@ -430,7 +430,7 @@ CMutableTransaction tx6 = CMutableTransaction(); tx6.vout.resize(1); tx6.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx6.vout[0].nValue = 20 * COIN; + tx6.vout[0].nValue = 20 * COIN.GetSatoshis(); uint64_t tx6Size = GetTransactionSize(tx6); pool.addUnchecked(tx6.GetId(), entry.Fee(0LL).FromTx(tx6)); @@ -450,7 +450,7 @@ tx7.vin[0].scriptSig = CScript() << OP_11; tx7.vout.resize(1); tx7.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; - tx7.vout[0].nValue = 10 * COIN; + tx7.vout[0].nValue = 10 * COIN.GetSatoshis(); uint64_t tx7Size = GetTransactionSize(tx7); /* set the fee to just below tx2's feerate when including ancestor */ @@ -487,7 +487,7 @@ tx1.vin[0].scriptSig = CScript() << OP_1; tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; - tx1.vout[0].nValue = 10 * COIN; + tx1.vout[0].nValue = 10 * COIN.GetSatoshis(); pool.addUnchecked(tx1.GetId(), entry.Fee(10000LL).FromTx(tx1, &pool)); CMutableTransaction tx2 = CMutableTransaction(); @@ -495,7 +495,7 @@ tx2.vin[0].scriptSig = CScript() << OP_2; tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL; - tx2.vout[0].nValue = 10 * COIN; + tx2.vout[0].nValue = 10 * COIN.GetSatoshis(); pool.addUnchecked(tx2.GetId(), entry.Fee(5000LL).FromTx(tx2, &pool)); // should do nothing @@ -515,7 +515,7 @@ tx3.vin[0].scriptSig = CScript() << OP_2; tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL; - tx3.vout[0].nValue = 10 * COIN; + tx3.vout[0].nValue = 10 * COIN.GetSatoshis(); pool.addUnchecked(tx3.GetId(), entry.Fee(20000LL).FromTx(tx3, &pool)); // tx3 should pay for tx2 (CPFP) @@ -530,8 +530,8 @@ BOOST_CHECK(!pool.exists(tx2.GetId())); BOOST_CHECK(!pool.exists(tx3.GetId())); - CFeeRate maxFeeRateRemoved( - 25000, GetTransactionSize(tx3) + GetTransactionSize(tx2)); + CFeeRate maxFeeRateRemoved(25000, GetTransactionSize(tx3) + + GetTransactionSize(tx2)); BOOST_CHECK_EQUAL(pool.GetMinFee(1).GetFeePerK(), maxFeeRateRemoved.GetFeePerK() + 1000); @@ -543,9 +543,9 @@ tx4.vin[1].scriptSig = CScript() << OP_4; tx4.vout.resize(2); tx4.vout[0].scriptPubKey = CScript() << OP_4 << OP_EQUAL; - tx4.vout[0].nValue = 10 * COIN; + tx4.vout[0].nValue = 10 * COIN.GetSatoshis(); tx4.vout[1].scriptPubKey = CScript() << OP_4 << OP_EQUAL; - tx4.vout[1].nValue = 10 * COIN; + tx4.vout[1].nValue = 10 * COIN.GetSatoshis(); CMutableTransaction tx5 = CMutableTransaction(); tx5.vin.resize(2); @@ -555,9 +555,9 @@ tx5.vin[1].scriptSig = CScript() << OP_5; tx5.vout.resize(2); tx5.vout[0].scriptPubKey = CScript() << OP_5 << OP_EQUAL; - tx5.vout[0].nValue = 10 * COIN; + tx5.vout[0].nValue = 10 * COIN.GetSatoshis(); tx5.vout[1].scriptPubKey = CScript() << OP_5 << OP_EQUAL; - tx5.vout[1].nValue = 10 * COIN; + tx5.vout[1].nValue = 10 * COIN.GetSatoshis(); CMutableTransaction tx6 = CMutableTransaction(); tx6.vin.resize(2); @@ -567,9 +567,9 @@ tx6.vin[1].scriptSig = CScript() << OP_6; tx6.vout.resize(2); tx6.vout[0].scriptPubKey = CScript() << OP_6 << OP_EQUAL; - tx6.vout[0].nValue = 10 * COIN; + tx6.vout[0].nValue = 10 * COIN.GetSatoshis(); tx6.vout[1].scriptPubKey = CScript() << OP_6 << OP_EQUAL; - tx6.vout[1].nValue = 10 * COIN; + tx6.vout[1].nValue = 10 * COIN.GetSatoshis(); CMutableTransaction tx7 = CMutableTransaction(); tx7.vin.resize(2); @@ -579,9 +579,9 @@ tx7.vin[1].scriptSig = CScript() << OP_6; tx7.vout.resize(2); tx7.vout[0].scriptPubKey = CScript() << OP_7 << OP_EQUAL; - tx7.vout[0].nValue = 10 * COIN; + tx7.vout[0].nValue = 10 * COIN.GetSatoshis(); tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL; - tx7.vout[1].nValue = 10 * COIN; + tx7.vout[1].nValue = 10 * COIN.GetSatoshis(); pool.addUnchecked(tx4.GetId(), entry.Fee(7000LL).FromTx(tx4, &pool)); pool.addUnchecked(tx5.GetId(), entry.Fee(1000LL).FromTx(tx5, &pool)); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -2,13 +2,13 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "miner.h" #include "chainparams.h" #include "coins.h" #include "config.h" #include "consensus/consensus.h" #include "consensus/merkle.h" #include "consensus/validation.h" +#include "miner.h" #include "policy/policy.h" #include "pubkey.h" #include "script/standard.h" @@ -17,7 +17,6 @@ #include "util.h" #include "utilstrencodings.h" #include "validation.h" -#include "validation.h" #include "test/test_bitcoin.h" @@ -300,10 +299,10 @@ pblocktemplate = BlockAssembler(config, chainparams).CreateNewBlock(scriptPubKey)); - const CAmount BLOCKSUBSIDY = 50 * COIN; - const CAmount LOWFEE = CENT; - const CAmount HIGHFEE = COIN; - const CAmount HIGHERFEE = 4 * COIN; + const CAmount BLOCKSUBSIDY = 50 * COIN.GetSatoshis(); + const CAmount LOWFEE = CENT.GetSatoshis(); + const CAmount HIGHFEE = COIN.GetSatoshis(); + const CAmount HIGHERFEE = 4 * COIN.GetSatoshis(); // block sigops > limit: 1000 CHECKMULTISIG + 1 tx.vin.resize(1); diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -255,32 +255,48 @@ "20999999.99999999"); BOOST_CHECK_EQUAL(ValueFromAmount(0).write(), "0.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount((COIN / 10000) * 123456789).write(), - "12345.67890000"); - BOOST_CHECK_EQUAL(ValueFromAmount(-COIN).write(), "-1.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(-COIN / 10).write(), "-0.10000000"); - - BOOST_CHECK_EQUAL(ValueFromAmount(COIN * 100000000).write(), + BOOST_CHECK_EQUAL( + ValueFromAmount((COIN.GetSatoshis() / 10000) * 123456789).write(), + "12345.67890000"); + BOOST_CHECK_EQUAL(ValueFromAmount(-COIN.GetSatoshis()).write(), + "-1.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(-COIN.GetSatoshis() / 10).write(), + "-0.10000000"); + + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() * 100000000).write(), "100000000.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN * 10000000).write(), + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() * 10000000).write(), "10000000.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN * 1000000).write(), + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() * 1000000).write(), "1000000.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN * 100000).write(), + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() * 100000).write(), "100000.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN * 10000).write(), "10000.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN * 1000).write(), "1000.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN * 100).write(), "100.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN * 10).write(), "10.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN).write(), "1.00000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN / 10).write(), "0.10000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN / 100).write(), "0.01000000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN / 1000).write(), "0.00100000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN / 10000).write(), "0.00010000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN / 100000).write(), "0.00001000"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN / 1000000).write(), "0.00000100"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN / 10000000).write(), "0.00000010"); - BOOST_CHECK_EQUAL(ValueFromAmount(COIN / 100000000).write(), "0.00000001"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() * 10000).write(), + "10000.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() * 1000).write(), + "1000.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() * 100).write(), + "100.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() * 10).write(), + "10.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis()).write(), + "1.00000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() / 10).write(), + "0.10000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() / 100).write(), + "0.01000000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() / 1000).write(), + "0.00100000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() / 10000).write(), + "0.00010000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() / 100000).write(), + "0.00001000"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() / 1000000).write(), + "0.00000100"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() / 10000000).write(), + "0.00000010"); + BOOST_CHECK_EQUAL(ValueFromAmount(COIN.GetSatoshis() / 100000000).write(), + "0.00000001"); } static UniValue ValueFromString(const std::string &str) { @@ -310,26 +326,26 @@ 2099999999999999LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("1e-8")), - COIN / 100000000); + COIN.GetSatoshis() / 100000000); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.1e-7")), - COIN / 100000000); + COIN.GetSatoshis() / 100000000); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.01e-6")), - COIN / 100000000); + COIN.GetSatoshis() / 100000000); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString( "0." "0000000000000000000000000000000000000000000000000000" "000000000000000000000001e+68")), - COIN / 100000000); + COIN.GetSatoshis() / 100000000); BOOST_CHECK_EQUAL( AmountFromValue(ValueFromString("10000000000000000000000000000000000000" "000000000000000000000000000e-64")), - COIN); + COIN.GetSatoshis()); BOOST_CHECK_EQUAL( AmountFromValue(ValueFromString( "0." "000000000000000000000000000000000000000000000000000000000000000100" "000000000000000000000000000000000000000000000000000e64")), - COIN); + COIN.GetSatoshis()); // should fail BOOST_CHECK_THROW(AmountFromValue(ValueFromString("1e-9")), UniValue); diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp --- a/src/test/script_P2SH_tests.cpp +++ b/src/test/script_P2SH_tests.cpp @@ -2,12 +2,12 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "script/script.h" #include "core_io.h" #include "key.h" #include "keystore.h" #include "policy/policy.h" #include "script/ismine.h" +#include "script/script.h" #include "script/script_error.h" #include "script/sign.h" #include "test/test_bitcoin.h" @@ -81,9 +81,9 @@ txFrom.vout.resize(8); for (int i = 0; i < 4; i++) { txFrom.vout[i].scriptPubKey = evalScripts[i]; - txFrom.vout[i].nValue = COIN; + txFrom.vout[i].nValue = COIN.GetSatoshis(); txFrom.vout[i + 4].scriptPubKey = standardScripts[i]; - txFrom.vout[i + 4].nValue = COIN; + txFrom.vout[i + 4].nValue = COIN.GetSatoshis(); } BOOST_CHECK(IsStandardTx(txFrom, reason)); @@ -187,7 +187,7 @@ txFrom.vout.resize(4); for (int i = 0; i < 4; i++) { txFrom.vout[i].scriptPubKey = outer[i]; - txFrom.vout[i].nValue = CENT; + txFrom.vout[i].nValue = CENT.GetSatoshis(); } BOOST_CHECK(IsStandardTx(txFrom, reason)); @@ -198,7 +198,7 @@ txTo[i].vout.resize(1); txTo[i].vin[0].prevout.n = i; txTo[i].vin[0].prevout.hash = txFrom.GetId(); - txTo[i].vout[0].nValue = 1 * CENT; + txTo[i].vout[0].nValue = 1 * CENT.GetSatoshis(); txTo[i].vout[0].scriptPubKey = inner[i]; BOOST_CHECK_MESSAGE(IsMine(keystore, txFrom.vout[i].scriptPubKey), strprintf("IsMine %d", i)); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -113,11 +113,12 @@ uint32_t verify_flags = ParseScriptFlags(test[2].get_str()); BOOST_CHECK_MESSAGE( - VerifyScript(tx.vin[i].scriptSig, - mapprevOutScriptPubKeys[tx.vin[i].prevout], - verify_flags, TransactionSignatureChecker( - &tx, i, amount, txdata), - &err), + VerifyScript( + tx.vin[i].scriptSig, + mapprevOutScriptPubKeys[tx.vin[i].prevout], + verify_flags, + TransactionSignatureChecker(&tx, i, amount, txdata), + &err), strTest); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); @@ -270,19 +271,19 @@ // Create some dummy input transactions dummyTransactions[0].vout.resize(2); - dummyTransactions[0].vout[0].nValue = 11 * CENT; + dummyTransactions[0].vout[0].nValue = 11 * CENT.GetSatoshis(); dummyTransactions[0].vout[0].scriptPubKey << ToByteVector(key[0].GetPubKey()) << OP_CHECKSIG; - dummyTransactions[0].vout[1].nValue = 50 * CENT; + dummyTransactions[0].vout[1].nValue = 50 * CENT.GetSatoshis(); dummyTransactions[0].vout[1].scriptPubKey << ToByteVector(key[1].GetPubKey()) << OP_CHECKSIG; AddCoins(coinsRet, dummyTransactions[0], 0); dummyTransactions[1].vout.resize(2); - dummyTransactions[1].vout[0].nValue = 21 * CENT; + dummyTransactions[1].vout[0].nValue = 21 * CENT.GetSatoshis(); dummyTransactions[1].vout[0].scriptPubKey = GetScriptForDestination(key[2].GetPubKey().GetID()); - dummyTransactions[1].vout[1].nValue = 22 * CENT; + dummyTransactions[1].vout[1].nValue = 22 * CENT.GetSatoshis(); dummyTransactions[1].vout[1].scriptPubKey = GetScriptForDestination(key[3].GetPubKey().GetID()); AddCoins(coinsRet, dummyTransactions[1], 0); @@ -311,11 +312,12 @@ t1.vin[2].scriptSig << std::vector(65, 0) << std::vector(33, 4); t1.vout.resize(2); - t1.vout[0].nValue = 90 * CENT; + t1.vout[0].nValue = 90 * CENT.GetSatoshis(); t1.vout[0].scriptPubKey << OP_1; BOOST_CHECK(AreInputsStandard(t1, coins)); - BOOST_CHECK_EQUAL(coins.GetValueIn(t1), (50 + 21 + 22) * CENT); + BOOST_CHECK_EQUAL(coins.GetValueIn(t1), + (50 + 21 + 22) * CENT.GetSatoshis()); } void CreateCreditAndSpend(const CKeyStore &keystore, const CScript &outscript, @@ -489,11 +491,12 @@ CheckWithFlag(output2, input2, 0, false); BOOST_CHECK(*output1 == *output2); UpdateTransaction( - input1, 0, CombineSignatures(output1->vout[0].scriptPubKey, - MutableTransactionSignatureChecker( - &input1, 0, output1->vout[0].nValue), - DataFromTransaction(input1, 0), - DataFromTransaction(input2, 0))); + input1, 0, + CombineSignatures(output1->vout[0].scriptPubKey, + MutableTransactionSignatureChecker( + &input1, 0, output1->vout[0].nValue), + DataFromTransaction(input1, 0), + DataFromTransaction(input2, 0))); CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); // P2SH 2-of-2 multisig @@ -509,11 +512,12 @@ CheckWithFlag(output2, input2, SCRIPT_VERIFY_P2SH, false); BOOST_CHECK(*output1 == *output2); UpdateTransaction( - input1, 0, CombineSignatures(output1->vout[0].scriptPubKey, - MutableTransactionSignatureChecker( - &input1, 0, output1->vout[0].nValue), - DataFromTransaction(input1, 0), - DataFromTransaction(input2, 0))); + input1, 0, + CombineSignatures(output1->vout[0].scriptPubKey, + MutableTransactionSignatureChecker( + &input1, 0, output1->vout[0].nValue), + DataFromTransaction(input1, 0), + DataFromTransaction(input2, 0))); CheckWithFlag(output1, input1, SCRIPT_VERIFY_P2SH, true); CheckWithFlag(output1, input1, STANDARD_SCRIPT_VERIFY_FLAGS, true); } @@ -532,7 +536,7 @@ t.vin[0].prevout.n = 1; t.vin[0].scriptSig << std::vector(65, 0); t.vout.resize(1); - t.vout[0].nValue = 90 * CENT; + t.vout[0].nValue = 90 * CENT.GetSatoshis(); CKey key; key.MakeNewKey(true); t.vout[0].scriptPubKey = GetScriptForDestination(key.GetPubKey().GetID()); @@ -587,8 +591,8 @@ // Data payload can be encoded in any way... t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex(""); BOOST_CHECK(IsStandardTx(t, reason)); - t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("00") - << ParseHex("01"); + t.vout[0].scriptPubKey = CScript() + << OP_RETURN << ParseHex("00") << ParseHex("01"); BOOST_CHECK(IsStandardTx(t, reason)); // OP_RESERVED *is* considered to be a PUSHDATA type opcode by IsPushOnly()! t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_RESERVED << -1 << 0 diff --git a/src/test/txvalidationcache_tests.cpp b/src/test/txvalidationcache_tests.cpp --- a/src/test/txvalidationcache_tests.cpp +++ b/src/test/txvalidationcache_tests.cpp @@ -44,7 +44,7 @@ spends[i].vin[0].prevout.hash = coinbaseTxns[0].GetId(); spends[i].vin[0].prevout.n = 0; spends[i].vout.resize(1); - spends[i].vout[0].nValue = 11 * CENT; + spends[i].vout[0].nValue = 11 * CENT.GetSatoshis(); spends[i].vout[0].scriptPubKey = scriptPubKey; // Sign: diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -153,26 +153,30 @@ BOOST_AUTO_TEST_CASE(util_FormatMoney) { BOOST_CHECK_EQUAL(FormatMoney(0), "0.00"); - BOOST_CHECK_EQUAL(FormatMoney((COIN / 10000) * 123456789), "12345.6789"); - BOOST_CHECK_EQUAL(FormatMoney(-COIN), "-1.00"); - - BOOST_CHECK_EQUAL(FormatMoney(COIN * 100000000), "100000000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN * 10000000), "10000000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN * 1000000), "1000000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN * 100000), "100000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN * 10000), "10000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN * 1000), "1000.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN * 100), "100.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN * 10), "10.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN), "1.00"); - BOOST_CHECK_EQUAL(FormatMoney(COIN / 10), "0.10"); - BOOST_CHECK_EQUAL(FormatMoney(COIN / 100), "0.01"); - BOOST_CHECK_EQUAL(FormatMoney(COIN / 1000), "0.001"); - BOOST_CHECK_EQUAL(FormatMoney(COIN / 10000), "0.0001"); - BOOST_CHECK_EQUAL(FormatMoney(COIN / 100000), "0.00001"); - BOOST_CHECK_EQUAL(FormatMoney(COIN / 1000000), "0.000001"); - BOOST_CHECK_EQUAL(FormatMoney(COIN / 10000000), "0.0000001"); - BOOST_CHECK_EQUAL(FormatMoney(COIN / 100000000), "0.00000001"); + BOOST_CHECK_EQUAL(FormatMoney((COIN.GetSatoshis() / 10000) * 123456789), + "12345.6789"); + BOOST_CHECK_EQUAL(FormatMoney(-COIN.GetSatoshis()), "-1.00"); + + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() * 100000000), + "100000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() * 10000000), + "10000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() * 1000000), "1000000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() * 100000), "100000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() * 10000), "10000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() * 1000), "1000.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() * 100), "100.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() * 10), "10.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis()), "1.00"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() / 10), "0.10"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() / 100), "0.01"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() / 1000), "0.001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() / 10000), "0.0001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() / 100000), "0.00001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() / 1000000), "0.000001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() / 10000000), "0.0000001"); + BOOST_CHECK_EQUAL(FormatMoney(COIN.GetSatoshis() / 100000000), + "0.00000001"); } BOOST_AUTO_TEST_CASE(util_ParseMoney) { @@ -181,44 +185,44 @@ BOOST_CHECK_EQUAL(ret, 0); BOOST_CHECK(ParseMoney("12345.6789", ret)); - BOOST_CHECK_EQUAL(ret, (COIN / 10000) * 123456789); + BOOST_CHECK_EQUAL(ret, (COIN.GetSatoshis() / 10000) * 123456789); BOOST_CHECK(ParseMoney("100000000.00", ret)); - BOOST_CHECK_EQUAL(ret, COIN * 100000000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() * 100000000); BOOST_CHECK(ParseMoney("10000000.00", ret)); - BOOST_CHECK_EQUAL(ret, COIN * 10000000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() * 10000000); BOOST_CHECK(ParseMoney("1000000.00", ret)); - BOOST_CHECK_EQUAL(ret, COIN * 1000000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() * 1000000); BOOST_CHECK(ParseMoney("100000.00", ret)); - BOOST_CHECK_EQUAL(ret, COIN * 100000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() * 100000); BOOST_CHECK(ParseMoney("10000.00", ret)); - BOOST_CHECK_EQUAL(ret, COIN * 10000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() * 10000); BOOST_CHECK(ParseMoney("1000.00", ret)); - BOOST_CHECK_EQUAL(ret, COIN * 1000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() * 1000); BOOST_CHECK(ParseMoney("100.00", ret)); - BOOST_CHECK_EQUAL(ret, COIN * 100); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() * 100); BOOST_CHECK(ParseMoney("10.00", ret)); - BOOST_CHECK_EQUAL(ret, COIN * 10); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() * 10); BOOST_CHECK(ParseMoney("1.00", ret)); - BOOST_CHECK_EQUAL(ret, COIN); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis()); BOOST_CHECK(ParseMoney("1", ret)); - BOOST_CHECK_EQUAL(ret, COIN); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis()); BOOST_CHECK(ParseMoney("0.1", ret)); - BOOST_CHECK_EQUAL(ret, COIN / 10); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() / 10); BOOST_CHECK(ParseMoney("0.01", ret)); - BOOST_CHECK_EQUAL(ret, COIN / 100); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() / 100); BOOST_CHECK(ParseMoney("0.001", ret)); - BOOST_CHECK_EQUAL(ret, COIN / 1000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() / 1000); BOOST_CHECK(ParseMoney("0.0001", ret)); - BOOST_CHECK_EQUAL(ret, COIN / 10000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() / 10000); BOOST_CHECK(ParseMoney("0.00001", ret)); - BOOST_CHECK_EQUAL(ret, COIN / 100000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() / 100000); BOOST_CHECK(ParseMoney("0.000001", ret)); - BOOST_CHECK_EQUAL(ret, COIN / 1000000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() / 1000000); BOOST_CHECK(ParseMoney("0.0000001", ret)); - BOOST_CHECK_EQUAL(ret, COIN / 10000000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() / 10000000); BOOST_CHECK(ParseMoney("0.00000001", ret)); - BOOST_CHECK_EQUAL(ret, COIN / 100000000); + BOOST_CHECK_EQUAL(ret, COIN.GetSatoshis() / 100000000); // Attempted 63 bit overflow should fail BOOST_CHECK(!ParseMoney("92233720368.54775808", ret)); diff --git a/src/txmempool.h b/src/txmempool.h --- a/src/txmempool.h +++ b/src/txmempool.h @@ -31,7 +31,7 @@ class CBlockIndex; inline double AllowFreeThreshold() { - return COIN * 144 / 250; + return COIN.GetSatoshis() * 144 / 250; } inline bool AllowFree(double dPriority) { diff --git a/src/utilmoneystr.cpp b/src/utilmoneystr.cpp --- a/src/utilmoneystr.cpp +++ b/src/utilmoneystr.cpp @@ -13,8 +13,8 @@ // Note: not using straight sprintf here because we do NOT want localized // number formatting. int64_t n_abs = (n > 0 ? n : -n); - int64_t quotient = n_abs / COIN; - int64_t remainder = n_abs % COIN; + int64_t quotient = n_abs / COIN.GetSatoshis(); + int64_t remainder = n_abs % COIN.GetSatoshis(); std::string str = strprintf("%d.%08d", quotient, remainder); // Right-trim excess zeros before the decimal point: @@ -40,7 +40,7 @@ for (; *p; p++) { if (*p == '.') { p++; - int64_t nMult = CENT * 10; + int64_t nMult = 10 * CENT.GetSatoshis(); while (isdigit(*p) && (nMult > 0)) { nUnits += nMult * (*p++ - '0'); nMult /= 10; @@ -55,9 +55,9 @@ if (!isspace(*p)) return false; // guard against 63 bit overflow if (strWhole.size() > 10) return false; - if (nUnits < 0 || nUnits > COIN) return false; + if (nUnits < 0 || nUnits > COIN.GetSatoshis()) return false; int64_t nWhole = atoi64(strWhole); - CAmount nValue = nWhole * COIN + nUnits; + CAmount nValue = nWhole * COIN.GetSatoshis() + nUnits; nRet = nValue; return true; diff --git a/src/validation.h b/src/validation.h --- a/src/validation.h +++ b/src/validation.h @@ -60,9 +60,9 @@ /** Default for -minrelaytxfee, minimum relay fee for transactions */ static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000; //! -maxtxfee default -static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN; +static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN.GetSatoshis(); //! Discourage users to set fees higher than this amount (in satoshis) per kB -static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN; +static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN.GetSatoshis(); /** -maxtxfee will warn if called with a higher fee than this amount (in * satoshis */ static const CAmount HIGH_MAX_TX_FEE = 100 * HIGH_TX_FEE_PER_KB; diff --git a/src/validation.cpp b/src/validation.cpp --- a/src/validation.cpp +++ b/src/validation.cpp @@ -156,7 +156,7 @@ /** Dirty block file entries. */ std::set setDirtyFileInfo; -} // anon namespace +} // namespace /* Use this class to start tracking transactions that are removed from the * mempool and pass all those transactions through SyncTransaction when the @@ -1086,7 +1086,7 @@ // Force block reward to zero when right shift is undefined. if (halvings >= 64) return 0; - CAmount nSubsidy = 50 * COIN; + CAmount nSubsidy = 50 * COIN.GetSatoshis(); // Subsidy is cut in half every 210,000 blocks which will occur // approximately every 4 years. nSubsidy >>= halvings; @@ -1199,9 +1199,10 @@ // should be detected by both). We define it this way because it allows us // to only store the highest fork tip (+ base) which meets the 7-block // condition and from this always have the most-likely-to-cause-warning fork - if (pfork && (!pindexBestForkTip || - (pindexBestForkTip && - pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) && + if (pfork && + (!pindexBestForkTip || + (pindexBestForkTip && + pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) && pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) && chainActive.Height() - pindexNewForkTip->nHeight < 72) { @@ -1316,10 +1317,10 @@ } if (nValueIn < tx.GetValueOut()) { - return state.DoS(100, false, REJECT_INVALID, "bad-txns-in-belowout", - false, strprintf("value in (%s) < value out (%s)", - FormatMoney(nValueIn), - FormatMoney(tx.GetValueOut()))); + return state.DoS( + 100, false, REJECT_INVALID, "bad-txns-in-belowout", false, + strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), + FormatMoney(tx.GetValueOut()))); } // Tally transaction fees @@ -1493,7 +1494,7 @@ return state.Error(strMessage); } -} // anon namespace +} // namespace /** Restore the UTXO in a Coin at a given COutPoint. */ DisconnectResult UndoCoinSpend(const Coin &undo, CCoinsViewCache &view, @@ -1921,8 +1922,9 @@ if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) { return state.DoS( - 100, error("%s: contains a non-BIP68-final transaction", - __func__), + 100, + error("%s: contains a non-BIP68-final transaction", + __func__), REJECT_INVALID, "bad-txns-nonfinal"); } } @@ -1972,8 +1974,9 @@ int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2; - LogPrint("bench", " - Connect %u transactions: %.2fms (%.3fms/tx, " - "%.3fms/txin) [%.2fs]\n", + LogPrint("bench", + " - Connect %u transactions: %.2fms (%.3fms/tx, " + "%.3fms/txin) [%.2fs]\n", (unsigned)block.vtx.size(), 0.001 * (nTime3 - nTime2), 0.001 * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : 0.001 * (nTime3 - nTime2) / (nInputs - 1), @@ -1982,9 +1985,10 @@ CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()); if (block.vtx[0]->GetValueOut() > blockReward) { - return state.DoS(100, error("ConnectBlock(): coinbase pays too much " - "(actual=%d vs limit=%d)", - block.vtx[0]->GetValueOut(), blockReward), + return state.DoS(100, + error("ConnectBlock(): coinbase pays too much " + "(actual=%d vs limit=%d)", + block.vtx[0]->GetValueOut(), blockReward), REJECT_INVALID, "bad-cb-amount"); } @@ -2696,9 +2700,8 @@ std::shared_ptr nullBlockPtr; if (!ActivateBestChainStep( config, state, pindexMostWork, - pblock && - pblock->GetHash() == - pindexMostWork->GetBlockHash() + pblock && pblock->GetHash() == + pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) @@ -3399,9 +3402,8 @@ } assert(pindexPrev); - if (fCheckpointsEnabled && - !CheckIndexAgainstCheckpoint(pindexPrev, state, chainparams, - hash)) { + if (fCheckpointsEnabled && !CheckIndexAgainstCheckpoint( + pindexPrev, state, chainparams, hash)) { return error("%s: CheckIndexAgainstCheckpoint(): %s", __func__, state.GetRejectReason().c_str()); } @@ -3802,8 +3804,9 @@ } } - LogPrint("prune", "Prune: target=%dMiB actual=%dMiB diff=%dMiB " - "max_prune_height=%d removed %d blk/rev pairs\n", + LogPrint("prune", + "Prune: target=%dMiB actual=%dMiB diff=%dMiB " + "max_prune_height=%d removed %d blk/rev pairs\n", nPruneTarget / 1024 / 1024, nCurrentUsage / 1024 / 1024, ((int64_t)nPruneTarget - (int64_t)nCurrentUsage) / 1024 / 1024, nLastBlockWeCanPrune, count); diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -83,155 +83,157 @@ empty_wallet(); // with an empty wallet we can't even pay one cent - BOOST_CHECK(!wallet.SelectCoinsMinConf(1 * CENT, 1, 6, 0, vCoins, - setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(1 * CENT.GetSatoshis(), 1, 6, 0, + vCoins, setCoinsRet, nValueRet)); - add_coin(1 * CENT, 4); // add a new 1 cent coin + add_coin(1 * CENT.GetSatoshis(), 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, 1, 6, 0, vCoins, - setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(1 * CENT.GetSatoshis(), 1, 6, 0, + vCoins, setCoinsRet, nValueRet)); // but we can find a new 1 cent - BOOST_CHECK(wallet.SelectCoinsMinConf(1 * CENT, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1 * CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(1 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1 * CENT.GetSatoshis()); - add_coin(2 * CENT); // add a mature 2 cent coin + add_coin(2 * CENT.GetSatoshis()); // add a mature 2 cent coin // we can't make 3 cents of mature coins - BOOST_CHECK(!wallet.SelectCoinsMinConf(3 * CENT, 1, 6, 0, vCoins, - setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(3 * CENT.GetSatoshis(), 1, 6, 0, + vCoins, setCoinsRet, nValueRet)); // we can make 3 cents of new coins - BOOST_CHECK(wallet.SelectCoinsMinConf(3 * CENT, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 3 * CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(3 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 3 * CENT.GetSatoshis()); // 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 - add_coin(10 * CENT, 3, true); + add_coin(10 * CENT.GetSatoshis(), 3, true); // 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: // 2+5+20=27. total = 38 // we can't make 38 cents only if we disallow new coins: - BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT, 1, 6, 0, vCoins, - setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT.GetSatoshis(), 1, 6, 0, + vCoins, setCoinsRet, nValueRet)); // 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, 6, 6, 0, vCoins, - setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(38 * CENT.GetSatoshis(), 6, 6, 0, + vCoins, setCoinsRet, nValueRet)); // but we can make 37 cents if we accept new coins from ourself - BOOST_CHECK(wallet.SelectCoinsMinConf(37 * CENT, 1, 6, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 37 * CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(37 * CENT.GetSatoshis(), 1, 6, 0, + vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 37 * CENT.GetSatoshis()); // and we can make 38 cents if we accept all new coins - BOOST_CHECK(wallet.SelectCoinsMinConf(38 * CENT, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 38 * CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(38 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 38 * CENT.GetSatoshis()); // 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, - setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(34 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); // 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 // included (but possible) BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // 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, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 7 * CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(7 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 7 * CENT.GetSatoshis()); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // when we try making 8 cents, the smaller coins (1,2,5) are exactly // enough. - BOOST_CHECK(wallet.SelectCoinsMinConf(8 * CENT, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK(nValueRet == 8 * CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(8 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(nValueRet == 8 * CENT.GetSatoshis()); BOOST_CHECK_EQUAL(setCoinsRet.size(), 3U); // 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, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 10 * CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(9 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 10 * CENT.GetSatoshis()); BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // 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(6 * CENT.GetSatoshis()); + add_coin(7 * CENT.GetSatoshis()); + add_coin(8 * CENT.GetSatoshis()); + add_coin(20 * CENT.GetSatoshis()); // 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 - BOOST_CHECK(wallet.SelectCoinsMinConf(71 * CENT, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(71 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK(!wallet.SelectCoinsMinConf(72 * CENT.GetSatoshis(), 1, 1, 0, + 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, 0, vCoins, - setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); // 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); - add_coin(5 * CENT); // now we have 5+6+7+8+20+30 = 75 cents total + add_coin( + 5 * + CENT.GetSatoshis()); // 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, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); // 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); - add_coin(18 * CENT); // now we have 5+6+7+8+18+20+30 + add_coin(18 * CENT.GetSatoshis()); // 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, 0, vCoins, - setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(16 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); // 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 BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); // now try making 11 cents. we should get 5+6 - BOOST_CHECK(wallet.SelectCoinsMinConf(11 * CENT, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 11 * CENT); + BOOST_CHECK(wallet.SelectCoinsMinConf(11 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 11 * CENT.GetSatoshis()); 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(1 * COIN.GetSatoshis()); + add_coin(2 * COIN.GetSatoshis()); + add_coin(3 * COIN.GetSatoshis()); // now we have 5+6+7+8+18+20+30+100+200+300+400 = 1094 cents - add_coin(4 * COIN); - BOOST_CHECK(wallet.SelectCoinsMinConf(95 * CENT, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); + add_coin(4 * COIN.GetSatoshis()); + BOOST_CHECK(wallet.SelectCoinsMinConf(95 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); // we should get 1 BCC in 1 coin BOOST_CHECK_EQUAL(nValueRet, 1 * COIN); BOOST_CHECK_EQUAL(setCoinsRet.size(), 1U); - BOOST_CHECK(wallet.SelectCoinsMinConf(195 * CENT, 1, 1, 0, vCoins, - setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(195 * CENT.GetSatoshis(), 1, 1, 0, + vCoins, setCoinsRet, nValueRet)); // 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); // empty the wallet and start again, now with fractions of a cent, to @@ -276,13 +278,14 @@ // up with 50k in change empty_wallet(); 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, - setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(500000 * COIN.GetSatoshis(), 1, 1, + 0, vCoins, setCoinsRet, + nValueRet)); // we should get the exact amount - BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN); + BOOST_CHECK_EQUAL(nValueRet, 500000 * COIN.GetSatoshis()); // in ten coins BOOST_CHECK_EQUAL(setCoinsRet.size(), 10U); @@ -337,7 +340,7 @@ BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); // test with many inputs - for (CAmount amt = 1500; amt < COIN; amt *= 10) { + for (CAmount amt = 1500; amt < COIN.GetSatoshis(); amt *= 10) { empty_wallet(); // Create 676 inputs (= (old MAX_STANDARD_TX_SIZE == 100000) / 148 // bytes per input) @@ -363,15 +366,17 @@ { empty_wallet(); 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 // depend on randomness in the stochastic approximation code - BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN, 1, 6, 0, vCoins, - setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN.GetSatoshis(), 1, 6, + 0, vCoins, setCoinsRet, + nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(50 * COIN.GetSatoshis(), 1, 6, + 0, vCoins, setCoinsRet2, + nValueRet)); BOOST_CHECK(!equal_sets(setCoinsRet, setCoinsRet2)); int fails = 0; @@ -379,10 +384,12 @@ // 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, 0, vCoins, - setCoinsRet, nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf(COIN, 1, 6, 0, vCoins, - setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN.GetSatoshis(), 1, 6, + 0, vCoins, setCoinsRet, + nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(COIN.GetSatoshis(), 1, 6, + 0, vCoins, setCoinsRet2, + nValueRet)); if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; } BOOST_CHECK_NE(fails, RANDOM_REPEATS); @@ -390,21 +397,23 @@ // 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.GetSatoshis()); + add_coin(10 * CENT.GetSatoshis()); + add_coin(15 * CENT.GetSatoshis()); + add_coin(20 * CENT.GetSatoshis()); + add_coin(25 * CENT.GetSatoshis()); fails = 0; for (int j = 0; j < RANDOM_REPEATS; j++) { // 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, 0, vCoins, setCoinsRet, nValueRet)); - BOOST_CHECK(wallet.SelectCoinsMinConf( - 90 * CENT, 1, 6, 0, vCoins, setCoinsRet2, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90 * CENT.GetSatoshis(), + 1, 6, 0, vCoins, + setCoinsRet, nValueRet)); + BOOST_CHECK(wallet.SelectCoinsMinConf(90 * CENT.GetSatoshis(), + 1, 6, 0, vCoins, + setCoinsRet2, nValueRet)); if (equal_sets(setCoinsRet, setCoinsRet2)) fails++; } BOOST_CHECK_NE(fails, RANDOM_REPEATS); @@ -423,13 +432,13 @@ // Test vValue sort order 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, - setCoinsRet, nValueRet)); - BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN); + BOOST_CHECK(wallet.SelectCoinsMinConf(1003 * COIN.GetSatoshis(), 1, 6, 0, + vCoins, setCoinsRet, nValueRet)); + BOOST_CHECK_EQUAL(nValueRet, 1003 * COIN.GetSatoshis()); BOOST_CHECK_EQUAL(setCoinsRet.size(), 2U); empty_wallet(); @@ -451,7 +460,8 @@ LOCK(wallet.cs_wallet); wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); 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. @@ -465,7 +475,7 @@ LOCK(wallet.cs_wallet); wallet.AddKeyPubKey(coinbaseKey, coinbaseKey.GetPubKey()); 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 diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -51,7 +51,7 @@ //! minimum recommended increment for BIP 125 replacement txs static const CAmount WALLET_INCREMENTAL_RELAY_FEE = 5000; //! target minimum change amount -static const CAmount MIN_CHANGE = CENT; +static const CAmount MIN_CHANGE = CENT.GetSatoshis(); //! final minimum change amount after paying for fees static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE / 2; //! Default for -spendzeroconfchange