Make XRPAmount constructor explicit:

Remove the implicit conversion from int64 to XRPAmount. The motivation for this
was noticing that many calls to `to_string` with an integer parameter type were
calling the wrong `to_string` function. Since the calls were not prefixed with
`std::`, and there is no ADL to call `std::to_string`, this was converting the
int to an `XRPAmount` and calling `to_string(XRPAmount)`.

Since `to_string(XRPAmount)` did the same thing as `to_string(int)` this error
went undetected.
This commit is contained in:
seelabs
2019-08-28 11:44:36 -07:00
parent e3b5b808c5
commit 761bb5744e
23 changed files with 87 additions and 77 deletions

View File

@@ -198,7 +198,7 @@ handleNewValidation(Application& app,
{
auto const seq = val->getFieldU32(sfLedgerSequence);
dmp(j.warn(),
"already validated sequence at or past " + to_string(seq));
"already validated sequence at or past " + std::to_string(seq));
}
if (val->isTrusted() && outcome == ValStatus::current)

View File

@@ -208,7 +208,7 @@ InboundLedger::~InboundLedger ()
"Acquire " << mHash << " abort " <<
((getTimeouts () == 0) ? std::string() :
(std::string ("timeouts:") +
to_string (getTimeouts ()) + " ")) <<
std::to_string (getTimeouts ()) + " ")) <<
mStats.get ();
}
}
@@ -463,7 +463,7 @@ void InboundLedger::done ()
(mFailed ? " fail " : " ") <<
((getTimeouts () == 0) ? std::string() :
(std::string ("timeouts:") +
to_string (getTimeouts ()) + " ")) <<
std::to_string (getTimeouts ()) + " ")) <<
mStats.get ();
assert (mComplete || mFailed);

View File

@@ -958,7 +958,7 @@ TxQ::apply(Application& app, OpenView& view,
auto const potentialTotalSpend = multiTxn->fee +
std::min(balance - std::min(balance, reserve),
multiTxn->potentialSpend);
assert(potentialTotalSpend > 0);
assert(potentialTotalSpend > XRPAmount{0});
sleBump->setFieldAmount(sfBalance,
balance - potentialTotalSpend);
sleBump->setFieldU32(sfSequence, tSeq);
@@ -1516,11 +1516,11 @@ TxQ::doRPC(Application& app) const
auto& levels = ret[jss::levels] = Json::objectValue;
ret[jss::ledger_current_index] = view->info().seq;
ret[jss::expected_ledger_size] = to_string(metrics.txPerLedger);
ret[jss::current_ledger_size] = to_string(metrics.txInLedger);
ret[jss::current_queue_size] = to_string(metrics.txCount);
ret[jss::expected_ledger_size] = std::to_string(metrics.txPerLedger);
ret[jss::current_ledger_size] = std::to_string(metrics.txInLedger);
ret[jss::current_queue_size] = std::to_string(metrics.txCount);
if (metrics.txQMaxSize)
ret[jss::max_queue_size] = to_string(*metrics.txQMaxSize);
ret[jss::max_queue_size] = std::to_string(*metrics.txQMaxSize);
levels[jss::reference_level] = to_string(metrics.referenceFeeLevel);
levels[jss::minimum_level] = to_string(metrics.minProcessingFeeLevel);

View File

@@ -174,7 +174,7 @@ XRPBalanceChecks::visitEntry(
return true;
// Can't have a negative balance (0 is OK)
if (drops < 0)
if (drops < XRPAmount{0})
return true;
return false;
@@ -262,7 +262,7 @@ NoZeroEscrow::visitEntry(
if (!amount.native())
return true;
if (amount.xrp() <= 0)
if (amount.xrp() <= XRPAmount{0})
return true;
if (amount.xrp() >= INITIAL_XRP)

View File

@@ -75,6 +75,7 @@ public:
}
constexpr
explicit
XRPAmount (value_type drops)
: drops_ (drops)
{

View File

@@ -105,6 +105,7 @@ public:
STAmount (SField const& name, Issue const& issue,
std::uint64_t mantissa = 0, int exponent = 0, bool negative = false);
explicit
STAmount (std::uint64_t mantissa = 0, bool negative = false);
STAmount (Issue const& issue, std::uint64_t mantissa = 0, int exponent = 0,

View File

@@ -42,7 +42,7 @@ systemName ()
/** Number of drops in the genesis account. */
constexpr
XRPAmount
INITIAL_XRP{ 100'000'000'000 * DROPS_PER_XRP };
INITIAL_XRP{100'000'000'000 * DROPS_PER_XRP };
/** Returns true if the amount does not exceed the initial XRP in existence. */
inline

View File

@@ -1154,7 +1154,7 @@ Json::Value transactionSubmitMultiSigned (
<< " field. Fees must be specified in XRP.";
return RPC::make_error (rpcINVALID_PARAMS, err.str ());
}
if (fee <= 0)
if (fee <= STAmount{0})
{
std::ostringstream err;
err << "Invalid " << sfFee.fieldName

View File

@@ -41,12 +41,10 @@ public:
return f;
}();
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{ 0 }, l, fees, false) ==
XRPAmount{ 0 });
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{ 10000 }, l, fees, false) ==
XRPAmount{ 10000 });
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{ 1 }, l, fees, false) ==
XRPAmount{ 1 });
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{0}, l, fees, false) == XRPAmount{0});
BEAST_EXPECT(
scaleFeeLoad(FeeUnit64{10000}, l, fees, false) == XRPAmount{10000});
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{1}, l, fees, false) == XRPAmount{1});
}
{
Fees const fees = [&]() {
@@ -58,12 +56,10 @@ public:
return f;
}();
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{ 0 }, l, fees, false) ==
XRPAmount{ 0 });
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{ 10000 }, l, fees, false) ==
XRPAmount{ 100000 });
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{ 1 }, l, fees, false) ==
XRPAmount{ 10 });
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{0}, l, fees, false) == XRPAmount{0});
BEAST_EXPECT(
scaleFeeLoad(FeeUnit64{10000}, l, fees, false) == XRPAmount{100000});
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{1}, l, fees, false) == XRPAmount{10});
}
{
Fees const fees = [&]()
@@ -76,12 +72,10 @@ public:
return f;
}();
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{ 0 }, l, fees, false) ==
XRPAmount{ 0 });
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{ 10000 }, l, fees, false) ==
XRPAmount{ 1000 });
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{ 1 }, l, fees, false) ==
XRPAmount{ 0 });
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{0}, l, fees, false) == XRPAmount{0});
BEAST_EXPECT(
scaleFeeLoad(FeeUnit64{10000}, l, fees, false) == XRPAmount{1000});
BEAST_EXPECT(scaleFeeLoad(FeeUnit64{1}, l, fees, false) == XRPAmount{0});
}
}
};

View File

@@ -299,7 +299,7 @@ struct PayChan_test : public beast::unit_test::suite
// Try to claim more than authorized
auto const preBob = env.balance (bob);
STAmount const authAmt = chanBal + XRP (500);
STAmount const reqAmt = authAmt + 1;
STAmount const reqAmt = authAmt + STAmount{1};
assert (reqAmt <= chanAmt);
auto const sig =
signClaimAuth (alice.pk (), alice.sk (), chan, authAmt);

View File

@@ -39,7 +39,7 @@ class SHAMapStore_test : public beast::unit_test::suite
{
cfg->LEDGER_HISTORY = deleteInterval;
auto& section = cfg->section(ConfigSection::nodeDatabase());
section.set("online_delete", to_string(deleteInterval));
section.set("online_delete", std::to_string(deleteInterval));
return cfg;
}
@@ -182,7 +182,7 @@ class SHAMapStore_test : public beast::unit_test::suite
store.rendezvous();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq++)));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq++)));
BEAST_EXPECT(store.getLastRotated() == ledgerSeq - 1);
return ledgerSeq;
@@ -230,19 +230,19 @@ public:
for (auto i = firstSeq + 1; i < deleteInterval + firstSeq; ++i)
{
env.fund(XRP(10000), noripple("test" + to_string(i)));
env.fund(XRP(10000), noripple("test" + std::to_string(i)));
env.close();
ledgerTmp = env.rpc("ledger", "current");
BEAST_EXPECT(goodLedger(env, ledgerTmp, to_string(i)));
BEAST_EXPECT(goodLedger(env, ledgerTmp, std::to_string(i)));
}
BEAST_EXPECT(store.getLastRotated() == lastRotated);
for (auto i = 3; i < deleteInterval + lastRotated; ++i)
{
ledgers.emplace(std::make_pair(i,
env.rpc("ledger", to_string(i))));
BEAST_EXPECT(goodLedger(env, ledgers[i], to_string(i), true) &&
ledgers.emplace(
std::make_pair(i, env.rpc("ledger", std::to_string(i))));
BEAST_EXPECT(goodLedger(env, ledgers[i], std::to_string(i), true) &&
getHash(ledgers[i]).length());
}
@@ -255,7 +255,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "current");
BEAST_EXPECT(goodLedger(env, ledger, to_string(deleteInterval + 4)));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(deleteInterval + 4)));
}
store.rendezvous();
@@ -275,13 +275,13 @@ public:
env.close();
ledgerTmp = env.rpc("ledger", "current");
BEAST_EXPECT(goodLedger(env, ledgerTmp, to_string(i + 3)));
BEAST_EXPECT(goodLedger(env, ledgerTmp, std::to_string(i + 3)));
ledgers.emplace(std::make_pair(i,
env.rpc("ledger", to_string(i))));
ledgers.emplace(
std::make_pair(i, env.rpc("ledger", std::to_string(i))));
BEAST_EXPECT(store.getLastRotated() == lastRotated ||
i == lastRotated + deleteInterval - 2);
BEAST_EXPECT(goodLedger(env, ledgers[i], to_string(i), true) &&
BEAST_EXPECT(goodLedger(env, ledgers[i], std::to_string(i), true) &&
getHash(ledgers[i]).length());
}
@@ -320,7 +320,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq), true));
}
store.rendezvous();
@@ -335,7 +335,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq++), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
}
store.rendezvous();
@@ -351,7 +351,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq), true));
}
store.rendezvous();
@@ -389,7 +389,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq), true));
}
store.rendezvous();
@@ -398,7 +398,7 @@ public:
BEAST_EXPECT(lastRotated == store.getLastRotated());
// This does not kick off a cleanup
canDelete = env.rpc("can_delete", to_string(
canDelete = env.rpc("can_delete", std::to_string(
ledgerSeq + deleteInterval / 2));
BEAST_EXPECT(!RPC::contains_error(canDelete[jss::result]));
BEAST_EXPECT(canDelete[jss::result][jss::can_delete] ==
@@ -414,7 +414,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq++), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
}
store.rendezvous();
@@ -430,7 +430,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq), true));
}
store.rendezvous();
@@ -442,7 +442,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq++), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
}
store.rendezvous();
@@ -464,7 +464,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq), true));
}
store.rendezvous();
@@ -476,7 +476,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq++), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
}
store.rendezvous();
@@ -497,7 +497,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq), true));
}
store.rendezvous();
@@ -509,7 +509,7 @@ public:
env.close();
auto ledger = env.rpc("ledger", "validated");
BEAST_EXPECT(goodLedger(env, ledger, to_string(ledgerSeq++), true));
BEAST_EXPECT(goodLedger(env, ledger, std::to_string(ledgerSeq++), true));
}
store.rendezvous();

View File

@@ -344,8 +344,7 @@ public:
void run() override
{
BEAST_EXPECT(INITIAL_XRP.drops() == 100'000'000'000'000'000);
BEAST_EXPECT(INITIAL_XRP ==
XRPAmount{ 100'000'000'000'000'000 });
BEAST_EXPECT(INITIAL_XRP == XRPAmount{100'000'000'000'000'000});
testTypes();
testJson();

View File

@@ -132,8 +132,7 @@ public:
{
// Explicitly test every defined function for the XRPAmount class
// since some of them are templated, but not used anywhere else.
auto make = [&](auto x) -> XRPAmount {
return x; };
auto make = [&](auto x) -> XRPAmount { return XRPAmount{x}; };
XRPAmount defaulted;
(void)defaulted;
@@ -156,8 +155,8 @@ public:
test = make(targetSame);
BEAST_EXPECT(test.drops() == 200);
BEAST_EXPECT(test == targetSame);
BEAST_EXPECT(test < XRPAmount{ 1000 });
BEAST_EXPECT(test > XRPAmount{ 100 });
BEAST_EXPECT(test < XRPAmount{1000});
BEAST_EXPECT(test > XRPAmount{100});
test = std::int64_t(200);
BEAST_EXPECT(test.drops() == 200);

View File

@@ -143,6 +143,14 @@ operator== (PrettyAmount const& lhs,
return lhs.value() == rhs.value();
}
inline
bool
operator!= (PrettyAmount const& lhs,
PrettyAmount const& rhs)
{
return !operator==(lhs, rhs);
}
std::ostream&
operator<< (std::ostream& os,
PrettyAmount const& amount);

View File

@@ -58,6 +58,12 @@ public:
"fee: not XRP");
}
explicit
fee(std::uint64_t amount)
: fee{STAmount{amount}}
{
}
void
operator()(Env&, JTx& jt) const;
};

View File

@@ -77,7 +77,7 @@ operator<< (std::ostream& os,
if (amount.value().native())
{
// measure in hundredths
XRPAmount const c{dropsPerXRP.drops() / 100};
auto const c = dropsPerXRP.drops() / 100;
auto const n = amount.value().mantissa();
if(n < c)
{

View File

@@ -35,9 +35,9 @@ std::atomic<bool> envUseIPv4 {false};
void
setupConfigForUnitTests (Config& cfg)
{
std::string const port_peer = to_string(port_base);
std::string port_rpc = to_string(port_base + 1);
std::string port_ws = to_string(port_base + 2);
std::string const port_peer = std::to_string(port_base);
std::string port_rpc = std::to_string(port_base + 1);
std::string port_ws = std::to_string(port_base + 2);
cfg.overwrite (ConfigSection::nodeDatabase (), "type", "memory");
cfg.overwrite (ConfigSection::nodeDatabase (), "path", "main");

View File

@@ -137,7 +137,7 @@ class Invariants_test : public beast::unit_test::suite
if(! sle)
return false;
auto amt = sle->getFieldAmount (sfBalance);
sle->setFieldAmount (sfBalance, amt + 500);
sle->setFieldAmount (sfBalance, amt + STAmount{500});
ac.view().update (sle);
return true;
});
@@ -299,7 +299,7 @@ class Invariants_test : public beast::unit_test::suite
auto const sle = ac.view().peek (keylet::account(A1.id()));
if(! sle)
return false;
sle->setFieldAmount (sfBalance, {1, true});
sle->setFieldAmount (sfBalance, STAmount{1, true});
BEAST_EXPECT(sle->getFieldAmount(sfBalance).negative());
ac.view().update (sle);
return true;
@@ -328,9 +328,10 @@ class Invariants_test : public beast::unit_test::suite
[](Account const&, Account const&, ApplyContext&) { return true; },
XRPAmount{INITIAL_XRP});
doInvariantCheck (enabled,
{{ "fee paid is 20 exceeds fee specified in transaction." },
{ "XRP net change of 0 doesn't match fee 20" }},
doInvariantCheck(
enabled,
{{"fee paid is 20 exceeds fee specified in transaction."},
{"XRP net change of 0 doesn't match fee 20"}},
[](Account const&, Account const&, ApplyContext&) { return true; },
XRPAmount{20},
STTx { ttACCOUNT_SET,

View File

@@ -78,7 +78,7 @@ public:
STAmount num (noIssue(), n);
STAmount den (noIssue(), d);
STAmount mul (noIssue(), m);
STAmount quot = divide (n, d, noIssue());
STAmount quot = divide(STAmount(n), STAmount(d), noIssue());
STAmount res = roundSelf (multiply (quot, mul, noIssue()));
BEAST_EXPECT(! res.native ());

View File

@@ -83,7 +83,7 @@ class LedgerRPC_test : public beast::unit_test::suite
// using current identifier
auto const jrr = env.rpc("ledger", "current") [jss::result];
BEAST_EXPECT(jrr[jss::ledger][jss::closed] == false);
BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == to_string(env.current()->info().seq));
BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == std::to_string(env.current()->info().seq));
BEAST_EXPECT(jrr[jss::ledger_current_index] == env.current()->info().seq);
}
}

View File

@@ -370,7 +370,7 @@ public:
jv[jss::ledger_hash] ==
to_string(env.closed()->info().hash) &&
jv[jss::ledger_index] ==
to_string(env.closed()->info().seq) &&
std::to_string(env.closed()->info().seq) &&
jv[jss::flags] ==
(vfFullyCanonicalSig | STValidation::kFullFlag) &&
jv[jss::full] == true &&

View File

@@ -35,6 +35,7 @@ class Transaction_test : public beast::unit_test::suite
testcase("Test Range Request");
using namespace test::jtx;
using std::to_string;
const char* COMMAND = jss::tx.c_str();
const char* BINARY = jss::binary.c_str();

View File

@@ -593,7 +593,7 @@ class ServerStatus_test :
using namespace boost::asio;
using namespace boost::beast::http;
Env env {*this, envconfig([&](std::unique_ptr<Config> cfg) {
(*cfg)["port_rpc"].set("limit", to_string(limit));
(*cfg)["port_rpc"].set("limit", std::to_string(limit));
return cfg;
})};
@@ -612,7 +612,7 @@ class ServerStatus_test :
auto it =
r.async_resolve(
ip::tcp::resolver::query{ip, to_string(port)}, yield[ec]);
ip::tcp::resolver::query{ip, std::to_string(port)}, yield[ec]);
BEAST_EXPECT(! ec);
std::vector<std::pair<ip::tcp::socket, boost::beast::multi_buffer>> clients;
@@ -721,7 +721,7 @@ class ServerStatus_test :
auto it =
r.async_resolve(
ip::tcp::resolver::query{ip, to_string(port)}, yield[ec]);
ip::tcp::resolver::query{ip, std::to_string(port)}, yield[ec]);
if(! BEAST_EXPECT(! ec))
return;
@@ -731,7 +731,7 @@ class ServerStatus_test :
return;
boost::beast::websocket::stream<boost::asio::ip::tcp::socket&> ws{sock};
ws.handshake(ip + ":" + to_string(port), "/");
ws.handshake(ip + ":" + std::to_string(port), "/");
// helper lambda, used below
auto sendAndParse = [&](std::string const& req) -> Json::Value