From 64ee0d07d0ed5f75449cf06ca4c577d4ec3b9842 Mon Sep 17 00:00:00 2001 From: Tom Swirly Date: Thu, 10 Apr 2014 19:14:52 -0400 Subject: [PATCH] New Zero struct implements "compare with zero." * Zero lets classes efficiently compare with 0, so you can use constructors like x < zero or y != zero. * New BEAST_CONSTEXPR to handle Windows/C++11 differences regarding the constexpr specifier. --- src/beast/beast/config/CompilerConfig.h | 16 +- .../container/tests/hardened_hash.test.cpp | 8 +- src/beast/beast/utility/Utility.cpp | 1 + src/beast/beast/utility/Zero.h | 140 ++++++++++++++ src/beast/beast/utility/tests/Zero.test.cpp | 136 +++++++++++++ src/beast/tests.sh | 0 src/ripple_app/book/Amount.h | 113 ----------- src/ripple_app/book/Amounts.h | 2 +- src/ripple_app/book/OfferStream.h | 4 +- src/ripple_app/book/tests/Quality.test.cpp | 8 +- src/ripple_app/ledger/LedgerEntrySet.cpp | 16 +- src/ripple_app/misc/NetworkOPs.cpp | 18 +- src/ripple_app/paths/PathRequest.cpp | 4 +- src/ripple_app/paths/PathState.cpp | 4 +- src/ripple_app/paths/Pathfinder.cpp | 10 +- src/ripple_app/paths/RippleCalc.cpp | 91 ++++----- src/ripple_app/rpc/RPCHandler.cpp | 12 +- .../transactors/OfferCreateTransactor.cpp | 110 +++++------ .../transactors/PaymentTransactor.cpp | 16 +- .../transactors/RegularKeySetTransactor.cpp | 2 +- src/ripple_app/transactors/Transactor.cpp | 10 +- .../transactors/TrustSetTransactor.cpp | 40 ++-- src/ripple_basics/ripple_basics.h | 4 + src/ripple_data/protocol/STAmount.cpp | 183 +++++++++--------- src/ripple_data/protocol/STAmountRound.cpp | 6 +- src/ripple_data/protocol/SerializedTypes.h | 62 +++--- 26 files changed, 591 insertions(+), 425 deletions(-) create mode 100644 src/beast/beast/utility/Zero.h create mode 100644 src/beast/beast/utility/tests/Zero.test.cpp mode change 100644 => 100755 src/beast/tests.sh diff --git a/src/beast/beast/config/CompilerConfig.h b/src/beast/beast/config/CompilerConfig.h index 7cdaf733a..1a279e6fe 100644 --- a/src/beast/beast/config/CompilerConfig.h +++ b/src/beast/beast/config/CompilerConfig.h @@ -24,13 +24,8 @@ #ifndef BEAST_CONFIG_COMPILERCONFIG_H_INCLUDED #define BEAST_CONFIG_COMPILERCONFIG_H_INCLUDED -// This file has to work when included in a C source file. - -#ifndef BEAST_CONFIG_PLATFORMCONFIG_H_INCLUDED -#error "PlatformConfig.h must come first!" -#endif - #include +#include "PlatformConfig.h" // This file defines miscellaneous macros for debugging, assertions, etc. @@ -47,6 +42,15 @@ # define BEAST_CDECL #endif +/** This macro fixes C++'s constexpr for VS2012, which doesn't understand it. +*/ +#if BEAST_MSVC +# define BEAST_CONSTEXPR const +#else +# define BEAST_CONSTEXPR constexpr +#endif + + // Debugging and assertion macros #if BEAST_LOG_ASSERTIONS || BEAST_DEBUG diff --git a/src/beast/beast/container/tests/hardened_hash.test.cpp b/src/beast/beast/container/tests/hardened_hash.test.cpp index a225b4994..a3f2d1a2f 100644 --- a/src/beast/beast/container/tests/hardened_hash.test.cpp +++ b/src/beast/beast/container/tests/hardened_hash.test.cpp @@ -17,7 +17,7 @@ */ //============================================================================== -// MODULES: ../../crypto/impl/Sha256.cpp +// MODULES: ../../crypto/impl/Sha256.cpp ../../container/impl/spookyv2.cpp #if BEAST_INCLUDE_BEASTCONFIG #include "../../../BeastConfig.h" @@ -131,7 +131,7 @@ public: static std::size_t const bytes = bits / 8; template - static + static unsigned_integer from_number (Int v) { @@ -167,7 +167,7 @@ public: { for (std::size_t i (0); i < size; ++i) s << - std::hex << + std::hex << std::setfill ('0') << std::setw (2*sizeof(UInt)) << v.m_vec[i] @@ -293,7 +293,7 @@ public: "i=" << std::setw(2) << i << " " << "sha256=0x" << d_ << " " << "hash=0x" << - std::setfill ('0') << + std::setfill ('0') << std::setw (2*sizeof(std::size_t)) << result ; pass(); diff --git a/src/beast/beast/utility/Utility.cpp b/src/beast/beast/utility/Utility.cpp index 45fcdeefc..380e2224d 100644 --- a/src/beast/beast/utility/Utility.cpp +++ b/src/beast/beast/utility/Utility.cpp @@ -31,3 +31,4 @@ #include "tests/bassert.test.cpp" #include "tests/empty_base_optimization.test.cpp" +#include "tests/Zero.test.cpp" diff --git a/src/beast/beast/utility/Zero.h b/src/beast/beast/utility/Zero.h new file mode 100644 index 000000000..6a11f2ee7 --- /dev/null +++ b/src/beast/beast/utility/Zero.h @@ -0,0 +1,140 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2014, Tom Ritchford + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef BEAST_UTILITY_ZERO_H_INCLUDED +#define BEAST_UTILITY_ZERO_H_INCLUDED + +#include "../config/CompilerConfig.h" + +namespace beast { + +/** Zero allows classes to offer efficient comparisons to zero. + + Zero is a struct to allow classes to efficiently compare with zero without + requiring an rvalue construction. + + It's often the case that we have classes which combine a number and a unit. + In such cases, comparisons like t > 0 or t != 0 make sense, but comparisons + like t > 1 or t != 1 do not. + + The class Zero allows such comparisons to be easily made. + + The comparing class T either needs to have a method called signum() which + returns a positive number, 0, or a negative; or there needs to be a signum + function which resolves in the namespace which takes an instance of T and + returns a positive, zero or negative number. + */ + +struct Zero {}; + +namespace { + +static BEAST_CONSTEXPR Zero zero{}; + +} // namespace + +/** The default implementation of signum calls the method on the class. + + Calls to signum must be made from a namespace that does not include + overloads of the function. + */ +template +auto signum(T const& t) -> decltype(t.signum()) { + return t.signum(); +} + +namespace detail { +namespace zero_helper { + +template +auto call_signum (T const& t) -> decltype(signum(t)) { + return signum(t); +} + +} // zero_helper +} // detail + +/** Handle operators where T is on the left side using signum. */ +template +bool operator==(T const& t, Zero) { + return detail::zero_helper::call_signum(t) == 0; +} + +template +bool operator!=(T const& t, Zero) { + return detail::zero_helper::call_signum(t) != 0; +} + +template +bool operator>(T const& t, Zero) { + return detail::zero_helper::call_signum(t) > 0; +} + +template +bool operator>=(T const& t, Zero) { + return detail::zero_helper::call_signum(t) >= 0; +} + +template +bool operator<(T const& t, Zero) { + return detail::zero_helper::call_signum(t) < 0; +} + +template +bool operator<=(T const& t, Zero) { + return detail::zero_helper::call_signum(t) <= 0; +} + + +/** Handle operators where T is on the right side by reversing the operation, + so that T is on the left side. + */ +template +bool operator==(Zero, T const& t) { + return t == zero; +} + +template +bool operator!=(Zero, T const& t) { + return t != zero; +} + +template +bool operator>(Zero, T const& t) { + return t < zero; +} + +template +bool operator>=(Zero, T const& t) { + return t <= zero; +} + +template +bool operator<(Zero, T const& t) { + return t > zero; +} + +template +bool operator<=(Zero, T const& t) { + return t >= zero; +} + +} // beast + +#endif diff --git a/src/beast/beast/utility/tests/Zero.test.cpp b/src/beast/beast/utility/tests/Zero.test.cpp new file mode 100644 index 000000000..07843f8a8 --- /dev/null +++ b/src/beast/beast/utility/tests/Zero.test.cpp @@ -0,0 +1,136 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2014, Nikolaos D. Bougalis + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include "../Zero.h" + +#include "../../unit_test/suite.h" + +namespace beast { + +struct adl_tester {}; + +int signum (adl_tester) { return 0; } + + +namespace detail { + +struct adl_tester2 {}; + +int signum (adl_tester2) { return 0; } + +} // detail + +class Zero_test : public beast::unit_test::suite +{ +private: + struct IntegerWrapper + { + int value; + + IntegerWrapper (int v) + : value (v) + { + } + + int signum() const + { + return value; + } + }; + +public: + void expect_same(bool result, bool correct, char const* message) + { + expect(result == correct, message); + } + + void + test_lhs_zero (IntegerWrapper x) + { + expect_same (x >= zero, x.signum () >= 0, + "lhs greater-than-or-equal-to"); + expect_same (x > zero, x.signum () > 0, + "lhs greater than"); + expect_same (x == zero, x.signum () == 0, + "lhs equal to"); + expect_same (x != zero, x.signum () != 0, + "lhs not equal to"); + expect_same (x < zero, x.signum () < 0, + "lhs less than"); + expect_same (x <= zero, x.signum () <= 0, + "lhs less-than-or-equal-to"); + } + + void + test_lhs_zero () + { + testcase ("lhs zero"); + + test_lhs_zero(-7); + test_lhs_zero(0); + test_lhs_zero(32); + } + + void + test_rhs_zero (IntegerWrapper x) + { + expect_same (zero >= x, 0 >= x.signum (), + "rhs greater-than-or-equal-to"); + expect_same (zero > x, 0 > x.signum (), + "rhs greater than"); + expect_same (zero == x, 0 == x.signum (), + "rhs equal to"); + expect_same (zero != x, 0 != x.signum (), + "rhs not equal to"); + expect_same (zero < x, 0 < x.signum (), + "rhs less than"); + expect_same (zero <= x, 0 <= x.signum (), + "rhs less-than-or-equal-to"); + } + + void + test_rhs_zero () + { + testcase ("rhs zero"); + + test_rhs_zero(-4); + test_rhs_zero(0); + test_rhs_zero(64); + } + + void + test_adl () + { + expect (adl_tester{} == zero, "ADL failure!"); + expect (detail::adl_tester2{} == zero, "ADL failure!"); + } + + void + run() + { + test_lhs_zero (); + test_rhs_zero (); + test_adl (); + } + +}; + +BEAST_DEFINE_TESTSUITE(Zero, types, beast); + +} diff --git a/src/beast/tests.sh b/src/beast/tests.sh old mode 100644 new mode 100755 diff --git a/src/ripple_app/book/Amount.h b/src/ripple_app/book/Amount.h index 5b5bf60be..6976d72bb 100644 --- a/src/ripple_app/book/Amount.h +++ b/src/ripple_app/book/Amount.h @@ -25,119 +25,6 @@ #include "../../beast/beast/utility/noexcept.h" #include "../../beast/beast/cxx14/type_traits.h" // -//------------------------------------------------------------------------------ - -struct Zero -{ - Zero() - { - } -}; - -namespace { -static Zero const zero; -} - -namespace detail { -namespace Zero_helpers { -template -int -get_signum (T const& t) noexcept -{ - return signum(t); -} -} -} - -/** Handle operators where T is on the left side using signum. */ -template - -bool operator==(T const& t, Zero) -{ - return detail::Zero_helpers::get_signum(t) == 0; -} - -template -bool operator!=(T const& t, Zero) -{ - return detail::Zero_helpers::get_signum(t) != 0; -} - -template -bool operator>(T const& t, Zero) -{ - return detail::Zero_helpers::get_signum(t) > 0; -} - -template -bool operator>=(T const& t, Zero) -{ - return detail::Zero_helpers::get_signum(t) >= 0; -} - -template -bool operator<(T const& t, Zero) -{ - return detail::Zero_helpers::get_signum(t) < 0; -} - -template -bool operator<=(T const& t, Zero) -{ - return detail::Zero_helpers::get_signum(t) <= 0; -} - - -/** Handle operators where T is on the right side by reversing the operation, - so that T is on the left side. - */ -template -bool operator==(Zero, T const& t) -{ - return t == zero; -} - -template -bool operator!=(Zero, T const& t) -{ - return t != zero; -} - -template -bool operator>(Zero, T const& t) -{ - return t < zero; -} - -template -bool operator>=(Zero, T const& t) -{ - return t <= zero; -} - -template -bool operator<(Zero, T const& t) -{ - return t > zero; -} - -template -bool operator<=(Zero, T const& t) -{ - return t >= zero; -} - -/** Default implementation calls the method on the class. - Alternatively, signum may be overloaded in the same namespace and found - via argument dependent lookup. -*/ -template -auto signum(T const& t) -> decltype(t.signum()) { - return t.signum(); -} - -//------------------------------------------------------------------------------ - namespace ripple { namespace core { diff --git a/src/ripple_app/book/Amounts.h b/src/ripple_app/book/Amounts.h index 709b337bc..d9a871342 100644 --- a/src/ripple_app/book/Amounts.h +++ b/src/ripple_app/book/Amounts.h @@ -39,7 +39,7 @@ struct Amounts bool empty() const noexcept { - return ! in.isPositive() || ! out.isPositive(); + return in <= zero || out <= zero; } Amount in; diff --git a/src/ripple_app/book/OfferStream.h b/src/ripple_app/book/OfferStream.h index a75f22b3e..98a1a19de 100644 --- a/src/ripple_app/book/OfferStream.h +++ b/src/ripple_app/book/OfferStream.h @@ -212,7 +212,7 @@ dir() const noexcept m_offer.account(), m_offer.amount().out)); // Check for unfunded offer - if (! owner_funds.isPositive()) + if (owner_funds <= zero) { // If the owner's balance in the pristine view is the same, // we haven't modified the balance and therefore the @@ -270,7 +270,7 @@ dir() const noexcept //------------------------------------------------------------------------------ -/** +/** Does everything an OfferStream does, and: - remove offers that became unfunded (if path is used) */ diff --git a/src/ripple_app/book/tests/Quality.test.cpp b/src/ripple_app/book/tests/Quality.test.cpp index 18b2bc398..8f9c473c4 100644 --- a/src/ripple_app/book/tests/Quality.test.cpp +++ b/src/ripple_app/book/tests/Quality.test.cpp @@ -101,7 +101,7 @@ public: 1, // limit: 1 1, 1); // 1 in, 1 out - ceil_in (q, + ceil_in (q, 10, 10, // 10 in, 10 out 5, // limit: 5 5, 5); // 5 in, 5 out @@ -162,12 +162,12 @@ public: // 1 in, 1 out: Quality q (Amounts (amount(1),amount(1))); - ceil_out (q, + ceil_out (q, 1, 1, // 1 in, 1 out 1, // limit 1 1, 1); // 1 in, 1 out - ceil_out (q, + ceil_out (q, 10, 10, // 10 in, 10 out 5, // limit 5 5, 5); // 5 in, 5 out @@ -230,7 +230,7 @@ public: Amount const limit ( raw (4131113916555555, -16)); // .4131113916555555 Amounts const result (q.ceil_out (value, limit)); - expect (! result.in.isZero()); + expect (result.in != zero); } } diff --git a/src/ripple_app/ledger/LedgerEntrySet.cpp b/src/ripple_app/ledger/LedgerEntrySet.cpp index 262622996..4af517d43 100644 --- a/src/ripple_app/ledger/LedgerEntrySet.cpp +++ b/src/ripple_app/ledger/LedgerEntrySet.cpp @@ -215,7 +215,7 @@ void LedgerEntrySet::entryModify (SLE::ref sle) { case taaCACHED: it->second.mAction = taaMODIFY; - + // Fall through case taaCREATE: @@ -1116,7 +1116,7 @@ STAmount LedgerEntrySet::rippleOwed (const uint160& uToAccountID, const uint160& } else { - saBalance.zero (uCurrencyID, uToAccountID); + saBalance.clear (uCurrencyID, uToAccountID); WriteLog (lsDEBUG, LedgerEntrySet) << "rippleOwed: No credit line between " << RippleAddress::createHumanAccountID (uFromAccountID) @@ -1149,7 +1149,7 @@ STAmount LedgerEntrySet::rippleLimit (const uint160& uToAccountID, const uint160 } else { - saLimit.zero (uCurrencyID, uToAccountID); + saLimit.clear (uCurrencyID, uToAccountID); #if 0 // We could cut off coming here if we test for no line sooner. assert (false); @@ -1244,7 +1244,7 @@ STAmount LedgerEntrySet::rippleHolds (const uint160& uAccountID, const uint160& if (!sleRippleState) { - saBalance.zero (uCurrencyID, uIssuerID); + saBalance.clear (uCurrencyID, uIssuerID); } else if (uAccountID > uIssuerID) { @@ -1279,7 +1279,7 @@ STAmount LedgerEntrySet::accountHolds (const uint160& uAccountID, const uint160& if (saBalance < uReserve) { - saAmount.zero (); + saAmount.clear (); } else { @@ -1525,8 +1525,8 @@ TER LedgerEntrySet::rippleCredit (const uint160& uSenderID, const uint160& uRece std::uint32_t uFlags; // YYY Could skip this if rippling in reverse. - if (saBefore.isPositive () // Sender balance was positive. - && !saBalance.isPositive () // Sender is zero or negative. + if (saBefore > zero // Sender balance was positive. + && saBalance <= zero // Sender is zero or negative. && isSetBit ((uFlags = sleRippleState->getFieldU32 (sfFlags)), !bSenderHigh ? lsfLowReserve : lsfHighReserve) // Sender reserve is set. && !isSetBit (uFlags, !bSenderHigh ? lsfLowNoRipple : lsfHighNoRipple) && !sleRippleState->getFieldAmount (!bSenderHigh ? sfLowLimit : sfHighLimit) // Sender trust limit is 0. @@ -1617,7 +1617,7 @@ TER LedgerEntrySet::accountSend (const uint160& uSenderID, const uint160& uRecei { TER terResult = tesSUCCESS; - assert (!saAmount.isNegative ()); + assert (saAmount >= zero); if (!saAmount || (uSenderID == uReceiverID)) { diff --git a/src/ripple_app/misc/NetworkOPs.cpp b/src/ripple_app/misc/NetworkOPs.cpp index 1bb0bcea2..6280c32d4 100644 --- a/src/ripple_app/misc/NetworkOPs.cpp +++ b/src/ripple_app/misc/NetworkOPs.cpp @@ -258,7 +258,7 @@ public: Not called for stand-alone mode. */ void setStateTimer (); - + void newLCL (int proposers, int convergeTime, uint256 const& ledgerHash); void needNetworkLedger () { @@ -324,7 +324,7 @@ public: void storeProposal (LedgerProposal::ref proposal, const RippleAddress& peerPublic); uint256 getConsensusLCL (); void reportFeeChange (); - + void updateLocalTx (Ledger::ref newValidLedger) override { m_localTX->sweep (newValidLedger); @@ -408,7 +408,7 @@ public: //-------------------------------------------------------------------------- // // Stoppable - + void onStop () { m_heartbeatTimer.cancel(); @@ -891,7 +891,7 @@ void NetworkOPsImp::runTransactionQueue () tx.set_receivetimestamp (getNetworkTimeNC ()); // FIXME: This should be when we received it getApp ().getPeers ().foreach (send_if_not ( boost::make_shared (tx, protocol::mtTRANSACTION), - peer_in_set(peers))); + peer_in_set(peers))); } else m_journal.debug << "recently relayed"; @@ -1022,7 +1022,7 @@ Transaction::pointer NetworkOPsImp::processTransactionCb ( tx.set_receivetimestamp (getNetworkTimeNC ()); // FIXME: This should be when we received it getApp ().getPeers ().foreach (send_if_not ( boost::make_shared (tx, protocol::mtTRANSACTION), - peer_in_set(peers))); + peer_in_set(peers))); } } } @@ -1459,7 +1459,7 @@ int NetworkOPsImp::beginConsensus (uint256 const& networkClosed, Ledger::pointer // Create a consensus object to get consensus on this ledger assert (!mConsensus); prevLedger->setImmutable (); - + mConsensus = LedgerConsensus::New (m_clock, *m_localTX, networkClosed, prevLedger, m_ledgerMaster.getCurrentLedger ()->getCloseTimeNC ()); @@ -2927,11 +2927,11 @@ void NetworkOPsImp::getBookPage (Ledger::pointer lpLedger, const uint160& uTaker saOwnerFunds = lesActive.accountHolds (uOfferOwnerID, uTakerGetsCurrencyID, uTakerGetsIssuerID); // m_journal.info << boost::str(boost::format("getBookPage: saOwnerFunds=%s (new)") % saOwnerFunds.getFullText()); - if (saOwnerFunds.isNegative ()) + if (saOwnerFunds < zero) { // Treat negative funds as zero. - saOwnerFunds.zero (); + saOwnerFunds.clear (); } } } @@ -2985,7 +2985,7 @@ void NetworkOPsImp::getBookPage (Ledger::pointer lpLedger, const uint160& uTaker umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays; - if (!saOwnerFunds.isZero () || uOfferOwnerID == uTakerID) + if (saOwnerFunds != zero || uOfferOwnerID == uTakerID) { // Only provide funded offers and offers of the taker. Json::Value& jvOf = jvOffers.append (jvOffer); diff --git a/src/ripple_app/paths/PathRequest.cpp b/src/ripple_app/paths/PathRequest.cpp index 811a12d6d..73d98d31e 100644 --- a/src/ripple_app/paths/PathRequest.cpp +++ b/src/ripple_app/paths/PathRequest.cpp @@ -114,7 +114,7 @@ bool PathRequest::needsUpdate (bool newOnly, LedgerIndex index) bool PathRequest::isValid (RippleLineCache::ref crCache) { ScopedLockType sl (mLock); - bValid = raSrcAccount.isSet () && raDstAccount.isSet () && saDstAmount.isPositive (); + bValid = raSrcAccount.isSet () && raDstAccount.isSet () && saDstAmount > zero; Ledger::pointer lrLedger = crCache->getLedger (); if (bValid) @@ -246,7 +246,7 @@ int PathRequest::parseJson (const Json::Value& jvParams, bool complete) if (!saDstAmount.bSetJson (jvParams["destination_amount"]) || (saDstAmount.getCurrency ().isZero () && saDstAmount.getIssuer ().isNonZero ()) || (saDstAmount.getCurrency () == CURRENCY_BAD) || - !saDstAmount.isPositive ()) + saDstAmount <= zero) { jvStatus = rpcError (rpcDST_AMT_MALFORMED); return PFR_PJ_INVALID; diff --git a/src/ripple_app/paths/PathState.cpp b/src/ripple_app/paths/PathState.cpp index e73a7ee97..57313d3a8 100644 --- a/src/ripple_app/paths/PathState.cpp +++ b/src/ripple_app/paths/PathState.cpp @@ -307,7 +307,7 @@ TER PathState::pushNode ( } else if ((isSetBit (sleBck->getFieldU32 (sfFlags), lsfRequireAuth) && !isSetBit (sleRippleState->getFieldU32 (sfFlags), (bHigh ? lsfHighAuth : lsfLowAuth))) - && sleRippleState->getFieldAmount(sfBalance).isZero()) // CHECKME + && sleRippleState->getFieldAmount(sfBalance) == zero) // CHECKME { WriteLog (lsWARNING, RippleCalc) << "pushNode: delay: can't receive IOUs from issuer without auth."; @@ -319,7 +319,7 @@ TER PathState::pushNode ( STAmount saOwed = lesEntries.rippleOwed (pnCur.uAccountID, pnBck.uAccountID, pnCur.uCurrencyID); STAmount saLimit; - if (!saOwed.isPositive () + if (saOwed <= zero && -saOwed >= (saLimit = lesEntries.rippleLimit (pnCur.uAccountID, pnBck.uAccountID, pnCur.uCurrencyID))) { WriteLog (lsWARNING, RippleCalc) << boost::str (boost::format ("pushNode: dry: saOwed=%s saLimit=%s") diff --git a/src/ripple_app/paths/Pathfinder.cpp b/src/ripple_app/paths/Pathfinder.cpp index 61b2e7eef..e71790403 100644 --- a/src/ripple_app/paths/Pathfinder.cpp +++ b/src/ripple_app/paths/Pathfinder.cpp @@ -104,7 +104,7 @@ Pathfinder::Pathfinder (RippleLineCache::ref cache, mLedger (cache->getLedger ()), mRLCache (cache) { - if (((mSrcAccountID == mDstAccountID) && (mSrcCurrencyID == mDstAmount.getCurrency ())) || mDstAmount.isZero ()) + if ((mSrcAccountID == mDstAccountID && mSrcCurrencyID == mDstAmount.getCurrency ()) || mDstAmount == zero) { // no need to send to same account with same currency, must send non-zero bValid = false; @@ -373,7 +373,7 @@ STPathSet Pathfinder::filterPaths(int iMaxPaths, STPath& extraPath) WriteLog (lsDEBUG, Pathfinder) << "Skipping a non-filling path: " << mCompletePaths[lqt.get<3> ()].getJson (0); } - if (remaining.isPositive ()) + if (remaining > zero) { WriteLog (lsINFO, Pathfinder) << "Paths could not send " << remaining << " of " << mDstAmount; } @@ -409,7 +409,7 @@ boost::unordered_set usAccountSourceCurrencies ( const STAmount& saBalance = rspEntry->getBalance (); // Filter out non - if (saBalance.isPositive () // Have IOUs to send. + if (saBalance > zero // Have IOUs to send. || (rspEntry->getLimitPeer () // Peer extends credit. && ((-saBalance) < rspEntry->getLimitPeer ()))) // Credit left. { @@ -489,7 +489,7 @@ int Pathfinder::getPathsOut (RippleCurrency const& currencyID, const uint160& ac if (currencyID != rspEntry->getLimit ().getCurrency ()) nothing (); - else if (!rspEntry->getBalance ().isPositive () && + else if (rspEntry->getBalance () <= zero && (!rspEntry->getLimitPeer () || -rspEntry->getBalance () >= rspEntry->getLimitPeer () || (bAuthRequired && !rspEntry->getAuth ()))) @@ -657,7 +657,7 @@ void Pathfinder::addLink( if ((uEndCurrency == rspEntry.getLimit().getCurrency()) && !currentPath.hasSeen(acctID, uEndCurrency, acctID)) { // path is for correct currency and has not been seen - if (!rspEntry.getBalance().isPositive() + if (rspEntry.getBalance() <= zero && (!rspEntry.getLimitPeer() || -rspEntry.getBalance() >= rspEntry.getLimitPeer() || (bRequireAuth && !rspEntry.getAuth()))) diff --git a/src/ripple_app/paths/RippleCalc.cpp b/src/ripple_app/paths/RippleCalc.cpp index 4078a707d..ff557fbe3 100644 --- a/src/ripple_app/paths/RippleCalc.cpp +++ b/src/ripple_app/paths/RippleCalc.cpp @@ -29,7 +29,7 @@ namespace ripple { SETUP_LOG (RippleCalc) // VFALCO TODO Update the comment for this function, the argument list no -// resembles the comment +// resembles the comment // // Provide a better explanation for what this function does. @@ -226,7 +226,7 @@ TER RippleCalc::calcNodeAdvance ( musUnfundedFound.insert(uOfferIndex); continue; } - else if (!saTakerPays.isPositive () || !saTakerGets.isPositive ()) + else if (saTakerPays <= zero || saTakerGets <= zero) { // Offer has bad amounts. Offers should never have a bad amounts. @@ -301,7 +301,7 @@ TER RippleCalc::calcNodeAdvance ( saOfferFunds = lesActive.accountFunds (uOfrOwnerID, saTakerGets); // Funds held. - if (!saOfferFunds.isPositive ()) + if (saOfferFunds <= zero) { // Offer is unfunded. WriteLog (lsTRACE, RippleCalc) << "calcNodeAdvance: unfunded offer"; @@ -388,7 +388,7 @@ TER RippleCalc::calcNodeDeliverRev ( bDirectRestart = true; // Restart at same quality. // YYY Note this gets zeroed on each increment, ideally only on first increment, then it could be a limit on the forward pass. - saOutAct.zero (saOutReq); + saOutAct.clear (saOutReq); WriteLog (lsTRACE, RippleCalc) << boost::str (boost::format ("calcNodeDeliverRev> saOutAct=%s saOutReq=%s saPrvDlvReq=%s") % saOutAct @@ -421,7 +421,8 @@ TER RippleCalc::calcNodeDeliverRev ( STAmount& saTakerGets = pnCur.saTakerGets; STAmount& saRateMax = pnCur.saRateMax; - terResult = calcNodeAdvance (uNode, psCur, bMultiQuality || saOutAct.isZero(), true); // If needed, advance to next funded offer. + terResult = calcNodeAdvance (uNode, psCur, bMultiQuality || saOutAct == zero, true); + // If needed, advance to next funded offer. if (tesSUCCESS != terResult || !uOfferIndex) { @@ -595,7 +596,7 @@ TER RippleCalc::calcNodeDeliverRev ( STAmount saTakerGetsNew = saTakerGets - saOutPassAct; STAmount saTakerPaysNew = saTakerPays - saInPassAct; - if (saTakerPaysNew.isNegative () || saTakerGetsNew.isNegative ()) + if (saTakerPaysNew < zero || saTakerGetsNew < zero) { WriteLog (lsWARNING, RippleCalc) << boost::str (boost::format ("calcNodeDeliverRev: NEGATIVE: saTakerPaysNew=%s saTakerGetsNew=%s") % saTakerPaysNew % saTakerGetsNew); @@ -683,8 +684,8 @@ TER RippleCalc::calcNodeDeliverFwd ( else bDirectRestart = true; // Restart at same quality. - saInAct.zero (saInReq); - saInFees.zero (saInReq); + saInAct.clear (saInReq); + saInFees.clear (saInReq); int loopCount = 0; @@ -700,7 +701,8 @@ TER RippleCalc::calcNodeDeliverFwd ( } // Determine values for pass to adjust saInAct, saInFees, and saCurDeliverAct - terResult = calcNodeAdvance (uNode, psCur, bMultiQuality || saInAct.isZero(), false); // If needed, advance to next funded offer. + terResult = calcNodeAdvance (uNode, psCur, bMultiQuality || saInAct == zero, false); + // If needed, advance to next funded offer. if (tesSUCCESS != terResult) { @@ -738,8 +740,8 @@ TER RippleCalc::calcNodeDeliverFwd ( STAmount saInTotal = STAmount::mulRound (saInFunded, saInFeeRate, true); // Offer maximum in with fees. STAmount saInRemaining = saInReq - saInAct - saInFees; - if (saInRemaining.isNegative()) - saInRemaining.zero(); + if (saInRemaining < zero) + saInRemaining.clear(); STAmount saInSum = std::min (saInTotal, saInRemaining); // In limited by remaining. STAmount saInPassAct = std::min (saTakerPays, STAmount::divRound (saInSum, saInFeeRate, true)); // In without fees. @@ -766,7 +768,7 @@ TER RippleCalc::calcNodeDeliverFwd ( % saInPassAct % saOutPassMax); - if (!saTakerPays || !saInSum.isPositive()) // FIXME: We remove an offer if WE didn't want anything out of it? + if (!saTakerPays || saInSum <= zero) // FIXME: We remove an offer if WE didn't want anything out of it? { WriteLog (lsDEBUG, RippleCalc) << "calcNodeDeliverFwd: Microscopic offer unfunded."; @@ -883,7 +885,7 @@ TER RippleCalc::calcNodeDeliverFwd ( STAmount saTakerGetsNew = saTakerGets - saOutPassAct; STAmount saTakerPaysNew = saTakerPays - saInPassAct; - if (saTakerPaysNew.isNegative () || saTakerGetsNew.isNegative ()) + if (saTakerPaysNew < zero || saTakerGetsNew < zero) { WriteLog (lsWARNING, RippleCalc) << boost::str (boost::format ("calcNodeDeliverFwd: NEGATIVE: saTakerPaysNew=%s saTakerGetsNew=%s") % saTakerPaysNew % saTakerGetsNew); @@ -899,7 +901,7 @@ TER RippleCalc::calcNodeDeliverFwd ( lesActive.entryModify (sleOffer); - if ((saOutPassAct == saOutFunded) || saTakerGetsNew.isZero()) + if (saOutPassAct == saOutFunded || saTakerGetsNew == zero) { // Offer became unfunded. @@ -1046,12 +1048,12 @@ void RippleCalc::calcNodeRipple ( % saPrvAct % saCurAct); - assert (saCurReq.isPositive ()); // FIXME: saCurReq was zero + assert (saCurReq > zero); // FIXME: saCurReq was zero assert (saPrvReq.getCurrency () == saCurReq.getCurrency ()); assert (saPrvReq.getCurrency () == saPrvAct.getCurrency ()); assert (saPrvReq.getIssuer () == saPrvAct.getIssuer ()); - const bool bPrvUnlimited = saPrvReq.isNegative (); + const bool bPrvUnlimited = saPrvReq < zero; const STAmount saPrv = bPrvUnlimited ? STAmount (saPrvReq) : saPrvReq - saPrvAct; const STAmount saCur = saCurReq - saCurAct; @@ -1187,11 +1189,11 @@ TER RippleCalc::calcNodeAccountRev (const unsigned int uNode, PathState& psCur, % saPrvLimit); // Previous can redeem the owed IOUs it holds. - const STAmount saPrvRedeemReq = saPrvOwed.isPositive () ? saPrvOwed : STAmount (saPrvOwed.getCurrency (), saPrvOwed.getIssuer ()); + const STAmount saPrvRedeemReq = (saPrvOwed > zero) ? saPrvOwed : STAmount (saPrvOwed.getCurrency (), saPrvOwed.getIssuer ()); STAmount& saPrvRedeemAct = pnPrv.saRevRedeem; // Previous can issue up to limit minus whatever portion of limit already used (not including redeemable amount). - const STAmount saPrvIssueReq = saPrvOwed.isNegative () ? saPrvLimit + saPrvOwed : saPrvLimit; + const STAmount saPrvIssueReq = (saPrvOwed < zero) ? saPrvLimit + saPrvOwed : saPrvLimit; STAmount& saPrvIssueAct = pnPrv.saRevIssue; // For !bPrvAccount @@ -1222,7 +1224,7 @@ TER RippleCalc::calcNodeAccountRev (const unsigned int uNode, PathState& psCur, assert (!saCurRedeemReq || (-saNxtOwed) >= saCurRedeemReq); // Current redeem req can't be more than IOUs on hand. assert (!saCurIssueReq // If not issuing, fine. - || !saNxtOwed.isNegative () // saNxtOwed >= 0: Sender not holding next IOUs, saNxtOwed < 0: Sender holding next IOUs. + || saNxtOwed >= zero // saNxtOwed >= 0: Sender not holding next IOUs, saNxtOwed < 0: Sender holding next IOUs. || -saNxtOwed == saCurRedeemReq); // If issue req, then redeem req must consume all owed. if (!uNode) @@ -1262,11 +1264,11 @@ TER RippleCalc::calcNodeAccountRev (const unsigned int uNode, PathState& psCur, } else { - saPrvRedeemAct.zero (saPrvRedeemReq); + saPrvRedeemAct.clear (saPrvRedeemReq); } // Calculate issuing. - saPrvIssueAct.zero (saPrvIssueReq); + saPrvIssueAct.clear (saPrvIssueReq); if (saCurWantedReq != saCurWantedAct // Need more. && saPrvIssueReq) // Will accept IOUs from prevous. @@ -1290,8 +1292,8 @@ TER RippleCalc::calcNodeAccountRev (const unsigned int uNode, PathState& psCur, else { // ^|account --> ACCOUNT --> account - saPrvRedeemAct.zero (saPrvRedeemReq); - saPrvIssueAct.zero (saPrvIssueReq); + saPrvRedeemAct.clear (saPrvRedeemReq); + saPrvIssueAct.clear (saPrvIssueReq); // redeem (part 1) -> redeem if (saCurRedeemReq // Next wants IOUs redeemed. @@ -1364,12 +1366,12 @@ TER RippleCalc::calcNodeAccountRev (const unsigned int uNode, PathState& psCur, // Note: deliver is always issue as ACCOUNT is the issuer for the offer input. WriteLog (lsTRACE, RippleCalc) << boost::str (boost::format ("calcNodeAccountRev: account --> ACCOUNT --> offer")); - saPrvRedeemAct.zero (saPrvRedeemReq); - saPrvIssueAct.zero (saPrvIssueReq); + saPrvRedeemAct.clear (saPrvRedeemReq); + saPrvIssueAct.clear (saPrvIssueReq); // redeem -> deliver/issue. - if (saPrvOwed.isPositive () // Previous has IOUs to redeem. - && saCurDeliverReq) // Need some issued. + if (saPrvOwed > zero // Previous has IOUs to redeem. + && saCurDeliverReq) // Need some issued. { // Rate : 1.0 : transfer_rate calcNodeRipple (QUALITY_ONE, lesActive.rippleTransferRate (uCurAccountID), saPrvRedeemReq, saCurDeliverReq, saPrvRedeemAct, saCurDeliverAct, uRateMax); @@ -1407,14 +1409,15 @@ TER RippleCalc::calcNodeAccountRev (const unsigned int uNode, PathState& psCur, % psCur.saOutAct % psCur.saOutReq); - if (!saCurWantedReq.isPositive ()) + if (saCurWantedReq <= zero) { // TEMPORARY emergency fix WriteLog (lsFATAL, RippleCalc) << "CurWantReq was not positive"; return tefEXCEPTION; } - assert (saCurWantedReq.isPositive ()); // FIXME: We got one of these + assert (saCurWantedReq > zero); // FIXME: We got one of these + // TR notes: can only be a race condition if true! // Rate: quality in : 1.0 calcNodeRipple (uQualityIn, QUALITY_ONE, saPrvDeliverReq, saCurWantedReq, saPrvDeliverAct, saCurWantedAct, uRateMax); @@ -1576,7 +1579,7 @@ TER RippleCalc::calcNodeAccountFwd ( saCurRedeemAct = saCurRedeemReq; - if (!psCur.saInReq.isNegative ()) + if (psCur.saInReq >= zero) { // Limit by send max. saCurRedeemAct = std::min (saCurRedeemAct, psCur.saInReq - psCur.saInAct); @@ -1588,7 +1591,7 @@ TER RippleCalc::calcNodeAccountFwd ( ? saCurIssueReq : STAmount (saCurIssueReq); - if (!!saCurIssueAct && !psCur.saInReq.isNegative ()) + if (!!saCurIssueAct && psCur.saInReq >= zero) { // Limit by send max. saCurIssueAct = std::min (saCurIssueAct, psCur.saInReq - psCur.saInAct - saCurRedeemAct); @@ -1640,8 +1643,8 @@ TER RippleCalc::calcNodeAccountFwd ( // account --> ACCOUNT --> account WriteLog (lsTRACE, RippleCalc) << boost::str (boost::format ("calcNodeAccountFwd: account --> ACCOUNT --> account")); - saCurRedeemAct.zero (saCurRedeemReq); - saCurIssueAct.zero (saCurIssueReq); + saCurRedeemAct.clear (saCurRedeemReq); + saCurIssueAct.clear (saCurIssueReq); // Previous redeem part 1: redeem -> redeem if (saPrvRedeemReq && saCurRedeemReq) // Previous wants to redeem. @@ -1696,7 +1699,7 @@ TER RippleCalc::calcNodeAccountFwd ( // Non-XRP, current node is the issuer. WriteLog (lsTRACE, RippleCalc) << boost::str (boost::format ("calcNodeAccountFwd: account --> ACCOUNT --> offer")); - saCurDeliverAct.zero (saCurDeliverReq); + saCurDeliverAct.clear (saCurDeliverReq); // redeem -> issue/deliver. // Previous wants to redeem. @@ -1727,7 +1730,7 @@ TER RippleCalc::calcNodeAccountFwd ( saCurDeliverAct = saCurDeliverReq; // If limited, then limit by send max and available. - if (!psCur.saInReq.isNegative ()) + if (psCur.saInReq >= zero) { // Limit by send max. saCurDeliverAct = std::min (saCurDeliverAct, psCur.saInReq - psCur.saInAct); @@ -1784,8 +1787,8 @@ TER RippleCalc::calcNodeAccountFwd ( // offer --> ACCOUNT --> account WriteLog (lsTRACE, RippleCalc) << boost::str (boost::format ("calcNodeAccountFwd: offer --> ACCOUNT --> account")); - saCurRedeemAct.zero (saCurRedeemReq); - saCurIssueAct.zero (saCurIssueReq); + saCurRedeemAct.clear (saCurRedeemReq); + saCurIssueAct.clear (saCurIssueReq); // deliver -> redeem if (saPrvDeliverReq && saCurRedeemReq) // Previous wants to deliver and can current redeem. @@ -1817,7 +1820,7 @@ TER RippleCalc::calcNodeAccountFwd ( // deliver/redeem -> deliver/issue. WriteLog (lsTRACE, RippleCalc) << boost::str (boost::format ("calcNodeAccountFwd: offer --> ACCOUNT --> offer")); - saCurDeliverAct.zero (saCurDeliverReq); + saCurDeliverAct.clear (saCurDeliverReq); if (saPrvDeliverReq // Previous wants to deliver && saCurIssueReq) // Current wants issue. @@ -1937,10 +1940,10 @@ void RippleCalc::pathNext (PathState::ref psrCur, const bool bMultiQuality, cons { PathState::Node& pnCur = psrCur->vpnNodes[uIndex]; - pnCur.saRevRedeem.zero (); - pnCur.saRevIssue.zero (); - pnCur.saRevDeliver.zero (); - pnCur.saFwdDeliver.zero (); + pnCur.saRevRedeem.clear (); + pnCur.saRevIssue.clear (); + pnCur.saRevDeliver.clear (); + pnCur.saFwdDeliver.clear (); } psrCur->terStatus = calcNodeRev (uLast, *psrCur, bMultiQuality); @@ -2139,12 +2142,12 @@ TER RippleCalc::rippleCalc ( pspCur->saInAct = saMaxAmountAct; // Update to current amount processed. pspCur->saOutAct = saDstAmountAct; - CondLog (pspCur->saInReq.isPositive () && pspCur->saInAct >= pspCur->saInReq, lsWARNING, RippleCalc) + CondLog (pspCur->saInReq > zero && pspCur->saInAct >= pspCur->saInReq, lsWARNING, RippleCalc) << boost::str (boost::format ("rippleCalc: DONE: saInAct=%s saInReq=%s") % pspCur->saInAct % pspCur->saInReq); - assert (pspCur->saInReq.isNegative () || pspCur->saInAct < pspCur->saInReq); // Error if done. + assert (pspCur->saInReq < zero || pspCur->saInAct < pspCur->saInReq); // Error if done. CondLog (pspCur->saOutAct >= pspCur->saOutReq, lsWARNING, RippleCalc) << boost::str (boost::format ("rippleCalc: ALREADY DONE: saOutAct=%s saOutReq=%s") diff --git a/src/ripple_app/rpc/RPCHandler.cpp b/src/ripple_app/rpc/RPCHandler.cpp index 1f34ae0b3..efaa4125a 100644 --- a/src/ripple_app/rpc/RPCHandler.cpp +++ b/src/ripple_app/rpc/RPCHandler.cpp @@ -105,7 +105,7 @@ enum is expressed as a multiplier based on the current ledger's fee schedule. JSON fields - + "Fee" The fee paid by the transaction. Omitted when the client wants the fee filled in. @@ -342,7 +342,7 @@ Json::Value RPCHandler::transactionSign (Json::Value params, if (!bOffline) { - SLE::pointer sleAccountRoot = mNetOps->getSLEi (lSnapshot, + SLE::pointer sleAccountRoot = mNetOps->getSLEi (lSnapshot, Ledger::getAccountRootIndex (raSrcAddressID.getAccountID ())); if (!sleAccountRoot) @@ -474,7 +474,7 @@ Json::Value RPCHandler::transactionSign (Json::Value params, try { // FIXME: For performance, should use asynch interface - tpTrans = mNetOps->submitTransactionSync (tpTrans, + tpTrans = mNetOps->submitTransactionSync (tpTrans, mRole == Config::ADMIN, true, bFailHard, bSubmit); if (!tpTrans) @@ -771,7 +771,7 @@ Json::Value RPCHandler::doAccountCurrencies (Json::Value params, Resource::Charg { recvCurrencies.append (STAmount::createHumanCurrency (c)); } - + return jvResult; } @@ -1520,7 +1520,7 @@ Json::Value RPCHandler::doBookOffers (Json::Value params, Resource::Charge& load { if (! params ["taker"].isString ()) return RPC::expected_field_error ("taker", "string"); - + if (! raTakerID.setAccountID (params ["taker"].asString ())) return RPC::invalid_field_error ("taker"); } @@ -1674,7 +1674,7 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, Resource::Charge& // Parse saDstAmount. !params.isMember ("destination_amount") || !saDstAmount.bSetJson (params["destination_amount"]) - || !saDstAmount.isPositive() + || saDstAmount <= zero || (!!saDstAmount.getCurrency () && (!saDstAmount.getIssuer () || ACCOUNT_ONE == saDstAmount.getIssuer ()))) { WriteLog (lsINFO, RPCHandler) << "Bad destination_amount."; diff --git a/src/ripple_app/transactors/OfferCreateTransactor.cpp b/src/ripple_app/transactors/OfferCreateTransactor.cpp index e9fe4c8c1..bc8e94a01 100644 --- a/src/ripple_app/transactors/OfferCreateTransactor.cpp +++ b/src/ripple_app/transactors/OfferCreateTransactor.cpp @@ -32,7 +32,7 @@ bool OfferCreateTransactor::isValidOffer ( std::unordered_set>& usAccountTouched, STAmount& saOfferFunds) { - if (sleOffer->isFieldPresent (sfExpiration) && + if (sleOffer->isFieldPresent (sfExpiration) && sleOffer->getFieldU32 (sfExpiration) <= mEngine->getLedger ()->getParentCloseTimeNC ()) { // Offer is expired. Expired offers are considered unfunded. Delete it. @@ -42,7 +42,7 @@ bool OfferCreateTransactor::isValidOffer ( return false; } - + if (uOfferOwnerID == uTakerAccountID) { // Would take own offer. Consider old offer expired. Delete it. @@ -52,8 +52,8 @@ bool OfferCreateTransactor::isValidOffer ( return false; } - - if (!saOfferGets.isPositive () || !saOfferPays.isPositive ()) + + if (saOfferGets <= zero || saOfferPays <= zero) { // Offer has bad amounts. Consider offer expired. Delete it. m_journal.warning << "isValidOffer: BAD OFFER:" << @@ -64,13 +64,13 @@ bool OfferCreateTransactor::isValidOffer ( return false; } - + m_journal.trace << "isValidOffer: saOfferPays=" << saOfferPays.getFullText (); saOfferFunds = mEngine->view ().accountFunds (uOfferOwnerID, saOfferPays); - if (!saOfferFunds.isPositive ()) + if (saOfferFunds <= zero) { // Offer is unfunded, possibly due to previous balance action. m_journal.debug << "isValidOffer: offer unfunded: delete"; @@ -107,7 +107,7 @@ bool OfferCreateTransactor::canCross ( bool& isUnfunded, TER& terResult) const { - if (!saTakerFunds.isPositive ()) + if (saTakerFunds <= zero) { // Taker is out of funds. Don't create the offer. isUnfunded = true; @@ -115,7 +115,7 @@ bool OfferCreateTransactor::canCross ( return false; } - if (!saSubTakerPays.isPositive() || !saSubTakerGets.isPositive()) + if (saSubTakerPays <= zero || saSubTakerGets <= zero) { // Offer is completely consumed terResult = tesSUCCESS; @@ -159,11 +159,11 @@ bool OfferCreateTransactor::canCross ( @param saTakerGets Limit for taker to get. @param saTakerPaid Actual amount the taker paid @param saTakerGot Actual amount the taker got - @param saTakerIssuerFee Actual + @param saTakerIssuerFee Actual @param saOfferIssuerFee Actual @note Buy vs. Sell semantics: - + In Ripple, placed offers are always executed at the rate at which they were placed. However, the offer we are processing hasn't been placed yet and it can cross with offers that have. Such crossing offers can be consumed by @@ -174,7 +174,7 @@ bool OfferCreateTransactor::canCross ( are consumed. First, consider the case where a user is trying to place an offer to buy - 1 BTC for 700 USD: + 1 BTC for 700 USD: If an offer to giving 0.5 BTC for 300 USD is on the books, the offers cross and under buy semantics the user buys 0.5 BTC for 300 USD (less than the 350 USD he was willing to pay) and the offer is adjusted and placed on the @@ -201,8 +201,8 @@ bool OfferCreateTransactor::applyOffer ( { saOfferGets.throwComparable (saTakerFunds); - assert (saOfferFunds.isPositive () && saTakerFunds.isPositive ()); // Both must have funds. - assert (saOfferGets.isPositive () && saOfferPays.isPositive ()); // Must not be a null offer. + assert (saOfferFunds > zero && saTakerFunds > zero); // Both must have funds. + assert (saOfferGets > zero && saOfferPays > zero); // Must not be a null offer. // Available = limited by funds. // Limit offerer funds available, by transfer fees. @@ -292,7 +292,7 @@ bool OfferCreateTransactor::applyOffer ( ? saTakerFunds - saTakerPaid // Not enough funds to cover fee, stiff issuer the rounding error. : saTakerCost - saTakerPaid; WriteLog (lsINFO, STAmount) << "applyOffer: saTakerIssuerFee=" << saTakerIssuerFee.getFullText (); - assert (!saTakerIssuerFee.isNegative ()); + assert (saTakerIssuerFee >= zero); } if (uOfferPaysRate == QUALITY_ONE) @@ -314,17 +314,17 @@ bool OfferCreateTransactor::applyOffer ( return saTakerGot >= saOfferPaysAvailable; // True, if consumed offer. } -/** Take as much as possible. +/** Take as much as possible. We adjusts account balances and charges fees on top to taker. @param uBookBase The order book to take against. @param saTakerPays What the taker offers (w/ issuer) @param saTakerGets What the taker wanted (w/ issuer) - @param saTakerPaid What taker could have paid including saved not including + @param saTakerPaid What taker could have paid including saved not including fees. To reduce an offer. @param saTakerGot What taker got not including fees. To reduce an offer. @param bUnfunded if tesSUCCESS, consider offer unfunded after taking. - @return tesSUCCESS, terNO_ACCOUNT, telFAILED_PROCESSING, or + @return tesSUCCESS, terNO_ACCOUNT, telFAILED_PROCESSING, or tecFAILED_PROCESSING */ TER OfferCreateTransactor::takeOffers ( @@ -361,7 +361,7 @@ TER OfferCreateTransactor::takeOffers ( TER terResult = temUNCERTAIN; // Offers that became unfunded. - std::unordered_set> usOfferUnfundedBecame; + std::unordered_set> usOfferUnfundedBecame; // Accounts touched. std::unordered_set> usAccountTouched; @@ -400,8 +400,8 @@ TER OfferCreateTransactor::takeOffers ( "/" << RippleAddress::createHumanAccountID (saTakerPays.getIssuer()) << "' - XRP - '" << - STAmount::createHumanCurrency(saTakerGets.getCurrency ()) << - "/" << + STAmount::createHumanCurrency(saTakerGets.getCurrency ()) << + "/" << RippleAddress::createHumanAccountID (saTakerGets.getIssuer()) << "'"; } @@ -416,27 +416,27 @@ TER OfferCreateTransactor::takeOffers ( std::uint64_t uTipQuality = directBookIter.getCurrentQuality(); #ifdef RIPPLE_AUTOBRIDGE - if (bridgeBookIn && bridgeBookIn->nextOffer() && + if (bridgeBookIn && bridgeBookIn->nextOffer() && bridgeBookOut && bridgeBookOut->nextOffer()) { STAmount bridgeIn = STAmount::setRate (bridgeBookIn->getCurrentQuality()); STAmount bridgeOut = STAmount::setRate (bridgeBookOut->getCurrentQuality()); - m_journal.error << + m_journal.error << "The direct quality is: " << STAmount::setRate (uTipQuality); - m_journal.error << + m_journal.error << "The bridge-to-XRP quality is: " << bridgeIn; - m_journal.error << + m_journal.error << "The bridge-from-XRP quality is: " << bridgeOut; m_journal.error << - "The bridge synthetic quality is: " << + "The bridge synthetic quality is: " << STAmount::multiply (bridgeIn, bridgeOut, CURRENCY_ONE, ACCOUNT_ONE); } #endif - + if (!canCross( saTakerFunds, saSubTakerPays, @@ -461,7 +461,7 @@ TER OfferCreateTransactor::takeOffers ( m_journal.warning << "takeOffers: offer not found : " << offerIndex; usMissingOffers.insert (missingOffer_t ( - directBookIter.getCurrentIndex (), + directBookIter.getCurrentIndex (), directBookIter.getCurrentDirectory ())); continue; @@ -600,12 +600,12 @@ TER OfferCreateTransactor::takeOffers ( // TODO check the synthetic case here (to ensure there // is no corruption) - if (!saOfferPays.isPositive () || !saOfferGets.isPositive ()) + if (saOfferPays <= zero || saOfferGets <= zero) { - m_journal.warning << + m_journal.warning << "takeOffers: ILLEGAL OFFER RESULT."; bUnfunded = true; - terResult = bOpenLedger + terResult = bOpenLedger ? telFAILED_PROCESSING : tecFAILED_PROCESSING; } @@ -757,7 +757,7 @@ TER OfferCreateTransactor::doApply () // FIXME understand why we use SequenceNext instead of current transaction // sequence to determine the transaction. Why is the offer seuqnce // number insufficient? - + std::uint32_t const uAccountSequenceNext = mTxnAccount->getFieldU32 (sfSequence); std::uint32_t const uSequence = mTxn.getSequence (); @@ -811,7 +811,7 @@ TER OfferCreateTransactor::doApply () terResult = temBAD_OFFER; } - else if (!saTakerPays.isPositive () || !saTakerGets.isPositive ()) + else if (saTakerPays <= zero || saTakerGets <= zero) { m_journal.warning << "Malformed offer: bad amount"; @@ -840,7 +840,7 @@ TER OfferCreateTransactor::doApply () terResult = temBAD_ISSUER; } - else if (!lesActive.accountFunds (mTxnAccountID, saTakerGets).isPositive ()) + else if (lesActive.accountFunds (mTxnAccountID, saTakerGets) <= zero) { m_journal.warning << "delay: Offers must be at least partially funded."; @@ -878,7 +878,7 @@ TER OfferCreateTransactor::doApply () // might not even have been an offer - we don't care. if (m_journal.warning) m_journal.warning << - "offer not found: " << + "offer not found: " << RippleAddress::createHumanAccountID (mTxnAccountID) << " : " << uCancelSequence << " : " << uCancelIndex.ToString (); @@ -886,11 +886,11 @@ TER OfferCreateTransactor::doApply () } // We definitely know the time that the parent ledger closed but we do not - // know the closing time of the ledger under construction. + // know the closing time of the ledger under construction. // FIXME: Make sure that expiration is documented in terms of the close time // of the previous ledger. - bool bExpired = - bHaveExpiration && + bool bExpired = + bHaveExpiration && (mEngine->getLedger ()->getParentCloseTimeNC () >= uExpiration); // If all is well and this isn't an offer to XRP, then we make sure we are @@ -911,7 +911,7 @@ TER OfferCreateTransactor::doApply () else if (isSetBit (sleTakerPays->getFieldU32 (sfFlags), lsfRequireAuth)) { SLE::pointer sleRippleState (mEngine->entryCache ( - ltRIPPLE_STATE, + ltRIPPLE_STATE, Ledger::getRippleStateIndex ( mTxnAccountID, uPaysIssuerID, uPaysCurrency))); @@ -923,7 +923,7 @@ TER OfferCreateTransactor::doApply () if (!sleRippleState) { - terResult = isSetBit (mParams, tapRETRY) + terResult = isSetBit (mParams, tapRETRY) ? terNO_LINE : tecNO_LINE; } @@ -986,7 +986,7 @@ TER OfferCreateTransactor::doApply () if (m_journal.debug) { m_journal.debug << - "takeOffers: AFTER saTakerPays=" << + "takeOffers: AFTER saTakerPays=" << saTakerPays.getFullText (); m_journal.debug << "takeOffers: AFTER saTakerGets=" << @@ -1019,11 +1019,11 @@ TER OfferCreateTransactor::doApply () // nothing to do nothing (); } - else if (saTakerPays.isNegative () || saTakerGets.isNegative ()) + else if (saTakerPays < zero || saTakerGets < zero) { // If ledger is not final, can vote no. - // When we are processing an open ledger, failures are local and we charge no fee; - // otherwise we must claim a fee (even if they do nothing else due to an error) + // When we are processing an open ledger, failures are local and we charge no fee; + // otherwise we must claim a fee (even if they do nothing else due to an error) // to prevent a DoS. terResult = bOpenLedger ? telFAILED_PROCESSING : tecFAILED_PROCESSING; } @@ -1033,11 +1033,11 @@ TER OfferCreateTransactor::doApply () lesActive.swapWith (lesCheckpoint); // Restore with just fees paid. } else if ( - !saTakerPays.isPositive() // Wants nothing more. - || !saTakerGets.isPositive() // Offering nothing more. - || bImmediateOrCancel // Do not persist. - || !lesActive.accountFunds (mTxnAccountID, saTakerGets).isPositive () // Not funded. - || bUnfunded) // Consider unfunded. + saTakerPays <= zero // Wants nothing more. + || saTakerGets <= zero // Offering nothing more. + || bImmediateOrCancel // Do not persist. + || lesActive.accountFunds (mTxnAccountID, saTakerGets) <= zero // Not funded. + || bUnfunded) // Consider unfunded. { // Complete as is. nothing (); @@ -1047,7 +1047,7 @@ TER OfferCreateTransactor::doApply () // If we are here, the signing account had an insufficient reserve // *prior* to our processing. We use the prior balance to simplify // client writing and make the user experience better. - + if (bOpenLedger) // Ledger is not final, can vote no. { // Hope for more reserve to come in or more offers to consume. If we @@ -1077,12 +1077,12 @@ TER OfferCreateTransactor::doApply () { // We need to place the remainder of the offer into its order book. if (m_journal.trace) m_journal.trace << - "offer not fully consumed:" << + "offer not fully consumed:" << " saTakerPays=" << saTakerPays.getFullText () << " saTakerGets=" << saTakerGets.getFullText (); // Add offer to owner's directory. - terResult = lesActive.dirAdd (uOwnerNode, + terResult = lesActive.dirAdd (uOwnerNode, Ledger::getOwnerDirIndex (mTxnAccountID), uLedgerIndex, BIND_TYPE (&Ledger::ownerDirDescriber, P_1, P_2, mTxnAccountID)); @@ -1109,7 +1109,7 @@ TER OfferCreateTransactor::doApply () // Add offer to order book. terResult = lesActive.dirAdd (uBookNode, uDirectory, uLedgerIndex, - BIND_TYPE (&Ledger::qualityDirDescriber, P_1, P_2, + BIND_TYPE (&Ledger::qualityDirDescriber, P_1, P_2, saTakerPays.getCurrency (), uPaysIssuerID, saTakerGets.getCurrency (), uGetsIssuerID, uRate)); } @@ -1187,15 +1187,15 @@ TER OfferCreateTransactor::doApply () { SLE::pointer sleDirectory ( lesActive.entryCache (ltDIR_NODE, indexes.second)); - + if (sleDirectory) { STVector256 svIndexes = sleDirectory->getFieldV256 (sfIndexes); std::vector& vuiIndexes = svIndexes.peekValue(); - + auto it = std::find ( vuiIndexes.begin (), vuiIndexes.end (), indexes.first); - + if (it != vuiIndexes.end ()) { vuiIndexes.erase (it); diff --git a/src/ripple_app/transactors/PaymentTransactor.cpp b/src/ripple_app/transactors/PaymentTransactor.cpp index b6628c426..baaaaba99 100644 --- a/src/ripple_app/transactors/PaymentTransactor.cpp +++ b/src/ripple_app/transactors/PaymentTransactor.cpp @@ -38,12 +38,12 @@ TER PaymentTransactor::doApply () mTxnAccountID, saDstAmount.getMantissa (), saDstAmount.getExponent (), - saDstAmount.isNegative ()); + saDstAmount < zero); uint160 const uSrcCurrency = saMaxAmount.getCurrency (); uint160 const uDstCurrency = saDstAmount.getCurrency (); bool const bXRPDirect = uSrcCurrency.isZero () && uDstCurrency.isZero (); - m_journal.trace << + m_journal.trace << "saMaxAmount=" << saMaxAmount.getFullText () << " saDstAmount=" << saDstAmount.getFullText (); @@ -52,7 +52,7 @@ TER PaymentTransactor::doApply () if (uTxFlags & tfPaymentMask) { - m_journal.trace << + m_journal.trace << "Malformed transaction: Invalid flags set."; return temINVALID_FLAG; @@ -64,14 +64,14 @@ TER PaymentTransactor::doApply () return temDST_NEEDED; } - else if (bMax && !saMaxAmount.isPositive ()) + else if (bMax && saMaxAmount <= zero) { m_journal.trace << "Malformed transaction: bad max amount: " << saMaxAmount.getFullText (); return temBAD_AMOUNT; } - else if (!saDstAmount.isPositive ()) + else if (saDstAmount <= zero) { m_journal.trace << "Malformed transaction: bad dst amount: " << saDstAmount.getFullText (); @@ -87,7 +87,7 @@ TER PaymentTransactor::doApply () } else if (mTxnAccountID == uDstAccountID && uSrcCurrency == uDstCurrency && !bPaths) { - m_journal.trace << + m_journal.trace << "Malformed transaction: Redundant transaction:" << " src=" << mTxnAccountID.ToString () << " dst=" << uDstAccountID.ToString () << @@ -159,7 +159,7 @@ TER PaymentTransactor::doApply () // Make retry work smaller, by rejecting this. m_journal.trace << "Delay transaction: Partial payment not allowed to create account."; - + // Another transaction could create the account and then this // transaction would succeed. @@ -282,7 +282,7 @@ TER PaymentTransactor::doApply () if (transResultInfo (terResult, strToken, strHuman)) { - m_journal.trace << + m_journal.trace << strToken << ": " << strHuman; } else diff --git a/src/ripple_app/transactors/RegularKeySetTransactor.cpp b/src/ripple_app/transactors/RegularKeySetTransactor.cpp index 068aec3a9..2e472bcfc 100644 --- a/src/ripple_app/transactors/RegularKeySetTransactor.cpp +++ b/src/ripple_app/transactors/RegularKeySetTransactor.cpp @@ -45,7 +45,7 @@ TER RegularKeySetTransactor::doApply () return temINVALID_FLAG; } - if (mFeeDue.isZero ()) + if (mFeeDue == zero) { mTxnAccount->setFlag (lsfPasswordSpent); } diff --git a/src/ripple_app/transactors/Transactor.cpp b/src/ripple_app/transactors/Transactor.cpp index 238e218c0..ca32b4c1e 100644 --- a/src/ripple_app/transactors/Transactor.cpp +++ b/src/ripple_app/transactors/Transactor.cpp @@ -79,7 +79,7 @@ Transactor::Transactor ( SerializedTransaction const& txn, TransactionEngineParams params, TransactionEngine* engine, - beast::Journal journal) + beast::Journal journal) : mTxn (txn) , mEngine (engine) , mParams (params) @@ -110,13 +110,13 @@ TER Transactor::payFee () // Only check fee is sufficient when the ledger is open. if (isSetBit (mParams, tapOPEN_LEDGER) && saPaid < mFeeDue) { - m_journal.trace << "Insufficient fee paid: " << + m_journal.trace << "Insufficient fee paid: " << saPaid.getText () << "/" << mFeeDue.getText (); return telINSUF_FEE_P; } - if (saPaid.isNegative () || !saPaid.isNative ()) + if (saPaid < zero || !saPaid.isNative ()) return temBAD_FEE; if (!saPaid) return tesSUCCESS; @@ -262,7 +262,7 @@ TER Transactor::apply () // Restructure this to avoid the dependency on LedgerBase::mLock Ledger::ScopedLockType sl (mEngine->getLedger ()->mLock); - mTxnAccount = mEngine->entryCache (ltACCOUNT_ROOT, + mTxnAccount = mEngine->entryCache (ltACCOUNT_ROOT, Ledger::getAccountRootIndex (mTxnAccountID)); calculateFee (); @@ -274,7 +274,7 @@ TER Transactor::apply () { if (mustHaveValidAccount ()) { - m_journal.trace << + m_journal.trace << "apply: delay transaction: source account does not exist " << mTxn.getSourceAccount ().humanAccountID (); return terNO_ACCOUNT; diff --git a/src/ripple_app/transactors/TrustSetTransactor.cpp b/src/ripple_app/transactors/TrustSetTransactor.cpp index d6c8429d9..2b24f0c73 100644 --- a/src/ripple_app/transactors/TrustSetTransactor.cpp +++ b/src/ripple_app/transactors/TrustSetTransactor.cpp @@ -26,7 +26,7 @@ TER TrustSetTransactor::doApply () STAmount const saLimitAmount (mTxn.getFieldAmount (sfLimitAmount)); bool const bQualityIn (mTxn.isFieldPresent (sfQualityIn)); bool const bQualityOut (mTxn.isFieldPresent (sfQualityOut)); - + uint160 const uCurrencyID (saLimitAmount.getCurrency ()); uint160 uDstAccountID (saLimitAmount.getIssuer ()); @@ -60,7 +60,7 @@ TER TrustSetTransactor::doApply () if (bSetAuth && !isSetBit (mTxnAccount->getFieldU32 (sfFlags), lsfRequireAuth)) { - m_journal.trace << + m_journal.trace << "Retry: Auth not required."; return tefNO_AUTH_REQUIRED; } @@ -73,9 +73,9 @@ TER TrustSetTransactor::doApply () return temBAD_LIMIT; } - if (saLimitAmount.isNegative ()) + if (saLimitAmount < zero) { - m_journal.trace << + m_journal.trace << "Malformed transaction: Negative credit limit."; return temBAD_LIMIT; } @@ -83,7 +83,7 @@ TER TrustSetTransactor::doApply () // Check if destination makes sense. if (!uDstAccountID || uDstAccountID == ACCOUNT_ONE) { - m_journal.trace << + m_journal.trace << "Malformed transaction: Destination account not specified."; return temDST_NEEDED; @@ -92,13 +92,13 @@ TER TrustSetTransactor::doApply () if (mTxnAccountID == uDstAccountID) { SLE::pointer selDelete ( - mEngine->entryCache (ltRIPPLE_STATE, + mEngine->entryCache (ltRIPPLE_STATE, Ledger::getRippleStateIndex ( mTxnAccountID, uDstAccountID, uCurrencyID))); - + if (selDelete) { - m_journal.warning << + m_journal.warning << "Clearing redundant line."; return mEngine->view ().trustDelete ( @@ -117,16 +117,16 @@ TER TrustSetTransactor::doApply () if (!sleDst) { - m_journal.trace << + m_journal.trace << "Delay transaction: Destination account does not exist."; return tecNO_DST; } std::uint32_t const uOwnerCount (mTxnAccount->getFieldU32 (sfOwnerCount)); // The reserve required to create the line. - std::uint64_t const uReserveCreate = - (uOwnerCount < 2) - ? 0 + std::uint64_t const uReserveCreate = + (uOwnerCount < 2) + ? 0 : mEngine->getLedger ()->getReserve (uOwnerCount + 1); STAmount saLimitAllow = saLimitAmount; @@ -233,7 +233,7 @@ TER TrustSetTransactor::doApply () std::uint32_t const uFlagsIn (sleRippleState->getFieldU32 (sfFlags)); std::uint32_t uFlagsOut (uFlagsIn); - if (bSetNoRipple && !bClearNoRipple && (bHigh ? saHighBalance : saLowBalance).isGEZero()) + if (bSetNoRipple && !bClearNoRipple && (bHigh ? saHighBalance : saLowBalance) >= zero) { uFlagsOut |= (bHigh ? lsfHighNoRipple : lsfLowNoRipple); } @@ -249,12 +249,12 @@ TER TrustSetTransactor::doApply () bool const bLowReserveSet = uLowQualityIn || uLowQualityOut || isSetBit (uFlagsOut, lsfLowNoRipple) || - !!saLowLimit || saLowBalance.isPositive (); + !!saLowLimit || saLowBalance > zero; bool const bLowReserveClear = !bLowReserveSet; bool const bHighReserveSet = uHighQualityIn || uHighQualityOut || isSetBit (uFlagsOut, lsfHighNoRipple) || - !!saHighLimit || saHighBalance.isPositive (); + !!saHighLimit || saHighBalance > zero; bool const bHighReserveClear = !bHighReserveSet; bool const bDefault = bLowReserveClear && bHighReserveClear; @@ -321,7 +321,7 @@ TER TrustSetTransactor::doApply () { m_journal.trace << "Delay transaction: Insufficent reserve to add trust line."; - + // Another transaction could provide XRP to the account and then // this transaction would succeed. terResult = tecINSUF_RESERVE_LINE; @@ -339,13 +339,13 @@ TER TrustSetTransactor::doApply () && (!bQualityIn || !uQualityIn) // Not setting quality in or setting default quality in. && (!bQualityOut || !uQualityOut)) // Not setting quality out or setting default quality out. { - m_journal.trace << + m_journal.trace << "Redundant: Setting non-existent ripple line to defaults."; return tecNO_LINE_REDUNDANT; } else if (mPriorBalance.getNValue () < uReserveCreate) // Reserve is not scaled by load. { - m_journal.trace << + m_journal.trace << "Delay transaction: Line does not exist. Insufficent reserve to create line."; // Another transaction could create the account and then this transaction would succeed. @@ -358,10 +358,10 @@ TER TrustSetTransactor::doApply () else { // Zero balance in currency. - STAmount saBalance (STAmount (uCurrencyID, ACCOUNT_ONE)); + STAmount saBalance (STAmount (uCurrencyID, ACCOUNT_ONE)); - m_journal.trace << + m_journal.trace << "doTrustSet: Creating ripple line: " << Ledger::getRippleStateIndex (mTxnAccountID, uDstAccountID, uCurrencyID).ToString (); diff --git a/src/ripple_basics/ripple_basics.h b/src/ripple_basics/ripple_basics.h index 76f196e2b..f50a68045 100644 --- a/src/ripple_basics/ripple_basics.h +++ b/src/ripple_basics/ripple_basics.h @@ -27,6 +27,10 @@ #include #include "../../beast/beast/cxx14/memory.h" +#include "../../beast/beast/utility/Zero.h" + +using beast::zero; +using beast::Zero; #ifndef RIPPLE_TRACK_MUTEXES # define RIPPLE_TRACK_MUTEXES 0 diff --git a/src/ripple_data/protocol/STAmount.cpp b/src/ripple_data/protocol/STAmount.cpp index 399aa672c..08ef2cf9a 100644 --- a/src/ripple_data/protocol/STAmount.cpp +++ b/src/ripple_data/protocol/STAmount.cpp @@ -482,7 +482,7 @@ void STAmount::add (Serializer& s) const } else { - if (isZero ()) + if (*this == zero) s.add64 (cNotNative); else if (mIsNegative) // 512 = not native s.add64 (mValue | (static_cast (mOffset + 512 + 97) << (64 - 10))); @@ -625,7 +625,8 @@ std::string STAmount::getRaw () const std::string STAmount::getText () const { // keep full internal accuracy, but make more human friendly if posible - if (isZero ()) return "0"; + if (*this == zero) + return "0"; if (mIsNative) { @@ -821,9 +822,10 @@ STAmount operator+ (const STAmount& v1, const STAmount& v2) { v1.throwComparable (v2); - if (v2.isZero ()) return v1; + if (v2 == zero) + return v1; - if (v1.isZero ()) + if (v1 == zero) { // Result must be in terms of v1 currency and issuer. return STAmount (v1.getFName (), v1.mCurrency, v1.mIssuer, v2.mValue, v2.mOffset, v2.mIsNegative); @@ -867,7 +869,8 @@ STAmount operator- (const STAmount& v1, const STAmount& v2) { v1.throwComparable (v2); - if (v2.isZero ()) return v1; + if (v2 == zero) + return v1; if (v2.mIsNative) { @@ -908,10 +911,10 @@ STAmount operator- (const STAmount& v1, const STAmount& v2) STAmount STAmount::divide (const STAmount& num, const STAmount& den, const uint160& uCurrencyID, const uint160& uIssuerID) { - if (den.isZero ()) + if (den == zero) throw std::runtime_error ("division by zero"); - if (num.isZero ()) + if (num == zero) return STAmount (uCurrencyID, uIssuerID); std::uint64_t numVal = num.mValue, denVal = den.mValue; @@ -951,7 +954,7 @@ STAmount STAmount::divide (const STAmount& num, const STAmount& den, const uint1 STAmount STAmount::multiply (const STAmount& v1, const STAmount& v2, const uint160& uCurrencyID, const uint160& uIssuerID) { - if (v1.isZero () || v2.isZero ()) + if (v1 == zero || v2 == zero) return STAmount (uCurrencyID, uIssuerID); if (v1.mIsNative && v2.mIsNative && uCurrencyID.isZero ()) @@ -1018,14 +1021,14 @@ STAmount STAmount::multiply (const STAmount& v1, const STAmount& v2, const uint1 // Zero is returned if the offer is worthless. std::uint64_t STAmount::getRate (const STAmount& offerOut, const STAmount& offerIn) { - if (offerOut.isZero ()) + if (offerOut == zero) return 0; try { STAmount r = divide (offerIn, offerOut, CURRENCY_ONE, ACCOUNT_ONE); - if (r.isZero ()) // offer is too good + if (r == zero) // offer is too good return 0; assert ((r.getExponent () >= -100) && (r.getExponent () <= 155)); @@ -1055,7 +1058,7 @@ STAmount STAmount::setRate (std::uint64_t rate) STAmount STAmount::getPay (const STAmount& offerOut, const STAmount& offerIn, const STAmount& needed) { // Someone wants to get (needed) out of the offer, how much should they pay in? - if (offerOut.isZero ()) + if (offerOut == zero) return STAmount (offerIn.getCurrency (), offerIn.getIssuer ()); if (needed >= offerOut) @@ -1217,7 +1220,7 @@ public: { pass (); } - + return true; } @@ -1289,127 +1292,127 @@ public: { testcase ("native currency"); - STAmount zero, one (1), hundred (100); + STAmount zeroSt, one (1), hundred (100); - unexpected (serializeAndDeserialize (zero) != zero, "STAmount fail"); + unexpected (serializeAndDeserialize (zeroSt) != zeroSt, "STAmount fail"); unexpected (serializeAndDeserialize (one) != one, "STAmount fail"); unexpected (serializeAndDeserialize (hundred) != hundred, "STAmount fail"); - unexpected (!zero.isNative (), "STAmount fail"); + unexpected (!zeroSt.isNative (), "STAmount fail"); unexpected (!hundred.isNative (), "STAmount fail"); - unexpected (!zero.isZero (), "STAmount fail"); + unexpected (zeroSt != zero, "STAmount fail"); - unexpected (one.isZero (), "STAmount fail"); + unexpected (one == zero, "STAmount fail"); - unexpected (hundred.isZero (), "STAmount fail"); + unexpected (hundred == zero, "STAmount fail"); - unexpected ((zero < zero), "STAmount fail"); + unexpected ((zeroSt < zeroSt), "STAmount fail"); - unexpected (! (zero < one), "STAmount fail"); + unexpected (! (zeroSt < one), "STAmount fail"); - unexpected (! (zero < hundred), "STAmount fail"); + unexpected (! (zeroSt < hundred), "STAmount fail"); - unexpected ((one < zero), "STAmount fail"); + unexpected ((one < zeroSt), "STAmount fail"); unexpected ((one < one), "STAmount fail"); unexpected (! (one < hundred), "STAmount fail"); - unexpected ((hundred < zero), "STAmount fail"); + unexpected ((hundred < zeroSt), "STAmount fail"); unexpected ((hundred < one), "STAmount fail"); unexpected ((hundred < hundred), "STAmount fail"); - unexpected ((zero > zero), "STAmount fail"); + unexpected ((zeroSt > zeroSt), "STAmount fail"); - unexpected ((zero > one), "STAmount fail"); + unexpected ((zeroSt > one), "STAmount fail"); - unexpected ((zero > hundred), "STAmount fail"); + unexpected ((zeroSt > hundred), "STAmount fail"); - unexpected (! (one > zero), "STAmount fail"); + unexpected (! (one > zeroSt), "STAmount fail"); unexpected ((one > one), "STAmount fail"); unexpected ((one > hundred), "STAmount fail"); - unexpected (! (hundred > zero), "STAmount fail"); + unexpected (! (hundred > zeroSt), "STAmount fail"); unexpected (! (hundred > one), "STAmount fail"); unexpected ((hundred > hundred), "STAmount fail"); - unexpected (! (zero <= zero), "STAmount fail"); + unexpected (! (zeroSt <= zeroSt), "STAmount fail"); - unexpected (! (zero <= one), "STAmount fail"); + unexpected (! (zeroSt <= one), "STAmount fail"); - unexpected (! (zero <= hundred), "STAmount fail"); + unexpected (! (zeroSt <= hundred), "STAmount fail"); - unexpected ((one <= zero), "STAmount fail"); + unexpected ((one <= zeroSt), "STAmount fail"); unexpected (! (one <= one), "STAmount fail"); unexpected (! (one <= hundred), "STAmount fail"); - unexpected ((hundred <= zero), "STAmount fail"); + unexpected ((hundred <= zeroSt), "STAmount fail"); unexpected ((hundred <= one), "STAmount fail"); unexpected (! (hundred <= hundred), "STAmount fail"); - unexpected (! (zero >= zero), "STAmount fail"); + unexpected (! (zeroSt >= zeroSt), "STAmount fail"); - unexpected ((zero >= one), "STAmount fail"); + unexpected ((zeroSt >= one), "STAmount fail"); - unexpected ((zero >= hundred), "STAmount fail"); + unexpected ((zeroSt >= hundred), "STAmount fail"); - unexpected (! (one >= zero), "STAmount fail"); + unexpected (! (one >= zeroSt), "STAmount fail"); unexpected (! (one >= one), "STAmount fail"); unexpected ((one >= hundred), "STAmount fail"); - unexpected (! (hundred >= zero), "STAmount fail"); + unexpected (! (hundred >= zeroSt), "STAmount fail"); unexpected (! (hundred >= one), "STAmount fail"); unexpected (! (hundred >= hundred), "STAmount fail"); - unexpected (! (zero == zero), "STAmount fail"); + unexpected (! (zeroSt == zeroSt), "STAmount fail"); - unexpected ((zero == one), "STAmount fail"); + unexpected ((zeroSt == one), "STAmount fail"); - unexpected ((zero == hundred), "STAmount fail"); + unexpected ((zeroSt == hundred), "STAmount fail"); - unexpected ((one == zero), "STAmount fail"); + unexpected ((one == zeroSt), "STAmount fail"); unexpected (! (one == one), "STAmount fail"); unexpected ((one == hundred), "STAmount fail"); - unexpected ((hundred == zero), "STAmount fail"); + unexpected ((hundred == zeroSt), "STAmount fail"); unexpected ((hundred == one), "STAmount fail"); unexpected (! (hundred == hundred), "STAmount fail"); - unexpected ((zero != zero), "STAmount fail"); + unexpected ((zeroSt != zeroSt), "STAmount fail"); - unexpected (! (zero != one), "STAmount fail"); + unexpected (! (zeroSt != one), "STAmount fail"); - unexpected (! (zero != hundred), "STAmount fail"); + unexpected (! (zeroSt != hundred), "STAmount fail"); - unexpected (! (one != zero), "STAmount fail"); + unexpected (! (one != zeroSt), "STAmount fail"); unexpected ((one != one), "STAmount fail"); unexpected (! (one != hundred), "STAmount fail"); - unexpected (! (hundred != zero), "STAmount fail"); + unexpected (! (hundred != zeroSt), "STAmount fail"); unexpected (! (hundred != one), "STAmount fail"); @@ -1439,129 +1442,129 @@ public: { testcase ("custom currency"); - STAmount zero (CURRENCY_ONE, ACCOUNT_ONE), one (CURRENCY_ONE, ACCOUNT_ONE, 1), hundred (CURRENCY_ONE, ACCOUNT_ONE, 100); + STAmount zeroSt (CURRENCY_ONE, ACCOUNT_ONE), one (CURRENCY_ONE, ACCOUNT_ONE, 1), hundred (CURRENCY_ONE, ACCOUNT_ONE, 100); serializeAndDeserialize (one).getRaw (); - unexpected (serializeAndDeserialize (zero) != zero, "STAmount fail"); + unexpected (serializeAndDeserialize (zeroSt) != zeroSt, "STAmount fail"); unexpected (serializeAndDeserialize (one) != one, "STAmount fail"); unexpected (serializeAndDeserialize (hundred) != hundred, "STAmount fail"); - unexpected (zero.isNative (), "STAmount fail"); + unexpected (zeroSt.isNative (), "STAmount fail"); unexpected (hundred.isNative (), "STAmount fail"); - unexpected (!zero.isZero (), "STAmount fail"); + unexpected (zeroSt != zero, "STAmount fail"); - unexpected (one.isZero (), "STAmount fail"); + unexpected (one == zero, "STAmount fail"); - unexpected (hundred.isZero (), "STAmount fail"); + unexpected (hundred == zero, "STAmount fail"); - unexpected ((zero < zero), "STAmount fail"); + unexpected ((zeroSt < zeroSt), "STAmount fail"); - unexpected (! (zero < one), "STAmount fail"); + unexpected (! (zeroSt < one), "STAmount fail"); - unexpected (! (zero < hundred), "STAmount fail"); + unexpected (! (zeroSt < hundred), "STAmount fail"); - unexpected ((one < zero), "STAmount fail"); + unexpected ((one < zeroSt), "STAmount fail"); unexpected ((one < one), "STAmount fail"); unexpected (! (one < hundred), "STAmount fail"); - unexpected ((hundred < zero), "STAmount fail"); + unexpected ((hundred < zeroSt), "STAmount fail"); unexpected ((hundred < one), "STAmount fail"); unexpected ((hundred < hundred), "STAmount fail"); - unexpected ((zero > zero), "STAmount fail"); + unexpected ((zeroSt > zeroSt), "STAmount fail"); - unexpected ((zero > one), "STAmount fail"); + unexpected ((zeroSt > one), "STAmount fail"); - unexpected ((zero > hundred), "STAmount fail"); + unexpected ((zeroSt > hundred), "STAmount fail"); - unexpected (! (one > zero), "STAmount fail"); + unexpected (! (one > zeroSt), "STAmount fail"); unexpected ((one > one), "STAmount fail"); unexpected ((one > hundred), "STAmount fail"); - unexpected (! (hundred > zero), "STAmount fail"); + unexpected (! (hundred > zeroSt), "STAmount fail"); unexpected (! (hundred > one), "STAmount fail"); unexpected ((hundred > hundred), "STAmount fail"); - unexpected (! (zero <= zero), "STAmount fail"); + unexpected (! (zeroSt <= zeroSt), "STAmount fail"); - unexpected (! (zero <= one), "STAmount fail"); + unexpected (! (zeroSt <= one), "STAmount fail"); - unexpected (! (zero <= hundred), "STAmount fail"); + unexpected (! (zeroSt <= hundred), "STAmount fail"); - unexpected ((one <= zero), "STAmount fail"); + unexpected ((one <= zeroSt), "STAmount fail"); unexpected (! (one <= one), "STAmount fail"); unexpected (! (one <= hundred), "STAmount fail"); - unexpected ((hundred <= zero), "STAmount fail"); + unexpected ((hundred <= zeroSt), "STAmount fail"); unexpected ((hundred <= one), "STAmount fail"); unexpected (! (hundred <= hundred), "STAmount fail"); - unexpected (! (zero >= zero), "STAmount fail"); + unexpected (! (zeroSt >= zeroSt), "STAmount fail"); - unexpected ((zero >= one), "STAmount fail"); + unexpected ((zeroSt >= one), "STAmount fail"); - unexpected ((zero >= hundred), "STAmount fail"); + unexpected ((zeroSt >= hundred), "STAmount fail"); - unexpected (! (one >= zero), "STAmount fail"); + unexpected (! (one >= zeroSt), "STAmount fail"); unexpected (! (one >= one), "STAmount fail"); unexpected ((one >= hundred), "STAmount fail"); - unexpected (! (hundred >= zero), "STAmount fail"); + unexpected (! (hundred >= zeroSt), "STAmount fail"); unexpected (! (hundred >= one), "STAmount fail"); unexpected (! (hundred >= hundred), "STAmount fail"); - unexpected (! (zero == zero), "STAmount fail"); + unexpected (! (zeroSt == zeroSt), "STAmount fail"); - unexpected ((zero == one), "STAmount fail"); + unexpected ((zeroSt == one), "STAmount fail"); - unexpected ((zero == hundred), "STAmount fail"); + unexpected ((zeroSt == hundred), "STAmount fail"); - unexpected ((one == zero), "STAmount fail"); + unexpected ((one == zeroSt), "STAmount fail"); unexpected (! (one == one), "STAmount fail"); unexpected ((one == hundred), "STAmount fail"); - unexpected ((hundred == zero), "STAmount fail"); + unexpected ((hundred == zeroSt), "STAmount fail"); unexpected ((hundred == one), "STAmount fail"); unexpected (! (hundred == hundred), "STAmount fail"); - unexpected ((zero != zero), "STAmount fail"); + unexpected ((zeroSt != zeroSt), "STAmount fail"); - unexpected (! (zero != one), "STAmount fail"); + unexpected (! (zeroSt != one), "STAmount fail"); - unexpected (! (zero != hundred), "STAmount fail"); + unexpected (! (zeroSt != hundred), "STAmount fail"); - unexpected (! (one != zero), "STAmount fail"); + unexpected (! (one != zeroSt), "STAmount fail"); unexpected ((one != one), "STAmount fail"); unexpected (! (one != hundred), "STAmount fail"); - unexpected (! (hundred != zero), "STAmount fail"); + unexpected (! (hundred != zeroSt), "STAmount fail"); unexpected (! (hundred != one), "STAmount fail"); @@ -1708,27 +1711,27 @@ public: (STAmount::cMinValue + STAmount::cMaxValue) / 2, STAmount::cMaxOffset - 1); STAmount smallValue (CURRENCY_ONE, ACCOUNT_ONE, (STAmount::cMinValue + STAmount::cMaxValue) / 2, STAmount::cMinOffset + 1); - STAmount zero (CURRENCY_ONE, ACCOUNT_ONE, 0); + STAmount zeroSt (CURRENCY_ONE, ACCOUNT_ONE, 0); STAmount smallXsmall = STAmount::multiply (smallValue, smallValue, CURRENCY_ONE, ACCOUNT_ONE); - expect (smallXsmall.isZero (), "smallXsmall != 0"); + expect (smallXsmall == zero, "smallXsmall != 0"); STAmount bigDsmall = STAmount::divide (smallValue, bigValue, CURRENCY_ONE, ACCOUNT_ONE); - expect (bigDsmall.isZero (), beast::String ("small/big != 0: ") + bigDsmall.getText ()); + expect (bigDsmall == zero, beast::String ("small/big != 0: ") + bigDsmall.getText ()); bigDsmall = STAmount::divide (smallValue, bigNative, CURRENCY_ONE, uint160 ()); - expect (bigDsmall.isZero (), beast::String ("small/bigNative != 0: ") + bigDsmall.getText ()); + expect (bigDsmall == zero, beast::String ("small/bigNative != 0: ") + bigDsmall.getText ()); bigDsmall = STAmount::divide (smallValue, bigValue, uint160 (), uint160 ()); - expect (bigDsmall.isZero (), beast::String ("(small/big)->N != 0: ") + bigDsmall.getText ()); + expect (bigDsmall == zero, beast::String ("(small/big)->N != 0: ") + bigDsmall.getText ()); bigDsmall = STAmount::divide (smallValue, bigNative, uint160 (), uint160 ()); - expect (bigDsmall.isZero (), beast::String ("(small/bigNative)->N != 0: ") + bigDsmall.getText ()); + expect (bigDsmall == zero, beast::String ("(small/bigNative)->N != 0: ") + bigDsmall.getText ()); // very bad offer std::uint64_t r = STAmount::getRate (smallValue, bigValue); diff --git a/src/ripple_data/protocol/STAmountRound.cpp b/src/ripple_data/protocol/STAmountRound.cpp index e91303602..ce318d8ae 100644 --- a/src/ripple_data/protocol/STAmountRound.cpp +++ b/src/ripple_data/protocol/STAmountRound.cpp @@ -203,7 +203,7 @@ STAmount STAmount::subRound (const STAmount& v1, const STAmount& v2, bool roundU STAmount STAmount::mulRound (const STAmount& v1, const STAmount& v2, const uint160& uCurrencyID, const uint160& uIssuerID, bool roundUp) { - if (v1.isZero () || v2.isZero ()) + if (v1 == zero || v2 == zero) return STAmount (uCurrencyID, uIssuerID); if (v1.mIsNative && v2.mIsNative && uCurrencyID.isZero ()) @@ -267,10 +267,10 @@ STAmount STAmount::mulRound (const STAmount& v1, const STAmount& v2, STAmount STAmount::divRound (const STAmount& num, const STAmount& den, const uint160& uCurrencyID, const uint160& uIssuerID, bool roundUp) { - if (den.isZero ()) + if (den == zero) throw std::runtime_error ("division by zero"); - if (num.isZero ()) + if (num == zero) return STAmount (uCurrencyID, uIssuerID); std::uint64_t numVal = num.mValue, denVal = den.mValue; diff --git a/src/ripple_data/protocol/SerializedTypes.h b/src/ripple_data/protocol/SerializedTypes.h index a0201dff7..bcdd764b9 100644 --- a/src/ripple_data/protocol/SerializedTypes.h +++ b/src/ripple_data/protocol/SerializedTypes.h @@ -70,13 +70,13 @@ static inline const uint160& get_u160_one () //------------------------------------------------------------------------------ /** A type which can be exported to a well known binary format. - + A SerializedType: - Always a field - Can always go inside an eligible enclosing SerializedType (such as STArray) - Has a field name - + Like JSON, a SerializedObject is a basket which has rules on what it can hold. @@ -574,6 +574,11 @@ public: return mValue; } + int signum () const + { + return mValue ? (mIsNegative ? -1 : 1) : 0; + } + // When the currency is XRP, the value in raw units. S=signed std::uint64_t getNValue () const { @@ -596,47 +601,24 @@ public: { return mIsNative; } - bool isZero () const - { - return mValue == 0; - } - bool isNonZero () const - { - return mValue != 0; - } - bool isNegative () const - { - return mIsNegative && !isZero (); - } - bool isPositive () const - { - return !mIsNegative && !isZero (); - } - bool isLEZero () const - { - return mIsNegative || isZero (); - } - bool isGEZero () const - { - return !mIsNegative; - } bool isLegalNet () const { return !mIsNative || (mValue <= cMaxNativeN); } - + explicit operator bool () const noexcept { - return !isZero (); + return *this != zero; } void negate () { - if (!isZero ()) mIsNegative = !mIsNegative; + if (*this != zero) + mIsNegative = !mIsNegative; } - void zero () + void clear () { // VFALCO: Why -100? mOffset = mIsNative ? 0 : -100; @@ -645,19 +627,25 @@ public: } // Zero while copying currency and issuer. - void zero (const STAmount& saTmpl) + void clear (const STAmount& saTmpl) { mCurrency = saTmpl.mCurrency; mIssuer = saTmpl.mIssuer; mIsNative = saTmpl.mIsNative; - zero (); + clear (); } - void zero (const uint160& uCurrencyID, const uint160& uIssuerID) + void clear (const uint160& uCurrencyID, const uint160& uIssuerID) { mCurrency = uCurrencyID; mIssuer = uIssuerID; mIsNative = !uCurrencyID; - zero (); + clear (); + } + + STAmount& operator=(beast::Zero) + { + clear (); + return *this; } int compare (const STAmount&) const; @@ -789,7 +777,7 @@ public: STAmount getRound () const; void roundSelf (); - + static void canonicalizeRound (bool isNative, std::uint64_t& value, int& offset, bool roundUp); private: @@ -1278,7 +1266,7 @@ public: bool operator== (const STPathElement& t) const { - return ((mType & typeAccount) == (t.mType & typeAccount)) && + return ((mType & typeAccount) == (t.mType & typeAccount)) && (mAccountID == t.mAccountID) && (mCurrencyID == t.mCurrencyID) && (mIssuerID == t.mIssuerID); } @@ -1655,4 +1643,4 @@ private: } // ripple -#endif \ No newline at end of file +#endif