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.
This commit is contained in:
Tom Swirly
2014-04-10 19:14:52 -04:00
committed by Vinnie Falco
parent 524f41177c
commit 64ee0d07d0
26 changed files with 591 additions and 425 deletions

View File

@@ -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 <assert.h>
#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

View File

@@ -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 <class Int>
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();

View File

@@ -31,3 +31,4 @@
#include "tests/bassert.test.cpp"
#include "tests/empty_base_optimization.test.cpp"
#include "tests/Zero.test.cpp"

View File

@@ -0,0 +1,140 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2014, Tom Ritchford <tom@swirly.com>
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 <typename T>
auto signum(T const& t) -> decltype(t.signum()) {
return t.signum();
}
namespace detail {
namespace zero_helper {
template <class T>
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 <typename T>
bool operator==(T const& t, Zero) {
return detail::zero_helper::call_signum(t) == 0;
}
template <typename T>
bool operator!=(T const& t, Zero) {
return detail::zero_helper::call_signum(t) != 0;
}
template <typename T>
bool operator>(T const& t, Zero) {
return detail::zero_helper::call_signum(t) > 0;
}
template <typename T>
bool operator>=(T const& t, Zero) {
return detail::zero_helper::call_signum(t) >= 0;
}
template <typename T>
bool operator<(T const& t, Zero) {
return detail::zero_helper::call_signum(t) < 0;
}
template <typename T>
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 <typename T>
bool operator==(Zero, T const& t) {
return t == zero;
}
template <typename T>
bool operator!=(Zero, T const& t) {
return t != zero;
}
template <typename T>
bool operator>(Zero, T const& t) {
return t < zero;
}
template <typename T>
bool operator>=(Zero, T const& t) {
return t <= zero;
}
template <typename T>
bool operator<(Zero, T const& t) {
return t > zero;
}
template <typename T>
bool operator<=(Zero, T const& t) {
return t >= zero;
}
} // beast
#endif

View File

@@ -0,0 +1,136 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2014, Nikolaos D. Bougalis <nikb@bougalis.net>
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);
}

0
src/beast/tests.sh Normal file → Executable file
View File

View File

@@ -25,119 +25,6 @@
#include "../../beast/beast/utility/noexcept.h"
#include "../../beast/beast/cxx14/type_traits.h" // <type_traits>
//------------------------------------------------------------------------------
struct Zero
{
Zero()
{
}
};
namespace {
static Zero const zero;
}
namespace detail {
namespace Zero_helpers {
template <class T>
int
get_signum (T const& t) noexcept
{
return signum(t);
}
}
}
/** Handle operators where T is on the left side using signum. */
template <class T>
bool operator==(T const& t, Zero)
{
return detail::Zero_helpers::get_signum(t) == 0;
}
template <class T>
bool operator!=(T const& t, Zero)
{
return detail::Zero_helpers::get_signum(t) != 0;
}
template <class T>
bool operator>(T const& t, Zero)
{
return detail::Zero_helpers::get_signum(t) > 0;
}
template <class T>
bool operator>=(T const& t, Zero)
{
return detail::Zero_helpers::get_signum(t) >= 0;
}
template <class T>
bool operator<(T const& t, Zero)
{
return detail::Zero_helpers::get_signum(t) < 0;
}
template <class T>
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 <class T>
bool operator==(Zero, T const& t)
{
return t == zero;
}
template <class T>
bool operator!=(Zero, T const& t)
{
return t != zero;
}
template <class T>
bool operator>(Zero, T const& t)
{
return t < zero;
}
template <class T>
bool operator>=(Zero, T const& t)
{
return t <= zero;
}
template <class T>
bool operator<(Zero, T const& t)
{
return t > zero;
}
template <class T>
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 <class T>
auto signum(T const& t) -> decltype(t.signum()) {
return t.signum();
}
//------------------------------------------------------------------------------
namespace ripple {
namespace core {

View File

@@ -39,7 +39,7 @@ struct Amounts
bool
empty() const noexcept
{
return ! in.isPositive() || ! out.isPositive();
return in <= zero || out <= zero;
}
Amount in;

View File

@@ -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)
*/

View File

@@ -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);
}
}

View File

@@ -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))
{

View File

@@ -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<PackedMessage> (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<PackedMessage> (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);

View File

@@ -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;

View File

@@ -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")

View File

@@ -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<uint160> 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())))

View File

@@ -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")

View File

@@ -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.";

View File

@@ -32,7 +32,7 @@ bool OfferCreateTransactor::isValidOffer (
std::unordered_set<uint160, beast::hardened_hash<uint160>>& 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<uint256, beast::hardened_hash<uint256>> usOfferUnfundedBecame;
std::unordered_set<uint256, beast::hardened_hash<uint256>> usOfferUnfundedBecame;
// Accounts touched.
std::unordered_set<uint160, beast::hardened_hash<uint160>> 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<uint256>& vuiIndexes = svIndexes.peekValue();
auto it = std::find (
vuiIndexes.begin (), vuiIndexes.end (), indexes.first);
if (it != vuiIndexes.end ())
{
vuiIndexes.erase (it);

View File

@@ -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

View File

@@ -45,7 +45,7 @@ TER RegularKeySetTransactor::doApply ()
return temINVALID_FLAG;
}
if (mFeeDue.isZero ())
if (mFeeDue == zero)
{
mTxnAccount->setFlag (lsfPasswordSpent);
}

View File

@@ -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;

View File

@@ -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 ();

View File

@@ -27,6 +27,10 @@
#include <atomic>
#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

View File

@@ -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<std::uint64_t> (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);

View File

@@ -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;

View File

@@ -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
#endif