Skip to content

Commit

Permalink
Add units to all fee calculations:
Browse files Browse the repository at this point in the history
* Uses existing XRPAmount with units for drops, and a new TaggedFee for
  fee units (LoadFeeTrack), and fee levels (TxQ).
* Resolves #2451
  • Loading branch information
ximinez committed Dec 18, 2019
1 parent ee738ba commit 279eedd
Show file tree
Hide file tree
Showing 88 changed files with 2,191 additions and 683 deletions.
13 changes: 8 additions & 5 deletions Builds/CMake/RippledCore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ else ()
src/ripple/basics/impl/contract.cpp
src/ripple/basics/impl/CountedObject.cpp
src/ripple/basics/impl/FileUtilities.cpp
src/ripple/basics/impl/IOUAmount.cpp
src/ripple/basics/impl/Log.cpp
src/ripple/basics/impl/strHex.cpp
src/ripple/basics/impl/StringUtilities.cpp
Expand All @@ -85,7 +86,6 @@ else ()
src/ripple/protocol/impl/ErrorCodes.cpp
src/ripple/protocol/impl/Feature.cpp
src/ripple/protocol/impl/HashPrefix.cpp
src/ripple/protocol/impl/IOUAmount.cpp
src/ripple/protocol/impl/Indexes.cpp
src/ripple/protocol/impl/InnerObjectFormats.cpp
src/ripple/protocol/impl/Issue.cpp
Expand Down Expand Up @@ -159,17 +159,20 @@ install (
src/ripple/basics/Buffer.h
src/ripple/basics/CountedObject.h
src/ripple/basics/FileUtilities.h
src/ripple/basics/IOUAmount.h
src/ripple/basics/LocalValue.h
src/ripple/basics/Log.h
src/ripple/basics/safe_cast.h
src/ripple/basics/Slice.h
src/ripple/basics/StringUtilities.h
src/ripple/basics/ToString.h
src/ripple/basics/UnorderedContainers.h
src/ripple/basics/XRPAmount.h
src/ripple/basics/algorithm.h
src/ripple/basics/base_uint.h
src/ripple/basics/chrono.h
src/ripple/basics/contract.h
src/ripple/basics/FeeUnits.h
src/ripple/basics/hardened_hash.h
src/ripple/basics/strHex.h
DESTINATION include/ripple/basics)
Expand Down Expand Up @@ -209,7 +212,6 @@ install (
src/ripple/protocol/ErrorCodes.h
src/ripple/protocol/Feature.h
src/ripple/protocol/HashPrefix.h
src/ripple/protocol/IOUAmount.h
src/ripple/protocol/Indexes.h
src/ripple/protocol/InnerObjectFormats.h
src/ripple/protocol/Issue.h
Expand Down Expand Up @@ -247,7 +249,6 @@ install (
src/ripple/protocol/TxFlags.h
src/ripple/protocol/TxFormats.h
src/ripple/protocol/UintTypes.h
src/ripple/protocol/XRPAmount.h
src/ripple/protocol/digest.h
src/ripple/protocol/jss.h
src/ripple/protocol/tokens.h
Expand Down Expand Up @@ -732,6 +733,7 @@ else ()
src/test/app/DepositAuth_test.cpp
src/test/app/Discrepancy_test.cpp
src/test/app/Escrow_test.cpp
src/test/app/FeeVote_test.cpp
src/test/app/Flow_test.cpp
src/test/app/Freeze_test.cpp
src/test/app/HashRouter_test.cpp
Expand Down Expand Up @@ -770,15 +772,18 @@ else ()
src/test/basics/Buffer_test.cpp
src/test/basics/DetectCrash_test.cpp
src/test/basics/FileUtilities_test.cpp
src/test/basics/IOUAmount_test.cpp
src/test/basics/KeyCache_test.cpp
src/test/basics/PerfLog_test.cpp
src/test/basics/RangeSet_test.cpp
src/test/basics/Slice_test.cpp
src/test/basics/StringUtilities_test.cpp
src/test/basics/TaggedCache_test.cpp
src/test/basics/XRPAmount_test.cpp
src/test/basics/base64_test.cpp
src/test/basics/base_uint_test.cpp
src/test/basics/contract_test.cpp
src/test/basics/FeeUnits_test.cpp
src/test/basics/hardened_hash_test.cpp
src/test/basics/mulDiv_test.cpp
src/test/basics/qalloc_test.cpp
Expand Down Expand Up @@ -934,7 +939,6 @@ else ()
nounity, test sources:
subdir: protocol
#]===============================]
src/test/protocol/IOUAmount_test.cpp
src/test/protocol/InnerObjectFormats_test.cpp
src/test/protocol/Issue_test.cpp
src/test/protocol/PublicKey_test.cpp
Expand All @@ -947,7 +951,6 @@ else ()
src/test/protocol/SecretKey_test.cpp
src/test/protocol/Seed_test.cpp
src/test/protocol/TER_test.cpp
src/test/protocol/XRPAmount_test.cpp
src/test/protocol/digest_test.cpp
src/test/protocol/types_test.cpp
#[===============================[
Expand Down
2 changes: 1 addition & 1 deletion src/ripple/app/ledger/Ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ Ledger::Ledger (
, rules_{config.features}
{
info_.seq = 1;
info_.drops = SYSTEM_CURRENCY_START;
info_.drops = INITIAL_XRP;
info_.closeTimeResolution = ledgerDefaultTimeResolution;

static auto const id = calcAccountID(
Expand Down
8 changes: 4 additions & 4 deletions src/ripple/app/misc/FeeVote.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,16 @@ class FeeVote
struct Setup
{
/** The cost of a reference transaction in drops. */
std::uint64_t reference_fee = 10;
XRPAmount reference_fee{ 10 };

/** The cost of a reference transaction in fee units. */
std::uint32_t const reference_fee_units = 10;
static constexpr FeeUnit32 reference_fee_units{ 10 };

/** The account reserve requirement in drops. */
std::uint64_t account_reserve = 20 * SYSTEM_CURRENCY_PARTS;
XRPAmount account_reserve{ 20 * DROPS_PER_XRP };

/** The per-owned item reserve requirement in drops. */
std::uint64_t owner_reserve = 5 * SYSTEM_CURRENCY_PARTS;
XRPAmount owner_reserve{ 5 * DROPS_PER_XRP };
};

virtual ~FeeVote () = default;
Expand Down
90 changes: 59 additions & 31 deletions src/ripple/app/misc/FeeVoteImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,16 @@ namespace ripple {

namespace detail {

template <typename Integer>
class VotableInteger
class VotableValue
{
private:
using map_type = std::map <Integer, int>;
Integer mCurrent; // The current setting
Integer mTarget; // The setting we want
map_type mVoteMap;
using value_type = XRPAmount;
value_type const mCurrent; // The current setting
value_type const mTarget; // The setting we want
std::map <value_type, int> mVoteMap;

public:
VotableInteger (Integer current, Integer target)
VotableValue (value_type current, value_type target)
: mCurrent (current)
, mTarget (target)
{
Expand All @@ -47,7 +46,7 @@ class VotableInteger
}

void
addVote(Integer vote)
addVote(value_type vote)
{
++mVoteMap[vote];
}
Expand All @@ -58,15 +57,15 @@ class VotableInteger
addVote (mCurrent);
}

Integer
value_type
getVotes() const;
};

template <class Integer>
Integer
VotableInteger <Integer>::getVotes() const
auto
VotableValue::getVotes() const
-> value_type
{
Integer ourVote = mCurrent;
value_type ourVote = mCurrent;
int weight = 0;
for (auto const& [key, val] : mVoteMap)
{
Expand Down Expand Up @@ -153,22 +152,35 @@ FeeVoteImpl::doVoting(
// LCL must be flag ledger
assert ((lastClosedLedger->info().seq % 256) == 0);

detail::VotableInteger<std::uint64_t> baseFeeVote (
lastClosedLedger->fees().base, target_.reference_fee);
detail::VotableValue baseFeeVote (
lastClosedLedger->fees().base,
target_.reference_fee);

detail::VotableInteger<std::uint32_t> baseReserveVote (
lastClosedLedger->fees().accountReserve(0).drops(), target_.account_reserve);
detail::VotableValue baseReserveVote(
lastClosedLedger->fees().accountReserve(0),
target_.account_reserve);

detail::VotableInteger<std::uint32_t> incReserveVote (
lastClosedLedger->fees().increment, target_.owner_reserve);
detail::VotableValue incReserveVote (
lastClosedLedger->fees().increment,
target_.owner_reserve);

for (auto const& val : set)
{
if (val->isTrusted ())
{
if (val->isFieldPresent (sfBaseFee))
{
baseFeeVote.addVote (val->getFieldU64 (sfBaseFee));
using xrptype = XRPAmount::value_type;
auto const vote = val->getFieldU64 (sfBaseFee);
if (vote <= std::numeric_limits<xrptype>::max() &&
isLegalAmount(XRPAmount{unsafe_cast<xrptype>(vote)}))
baseFeeVote.addVote(XRPAmount{
unsafe_cast<XRPAmount::value_type>(vote)});
else
// Invalid amounts will be treated as if they're
// not provided. Don't throw because this value is
// provided by an external entity.
baseFeeVote.noVote();
}
else
{
Expand All @@ -177,7 +189,8 @@ FeeVoteImpl::doVoting(

if (val->isFieldPresent (sfReserveBase))
{
baseReserveVote.addVote (val->getFieldU32 (sfReserveBase));
baseReserveVote.addVote(XRPAmount{
val->getFieldU32(sfReserveBase)});
}
else
{
Expand All @@ -186,7 +199,8 @@ FeeVoteImpl::doVoting(

if (val->isFieldPresent (sfReserveIncrement))
{
incReserveVote.addVote (val->getFieldU32 (sfReserveIncrement));
incReserveVote.addVote (XRPAmount{
val->getFieldU32 (sfReserveIncrement)});
}
else
{
Expand All @@ -196,15 +210,19 @@ FeeVoteImpl::doVoting(
}

// choose our positions
std::uint64_t const baseFee = baseFeeVote.getVotes ();
std::uint32_t const baseReserve = baseReserveVote.getVotes ();
std::uint32_t const incReserve = incReserveVote.getVotes ();
std::uint32_t const feeUnits = target_.reference_fee_units;
// If any of the values are invalid, send the current values.
auto const baseFee = baseFeeVote.getVotes ().dropsAs<std::uint64_t>(
lastClosedLedger->fees().base);
auto const baseReserve = baseReserveVote.getVotes ().dropsAs<std::uint32_t>(
lastClosedLedger->fees().accountReserve(0));
auto const incReserve = incReserveVote.getVotes ().dropsAs<std::uint32_t>(
lastClosedLedger->fees().increment);
constexpr FeeUnit32 feeUnits = Setup::reference_fee_units;
auto const seq = lastClosedLedger->info().seq + 1;

// add transactions to our position
if ((baseFee != lastClosedLedger->fees().base) ||
(baseReserve != lastClosedLedger->fees().accountReserve(0)) ||
(baseReserve != lastClosedLedger->fees().accountReserve(0)) ||
(incReserve != lastClosedLedger->fees().increment))
{
JLOG(journal_.warn()) <<
Expand All @@ -220,7 +238,7 @@ FeeVoteImpl::doVoting(
obj[sfBaseFee] = baseFee;
obj[sfReserveBase] = baseReserve;
obj[sfReserveIncrement] = incReserve;
obj[sfReferenceFeeUnits] = feeUnits;
obj[sfReferenceFeeUnits] = feeUnits.fee();
});

uint256 txID = feeTx.getTransactionID ();
Expand All @@ -247,9 +265,19 @@ FeeVote::Setup
setup_FeeVote (Section const& section)
{
FeeVote::Setup setup;
set (setup.reference_fee, "reference_fee", section);
set (setup.account_reserve, "account_reserve", section);
set (setup.owner_reserve, "owner_reserve", section);
{
std::uint64_t temp;
if (set(temp, "reference_fee", section) &&
temp <= std::numeric_limits<XRPAmount::value_type>::max())
setup.reference_fee = temp;
}
{
std::uint32_t temp;
if (set(temp, "account_reserve", section))
setup.account_reserve = temp;
if (set(temp, "owner_reserve", section))
setup.owner_reserve = temp;
}
return setup;
}

Expand Down
4 changes: 3 additions & 1 deletion src/ripple/app/misc/LoadFeeTrack.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#ifndef RIPPLE_CORE_LOADFEETRACK_H_INCLUDED
#define RIPPLE_CORE_LOADFEETRACK_H_INCLUDED

#include <ripple/basics/FeeUnits.h>
#include <ripple/json/json_value.h>
#include <ripple/beast/utility/Journal.h>
#include <algorithm>
Expand Down Expand Up @@ -140,7 +141,8 @@ class LoadFeeTrack final
//------------------------------------------------------------------------------

// Scale using load as well as base rate
std::uint64_t scaleFeeLoad(std::uint64_t fee, LoadFeeTrack const& feeTrack,
XRPAmount
scaleFeeLoad(FeeUnit64 fee, LoadFeeTrack const& feeTrack,
Fees const& fees, bool bUnlimited);

} // ripple
Expand Down
Loading

0 comments on commit 279eedd

Please sign in to comment.