Use Rate to represent transfer rates (RIPD-201, RIPD-983):

The Ripple protocol represent transfer rates and trust line
qualities as fractions of one billion. For example, a transfer
rate of 1% is represented as 1010000000.

Previously, such rates where represented either as std::uint32_t
or std::uint64_t. Other, nominally related types, also used an
integral representation and could be unintentionally substituted.

The new Rate class addresses this by providing a simple, type
safe alternative which also helps make the code self-documenting
since arithmetic operations now can be clearly understood to
involve the scaling of an amount by a rate.
This commit is contained in:
Nik Bougalis
2016-06-08 03:07:19 -07:00
committed by Miguel Portilla
parent f060820f3b
commit a698104c55
34 changed files with 579 additions and 433 deletions

View File

@@ -25,4 +25,121 @@ namespace ripple {
Rate const parityRate (QUALITY_ONE);
namespace detail {
STAmount as_amount (Rate const& rate)
{
return { noIssue(), rate.value, -9, false };
}
}
STAmount
multiply (
STAmount const& amount,
Rate const& rate)
{
assert (rate.value != 0);
if (rate == parityRate)
return amount;
return multiply (
amount,
detail::as_amount(rate),
amount.issue());
}
STAmount
multiplyRound (
STAmount const& amount,
Rate const& rate,
bool roundUp)
{
assert (rate.value != 0);
if (rate == parityRate)
return amount;
return mulRound (
amount,
detail::as_amount(rate),
amount.issue(),
roundUp);
}
STAmount
multiplyRound (
STAmount const& amount,
Rate const& rate,
Issue const& issue,
bool roundUp)
{
assert (rate.value != 0);
if (rate == parityRate)
{
return amount;
}
return mulRound (
amount,
detail::as_amount(rate),
issue,
roundUp);
}
STAmount
divide (
STAmount const& amount,
Rate const& rate)
{
assert (rate.value != 0);
if (rate == parityRate)
return amount;
return divide (
amount,
detail::as_amount(rate),
amount.issue());
}
STAmount
divideRound (
STAmount const& amount,
Rate const& rate,
bool roundUp)
{
assert (rate.value != 0);
if (rate == parityRate)
return amount;
return divRound (
amount,
detail::as_amount(rate),
amount.issue(),
roundUp);
}
STAmount
divideRound (
STAmount const& amount,
Rate const& rate,
Issue const& issue,
bool roundUp)
{
assert (rate.value != 0);
if (rate == parityRate)
return amount;
return divRound (
amount,
detail::as_amount(rate),
issue,
roundUp);
}
}

View File

@@ -406,9 +406,6 @@ STAmount operator- (STAmount const& v1, STAmount const& v2)
std::uint64_t const STAmount::uRateOne = getRate (STAmount (1), STAmount (1));
STAmount const STAmount::saZero (noIssue (), 0u);
STAmount const STAmount::saOne (noIssue (), 1u);
void
STAmount::setIssue (Issue const& issue)
{
@@ -721,12 +718,6 @@ void STAmount::set (std::int64_t v)
//------------------------------------------------------------------------------
STAmount
amountFromRate (std::uint64_t uRate)
{
return { noIssue(), uRate, -9, false };
}
STAmount
amountFromQuality (std::uint64_t rate)
{

View File

@@ -133,7 +133,7 @@ bool transResultInfo (TER code, std::string& token, std::string& text)
{ terNO_LINE, { "terNO_LINE", "No such line." } },
{ terPRE_SEQ, { "terPRE_SEQ", "Missing/inapplicable prior transaction." } },
{ terOWNERS, { "terOWNERS", "Non-zero owner count." } },
{ terQUEUED, { "terQUEUED", "Held until escalated fee drops." } },
{ terQUEUED, { "terQUEUED", "Held until escalated fee drops." } },
{ tesSUCCESS, { "tesSUCCESS", "The transaction was applied. Only final in a validated ledger." } },
};