Make the FeeEscalation amendment permanent (RIPD-1654):

The FeeEscalation amendment has been enabled on the XRP Ledger network
since May 19, 2016. The transaction which activated this amendment is:
5B1F1E8E791A9C243DD728680F108FEF1F28F21BA3B202B8F66E7833CA71D3C3.

This change removes all conditional code based around the FeeEscalation
amendment, but leaves the amendment definition itself since removing the
definition would cause nodes to think an unknown amendment was activate
causing them to become amendment blocked.

The commit also removes the redundant precomputed hashes from the
supportedAmendments vector.
This commit is contained in:
Edward Hennis
2018-10-16 18:17:43 -04:00
committed by Nik Bougalis
parent a96cb8fc1c
commit 58f786cbb4
16 changed files with 191 additions and 325 deletions

View File

@@ -1212,8 +1212,18 @@ bool ApplicationImp::setup()
// Configure the amendments the server supports
{
auto const& sa = detail::supportedAmendments();
std::vector<std::string> saHashes;
saHashes.reserve(sa.size());
for (auto const& name : sa)
{
auto const f = getRegisteredFeature(name);
BOOST_ASSERT(f);
if (f)
saHashes.push_back(to_string(*f) + " " + name);
}
Section supportedAmendments ("Supported Amendments");
supportedAmendments.append (detail::supportedAmendments ());
supportedAmendments.append (saHashes);
Section enabledAmendments = config_->section (SECTION_AMENDMENTS);

View File

@@ -163,7 +163,7 @@ class NetworkOPsImp final
ServerFeeSummary() = default;
ServerFeeSummary(std::uint64_t fee,
boost::optional<TxQ::Metrics>&& escalationMetrics,
TxQ::Metrics&& escalationMetrics,
LoadFeeTrack const & loadFeeTrack);
bool
operator !=(ServerFeeSummary const & b) const;
@@ -1587,7 +1587,7 @@ void NetworkOPsImp::pubManifest (Manifest const& mo)
NetworkOPsImp::ServerFeeSummary::ServerFeeSummary(
std::uint64_t fee,
boost::optional<TxQ::Metrics>&& escalationMetrics,
TxQ::Metrics&& escalationMetrics,
LoadFeeTrack const & loadFeeTrack)
: loadFactorServer{loadFeeTrack.getLoadFactor()}
, loadBaseServer{loadFeeTrack.getLoadBase()}
@@ -2208,43 +2208,40 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin, bool counters)
auto const escalationMetrics = app_.getTxQ().getMetrics(
*app_.openLedger().current());
constexpr std::uint64_t max32 =
std::numeric_limits<std::uint32_t>::max();
auto const loadFactorServer = app_.getFeeTrack().getLoadFactor();
auto const loadBaseServer = app_.getFeeTrack().getLoadBase();
auto const loadFactorFeeEscalation = escalationMetrics ?
escalationMetrics->openLedgerFeeLevel : 1;
auto const loadBaseFeeEscalation = escalationMetrics ?
escalationMetrics->referenceFeeLevel : 1;
auto const loadFactorFeeEscalation =
escalationMetrics.openLedgerFeeLevel;
auto const loadBaseFeeEscalation =
escalationMetrics.referenceFeeLevel;
auto const loadFactor = std::max(static_cast<std::uint64_t>(loadFactorServer),
mulDiv(loadFactorFeeEscalation, loadBaseServer, loadBaseFeeEscalation).second);
if (!human)
{
constexpr std::uint64_t max32 =
std::numeric_limits<std::uint32_t>::max();
info[jss::load_base] = loadBaseServer;
info[jss::load_factor] = static_cast<std::uint32_t>(
std::min(max32, loadFactor));
if (escalationMetrics)
{
info[jss::load_factor_server] = loadFactorServer;
info[jss::load_factor_server] = loadFactorServer;
/* Json::Value doesn't support uint64, so clamp to max
uint32 value. This is mostly theoretical, since there
probably isn't enough extant XRP to drive the factor
that high.
*/
info[jss::load_factor_fee_escalation] =
static_cast<std::uint32_t> (std::min(
max32, loadFactorFeeEscalation));
info[jss::load_factor_fee_queue] =
static_cast<std::uint32_t> (std::min(
max32, escalationMetrics->minProcessingFeeLevel));
info[jss::load_factor_fee_reference] =
static_cast<std::uint32_t> (std::min(
max32, loadBaseFeeEscalation));
}
/* Json::Value doesn't support uint64, so clamp to max
uint32 value. This is mostly theoretical, since there
probably isn't enough extant XRP to drive the factor
that high.
*/
info[jss::load_factor_fee_escalation] =
static_cast<std::uint32_t> (std::min(
max32, loadFactorFeeEscalation));
info[jss::load_factor_fee_queue] =
static_cast<std::uint32_t> (std::min(
max32, escalationMetrics.minProcessingFeeLevel));
info[jss::load_factor_fee_reference] =
static_cast<std::uint32_t> (std::min(
max32, loadBaseFeeEscalation));
}
else
{
@@ -2269,21 +2266,18 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin, bool counters)
info[jss::load_factor_cluster] =
static_cast<double> (fee) / loadBaseServer;
}
if (escalationMetrics)
{
if (loadFactorFeeEscalation !=
escalationMetrics->referenceFeeLevel &&
(admin || loadFactorFeeEscalation != loadFactor))
info[jss::load_factor_fee_escalation] =
static_cast<double> (loadFactorFeeEscalation) /
escalationMetrics->referenceFeeLevel;
if (escalationMetrics->minProcessingFeeLevel !=
escalationMetrics->referenceFeeLevel)
info[jss::load_factor_fee_queue] =
static_cast<double> (
escalationMetrics->minProcessingFeeLevel) /
escalationMetrics->referenceFeeLevel;
}
if (loadFactorFeeEscalation !=
escalationMetrics.referenceFeeLevel &&
(admin || loadFactorFeeEscalation != loadFactor))
info[jss::load_factor_fee_escalation] =
static_cast<double> (loadFactorFeeEscalation) /
escalationMetrics.referenceFeeLevel;
if (escalationMetrics.minProcessingFeeLevel !=
escalationMetrics.referenceFeeLevel)
info[jss::load_factor_fee_queue] =
static_cast<double> (
escalationMetrics.minProcessingFeeLevel) /
escalationMetrics.referenceFeeLevel;
}
bool valid = false;

View File

@@ -315,18 +315,14 @@ public:
ReadView const& view, bool timeLeap);
/** Returns fee metrics in reference fee level units.
@returns Uninitialized boost::optional if the
FeeEscalation amendment is not enabled.
*/
boost::optional<Metrics>
Metrics
getMetrics(OpenView const& view) const;
/** Returns information about the transactions currently
in the queue for the account.
@returns Empty `map` if the
FeeEscalation amendment is not enabled, OR if the
account has no transactions in the queue.
*/
std::map<TxSeq, AccountTxDetails const>
@@ -335,8 +331,7 @@ public:
/** Returns information about all transactions currently
in the queue.
@returns Empty `vector` if the FeeEscalation
amendment is not enabled, OR if there are no transactions
@returns Empty `vector` if there are no transactions
in the queue.
*/
std::vector<TxDetails>
@@ -440,12 +435,6 @@ private:
queue.
@param view Current open ledger.
@param txCountPadding Optional number of "extra" transactions
to assume are in the ledger. Can be used to determine a
padded fee, so a transaction can pay more if the user is
concerned that more transactions will get into the open
ledger between the time this fee is computed and the
transaction is submitted.
@return A fee level value.
*/

View File

@@ -619,13 +619,6 @@ TxQ::apply(Application& app, OpenView& view,
std::shared_ptr<STTx const> const& tx,
ApplyFlags flags, beast::Journal j)
{
auto const allowEscalation =
(view.rules().enabled(featureFeeEscalation));
if (!allowEscalation)
{
return ripple::apply(app, view, *tx, flags, j);
}
auto const account = (*tx)[sfAccount];
auto const transactionID = tx->getTransactionID();
auto const tSeq = tx->getSequence();
@@ -1169,13 +1162,6 @@ void
TxQ::processClosedLedger(Application& app,
ReadView const& view, bool timeLeap)
{
auto const allowEscalation =
(view.rules().enabled(featureFeeEscalation));
if (!allowEscalation)
{
return;
}
std::lock_guard<std::mutex> lock(mutex_);
feeMetrics_.update(app, view, timeLeap, setup_);
@@ -1250,13 +1236,6 @@ bool
TxQ::accept(Application& app,
OpenView& view)
{
auto const allowEscalation =
(view.rules().enabled(featureFeeEscalation));
if (!allowEscalation)
{
return false;
}
/* Move transactions from the queue from largest fee level to smallest.
As we add more transactions, the required fee level will increase.
Stop when the transaction fee level gets lower than the required fee
@@ -1374,15 +1353,9 @@ TxQ::accept(Application& app,
return ledgerChanged;
}
auto
TxQ::Metrics
TxQ::getMetrics(OpenView const& view) const
-> boost::optional<Metrics>
{
auto const allowEscalation =
(view.rules().enabled(featureFeeEscalation));
if (!allowEscalation)
return boost::none;
Metrics result;
std::lock_guard<std::mutex> lock(mutex_);
@@ -1406,11 +1379,6 @@ auto
TxQ::getAccountTxs(AccountID const& account, ReadView const& view) const
-> std::map<TxSeq, AccountTxDetails const>
{
auto const allowEscalation =
(view.rules().enabled(featureFeeEscalation));
if (!allowEscalation)
return {};
std::lock_guard<std::mutex> lock(mutex_);
auto accountIter = byAccount_.find(account);
@@ -1440,11 +1408,6 @@ auto
TxQ::getTxs(ReadView const& view) const
-> std::vector<TxDetails>
{
auto const allowEscalation =
(view.rules().enabled(featureFeeEscalation));
if (!allowEscalation)
return {};
std::lock_guard<std::mutex> lock(mutex_);
if (byFee_.empty())
@@ -1483,45 +1446,48 @@ TxQ::doRPC(Application& app) const
using std::to_string;
auto const view = app.openLedger().current();
auto const metrics = getMetrics(*view);
if (!view)
{
BOOST_ASSERT(false);
return {};
}
if (!metrics)
return{};
auto const metrics = getMetrics(*view);
Json::Value ret(Json::objectValue);
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);
if (metrics->txQMaxSize)
ret[jss::max_queue_size] = to_string(*metrics->txQMaxSize);
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);
if (metrics.txQMaxSize)
ret[jss::max_queue_size] = to_string(*metrics.txQMaxSize);
levels[jss::reference_level] = to_string(metrics->referenceFeeLevel);
levels[jss::minimum_level] = to_string(metrics->minProcessingFeeLevel);
levels[jss::median_level] = to_string(metrics->medFeeLevel);
levels[jss::open_ledger_level] = to_string(metrics->openLedgerFeeLevel);
levels[jss::reference_level] = to_string(metrics.referenceFeeLevel);
levels[jss::minimum_level] = to_string(metrics.minProcessingFeeLevel);
levels[jss::median_level] = to_string(metrics.medFeeLevel);
levels[jss::open_ledger_level] = to_string(metrics.openLedgerFeeLevel);
auto const baseFee = view->fees().base;
auto& drops = ret[jss::drops] = Json::Value();
// Don't care about the overflow flags
drops[jss::base_fee] = to_string(mulDiv(
metrics->referenceFeeLevel, baseFee,
metrics->referenceFeeLevel).second);
metrics.referenceFeeLevel, baseFee,
metrics.referenceFeeLevel).second);
drops[jss::minimum_fee] = to_string(mulDiv(
metrics->minProcessingFeeLevel, baseFee,
metrics->referenceFeeLevel).second);
metrics.minProcessingFeeLevel, baseFee,
metrics.referenceFeeLevel).second);
drops[jss::median_fee] = to_string(mulDiv(
metrics->medFeeLevel, baseFee,
metrics->referenceFeeLevel).second);
metrics.medFeeLevel, baseFee,
metrics.referenceFeeLevel).second);
auto escalatedFee = mulDiv(
metrics->openLedgerFeeLevel, baseFee,
metrics->referenceFeeLevel).second;
if (mulDiv(escalatedFee, metrics->referenceFeeLevel,
baseFee).second < metrics->openLedgerFeeLevel)
metrics.openLedgerFeeLevel, baseFee,
metrics.referenceFeeLevel).second;
if (mulDiv(escalatedFee, metrics.referenceFeeLevel,
baseFee).second < metrics.openLedgerFeeLevel)
++escalatedFee;
drops[jss::open_ledger_fee] = to_string(escalatedFee);

View File

@@ -342,7 +342,6 @@ foreachFeature(FeatureBitset bs, F&& f)
extern uint256 const featureMultiSign;
extern uint256 const featureTickets;
extern uint256 const featureTrustSetAuth;
extern uint256 const featureFeeEscalation;
extern uint256 const featureOwnerPaysFee;
extern uint256 const featureCompareFlowV1V2;
extern uint256 const featureSHAMapV2;

View File

@@ -84,39 +84,39 @@ detail::supportedAmendments ()
// uncommented at that time).
static std::vector<std::string> const supported
{
// { "C6970A8B603D8778783B61C0D445C23D1633CCFAEF0D43E7DBCD1521D34BD7C3 SHAMapV2" },
{ "4C97EBA926031A7CF7D7B36FDE3ED66DDA5421192D63DE53FFB46E43B9DC8373 MultiSign" },
// { "C1B8D934087225F509BEB5A8EC24447854713EE447D277F69545ABFA0E0FD490 Tickets" },
{ "6781F8368C4771B83E8B821D88F580202BCB4228075297B19E4FDC5233F1EFDC TrustSetAuth" },
{ "42426C4D4F1009EE67080A9B7965B44656D7714D104A72F9B4369F97ABF044EE FeeEscalation" },
// { "9178256A980A86CF3D70D0260A7DA6402AAFE43632FDBCB88037978404188871 OwnerPaysFee" },
{ "08DE7D96082187F6E6578530258C77FAABABE4C20474BDB82F04B021F1A68647 PayChan" },
{ "740352F2412A9909880C23A559FCECEDA3BE2126FED62FC7660D628A06927F11 Flow" },
{ "1562511F573A19AE9BD103B5D6B9E01B3B46805AEC5D3C4805C902B514399146 CryptoConditions" },
{ "532651B4FD58DF8922A49BA101AB3E996E5BFBF95A913B3E392504863E63B164 TickSize" },
{ "E2E6F2866106419B88C50045ACE96368558C345566AC8F2BDF5A5B5587F0E6FA fix1368" },
{ "07D43DCE529B15A10827E5E04943B496762F9A88E3268269D69C44BE49E21104 Escrow" },
{ "86E83A7D2ECE3AD5FA87AB2195AE015C950469ABF0B72EAACED318F74886AE90 CryptoConditionsSuite" },
{ "42EEA5E28A97824821D4EF97081FE36A54E9593C6E4F20CBAE098C69D2E072DC fix1373" },
{ "DC9CA96AEA1DCF83E527D1AFC916EFAF5D27388ECA4060A88817C1238CAEE0BF EnforceInvariants" },
{ "3012E8230864E95A58C60FD61430D7E1B4D3353195F2981DC12B0C7C0950FFAC FlowCross" },
{ "CC5ABAE4F3EC92E94A59B1908C2BE82D2228B6485C00AFF8F22DF930D89C194E SortedDirectories" },
{ "B4D44CC3111ADD964E846FC57760C8B50FFCD5A82C86A72756F6B058DDDF96AD fix1201" },
{ "6C92211186613F9647A89DFFBAB8F94C99D4C7E956D495270789128569177DA1 fix1512" },
{ "67A34F2CF55BFC0F93AACD5B281413176FEE195269FA6D95219A2DF738671172 fix1513" },
{ "B9E739B8296B4A1BB29BE990B17D66E21B62A300A909F25AC55C22D6C72E1F9D fix1523" },
{ "1D3463A5891F9E589C5AE839FFAC4A917CE96197098A1EF22304E1BC5B98A454 fix1528" },
{ "F64E1EABBE79D55B3BB82020516CEC2C582A98A6BFE20FBE9BB6A0D233418064 DepositAuth" },
{ "157D2D480E006395B76F948E3E07A45A05FE10230D88A7993C71F97AE4B1F2D1 Checks" },
{ "7117E2EC2DBF119CA55181D69819F1999ECEE1A0225A7FD2B9ED47940968479C fix1571" },
{ "CA7C02118BA27599528543DFE77BA6838D1B0F43B447D4D7F53523CE6A0E9AC2 fix1543" },
{ "58BE9B5968C4DA7C59BA900961828B113E5490699B21877DEF9A31E9D0FE5D5F fix1623" },
{ "3CBC5C4E630A1B82380295CDA84B32B49DD066602E74E39B85EF64137FA65194 DepositPreauth" },
// "SHAMapV2",
"MultiSign",
// "Tickets",
"TrustSetAuth",
"FeeEscalation", // Looks unused, but do not remove; Servers will be amendment blocked.
// "OwnerPaysFee",
"PayChan",
"Flow",
"CryptoConditions",
"TickSize",
"fix1368",
"Escrow",
"CryptoConditionsSuite",
"fix1373",
"EnforceInvariants",
"FlowCross",
"SortedDirectories",
"fix1201",
"fix1512",
"fix1513",
"fix1523",
"fix1528",
"DepositAuth",
"Checks",
"fix1571",
"fix1543",
"fix1623",
"DepositPreauth",
// Use liquidity from strands that consume max offers, but mark as dry
{ "5D08145F0A4983F23AFFFF514E83FAD355C5ABFBB6CAB76FB5BC8519FF5F33BE fix1515" },
{ "FBD513F1B893AC765B78F250E6FFA6A11B573209D1842ADC787C850696741288 fix1578" },
{ "586480873651E106F1D6339B0C4A8945BA705A777F3F4524626FF1FC07EFE41D MultiSignReserve" },
{ "2CD5286D8D687E98B41102BDD797198E81EA41DF7BD104E6561FEB104EFF2561 fixTakerDryOfferRemoval"}
"fix1515",
"fix1578",
"MultiSignReserve",
"fixTakerDryOfferRemoval"
};
return supported;
}
@@ -143,7 +143,6 @@ uint256 bitsetIndexToFeature(size_t i)
uint256 const featureMultiSign = *getRegisteredFeature("MultiSign");
uint256 const featureTickets = *getRegisteredFeature("Tickets");
uint256 const featureTrustSetAuth = *getRegisteredFeature("TrustSetAuth");
uint256 const featureFeeEscalation = *getRegisteredFeature("FeeEscalation");
uint256 const featureOwnerPaysFee = *getRegisteredFeature("OwnerPaysFee");
uint256 const featureCompareFlowV1V2 = *getRegisteredFeature("CompareFlowV1V2");
uint256 const featureSHAMapV2 = *getRegisteredFeature("SHAMapV2");

View File

@@ -28,15 +28,6 @@ namespace ripple
{
Json::Value doFee(RPC::Context& context)
{
// Bail if fee escalation is not enabled.
auto const view = context.app.openLedger().current();
BOOST_ASSERT(view);
if (!view || !view->rules().enabled(featureFeeEscalation))
{
RPC::inject_error(rpcNOT_ENABLED, context.params);
return context.params;
}
auto result = context.app.getTxQ().doRPC(context.app);
if (result.type() == Json::objectValue)
return result;

View File

@@ -700,17 +700,14 @@ Json::Value checkFee (
std::uint64_t fee = loadFee;
{
auto const metrics = txQ.getMetrics(*ledger);
if(metrics)
{
auto const baseFee = ledger->fees().base;
auto escalatedFee = mulDiv(
metrics->openLedgerFeeLevel, baseFee,
metrics->referenceFeeLevel).second;
if (mulDiv(escalatedFee, metrics->referenceFeeLevel,
baseFee).second < metrics->openLedgerFeeLevel)
++escalatedFee;
fee = std::max(fee, escalatedFee);
}
auto const baseFee = ledger->fees().base;
auto escalatedFee = mulDiv(
metrics.openLedgerFeeLevel, baseFee,
metrics.referenceFeeLevel).second;
if (mulDiv(escalatedFee, metrics.referenceFeeLevel,
baseFee).second < metrics.openLedgerFeeLevel)
++escalatedFee;
fee = std::max(fee, escalatedFee);
}
auto const limit = [&]()

View File

@@ -737,16 +737,6 @@ public:
}
}
void
testSupportedAmendments ()
{
for (auto const& amend : detail::supportedAmendments ())
{
auto const f = getRegisteredFeature(amend.substr (65));
BEAST_EXPECT(f && amend.substr (0, 64) == to_string (*f));
}
}
void testHasUnsupported ()
{
testcase ("hasUnsupportedEnabled");
@@ -772,7 +762,6 @@ public:
testVoteEnable ();
testDetectMajority ();
testLostMajority ();
testSupportedAmendments ();
testHasUnsupported ();
}
};

View File

@@ -1297,26 +1297,20 @@ struct Flow_manual_test : public Flow_test
{
using namespace jtx;
auto const all = supported_amendments();
FeatureBitset const feeEscalation{featureFeeEscalation};
FeatureBitset const flow{featureFlow};
FeatureBitset const f1373{fix1373};
FeatureBitset const flowCross{featureFlowCross};
FeatureBitset const f1513{fix1513};
testWithFeats(all - feeEscalation - flow - f1373 - flowCross - f1513);
testWithFeats(all - flow - f1373 - flowCross - f1513);
testWithFeats(all - flow - f1373 - flowCross );
testWithFeats(all - feeEscalation - f1373 - flowCross - f1513);
testWithFeats(all - f1373 - flowCross - f1513);
testWithFeats(all - f1373 - flowCross );
testWithFeats(all - feeEscalation - flowCross - f1513);
testWithFeats(all - flowCross - f1513);
testWithFeats(all - flowCross );
testWithFeats(all - feeEscalation - f1513);
testWithFeats(all - f1513);
testWithFeats(all );
testEmptyStrand(all - feeEscalation - f1513);
testEmptyStrand(all - f1513);
testEmptyStrand(all );
}

View File

@@ -286,8 +286,7 @@ public:
d * env.closed()->info().closeTimeResolution;
env.close (closeTime);
*stAmountCalcSwitchover = closeTime > STAmountSO::soTime ||
(hasFeature(env, featureFeeEscalation) &&
!hasFeature(env, fix1513));
!hasFeature(env, fix1513);
// Will fail without the underflow fix
TER const expectedResult = *stAmountCalcSwitchover ?
TER {tesSUCCESS} : TER {tecPATH_PARTIAL};
@@ -328,8 +327,7 @@ public:
for (auto withFix : {false, true})
{
if (!withFix &&
(features[featureFlow] || features[featureFeeEscalation]))
if (!withFix)
continue;
Env env {*this, features};
@@ -4738,29 +4736,22 @@ class Offer_manual_test : public Offer_test
{
using namespace jtx;
FeatureBitset const all{supported_amendments()};
FeatureBitset const feeEscalation{featureFeeEscalation};
FeatureBitset const flow{featureFlow};
FeatureBitset const f1373{fix1373};
FeatureBitset const flowCross{featureFlowCross};
FeatureBitset const f1513{fix1513};
FeatureBitset const takerDryOffer{fixTakerDryOfferRemoval};
testAll(all -feeEscalation - flow - f1373 - flowCross - f1513);
testAll(all - flow - f1373 - flowCross - f1513);
testAll(all - flow - f1373 - flowCross );
testAll(all -feeEscalation - flow - f1373 - f1513);
testAll(all - flow - f1373 - f1513);
testAll(all - flow - f1373 );
testAll(all -feeEscalation - f1373 - flowCross - f1513);
testAll(all - f1373 - flowCross - f1513);
testAll(all - f1373 - flowCross );
testAll(all -feeEscalation - f1373 - f1513);
testAll(all - f1373 - f1513);
testAll(all - f1373 );
testAll(all -feeEscalation - flowCross - f1513);
testAll(all - flowCross - f1513);
testAll(all - flowCross );
testAll(all -feeEscalation - f1513);
testAll(all - f1513);
testAll(all );

View File

@@ -50,10 +50,7 @@ class TxQ_test : public beast::unit_test::suite
std::uint64_t expectedMinFeeLevel,
std::uint64_t expectedMedFeeLevel = 256 * 500)
{
auto optMetrics = env.app().getTxQ().getMetrics(*env.current());
if (!BEAST_EXPECT(optMetrics))
return;
auto& metrics = *optMetrics;
auto const metrics = env.app().getTxQ().getMetrics(*env.current());
BEAST_EXPECT(metrics.referenceFeeLevel == 256);
BEAST_EXPECT(metrics.txCount == expectedCount);
BEAST_EXPECT(metrics.txQMaxSize == expectedMaxCount);
@@ -74,9 +71,7 @@ class TxQ_test : public beast::unit_test::suite
jtx::Account const& account)
{
auto metrics = env.app().getTxQ().getMetrics(*env.current());
if (!BEAST_EXPECT(metrics))
return;
for (int i = metrics->txInLedger; i <= metrics->txPerLedger; ++i)
for (int i = metrics.txInLedger; i <= metrics.txPerLedger; ++i)
env(noop(account));
}
@@ -87,12 +82,10 @@ class TxQ_test : public beast::unit_test::suite
auto const& view = *env.current();
auto metrics = env.app().getTxQ().getMetrics(view);
if (!BEAST_EXPECT(metrics))
return fee(none);
// Don't care about the overflow flag
return fee(mulDiv(metrics->openLedgerFeeLevel,
view.fees().base, metrics->referenceFeeLevel).second + 1);
return fee(mulDiv(metrics.openLedgerFeeLevel,
view.fees().base, metrics.referenceFeeLevel).second + 1);
}
static
@@ -328,21 +321,21 @@ public:
// test ends and the TxQ is destructed.
auto metrics = txq.getMetrics(*env.current());
BEAST_EXPECT(metrics->txCount == 0);
BEAST_EXPECT(metrics.txCount == 0);
// Stuff the ledger.
for (int i = metrics->txInLedger; i <= metrics->txPerLedger; ++i)
for (int i = metrics.txInLedger; i <= metrics.txPerLedger; ++i)
{
env(noop(env.master));
}
// Queue one straightforward transaction
env(noop(env.master), fee(20), queued);
++metrics->txCount;
++metrics.txCount;
checkMetrics(env, metrics->txCount,
metrics->txQMaxSize, metrics->txPerLedger + 1,
metrics->txPerLedger,
checkMetrics(env, metrics.txCount,
metrics.txQMaxSize, metrics.txPerLedger + 1,
metrics.txPerLedger,
256);
}
@@ -1098,28 +1091,6 @@ public:
BEAST_EXPECT(elmoSeq == env.seq(elmo));
}
void testDisabled()
{
using namespace jtx;
Env env(*this, FeatureBitset{});
auto alice = Account("alice");
BEAST_EXPECT(!env.app().getTxQ().getMetrics(*env.current()));
env.fund(XRP(50000), noripple(alice));
// If the queue was enabled, most of these would
// return terQUEUED. (The required fee for the last
// would be 10 * 500 * 11^2 / 5^2 = 24,200.)
for (int i = 0; i < 10; ++i)
env(noop(alice), fee(30));
env.close();
BEAST_EXPECT(!env.app().getTxQ().getMetrics(*env.current()));
}
void testAcctTxnID()
{
using namespace jtx;
@@ -1658,76 +1629,59 @@ public:
void testRPC()
{
using namespace jtx;
Env env(*this);
auto fee = env.rpc("fee");
if (BEAST_EXPECT(fee.isMember(jss::result)) &&
BEAST_EXPECT(!RPC::contains_error(fee[jss::result])))
{
Env env(*this);
auto fee = env.rpc("fee");
if (BEAST_EXPECT(fee.isMember(jss::result) &&
BEAST_EXPECT(!RPC::contains_error(fee[jss::result]))))
{
auto const& result = fee[jss::result];
BEAST_EXPECT(result.isMember(jss::ledger_current_index)
&& result[jss::ledger_current_index] == 3);
BEAST_EXPECT(result.isMember(jss::current_ledger_size));
BEAST_EXPECT(result.isMember(jss::current_queue_size));
BEAST_EXPECT(result.isMember(jss::expected_ledger_size));
BEAST_EXPECT(!result.isMember(jss::max_queue_size));
BEAST_EXPECT(result.isMember(jss::drops));
auto const& drops = result[jss::drops];
BEAST_EXPECT(drops.isMember(jss::base_fee));
BEAST_EXPECT(drops.isMember(jss::median_fee));
BEAST_EXPECT(drops.isMember(jss::minimum_fee));
BEAST_EXPECT(drops.isMember(jss::open_ledger_fee));
BEAST_EXPECT(result.isMember(jss::levels));
auto const& levels = result[jss::levels];
BEAST_EXPECT(levels.isMember(jss::median_level));
BEAST_EXPECT(levels.isMember(jss::minimum_level));
BEAST_EXPECT(levels.isMember(jss::open_ledger_level));
BEAST_EXPECT(levels.isMember(jss::reference_level));
}
env.close();
fee = env.rpc("fee");
if (BEAST_EXPECT(fee.isMember(jss::result) &&
BEAST_EXPECT(!RPC::contains_error(fee[jss::result]))))
{
auto const& result = fee[jss::result];
BEAST_EXPECT(result.isMember(jss::ledger_current_index)
&& result[jss::ledger_current_index] == 4);
BEAST_EXPECT(result.isMember(jss::current_ledger_size));
BEAST_EXPECT(result.isMember(jss::current_queue_size));
BEAST_EXPECT(result.isMember(jss::expected_ledger_size));
BEAST_EXPECT(result.isMember(jss::max_queue_size));
auto const& drops = result[jss::drops];
BEAST_EXPECT(drops.isMember(jss::base_fee));
BEAST_EXPECT(drops.isMember(jss::median_fee));
BEAST_EXPECT(drops.isMember(jss::minimum_fee));
BEAST_EXPECT(drops.isMember(jss::open_ledger_fee));
BEAST_EXPECT(result.isMember(jss::levels));
auto const& levels = result[jss::levels];
BEAST_EXPECT(levels.isMember(jss::median_level));
BEAST_EXPECT(levels.isMember(jss::minimum_level));
BEAST_EXPECT(levels.isMember(jss::open_ledger_level));
BEAST_EXPECT(levels.isMember(jss::reference_level));
}
auto const& result = fee[jss::result];
BEAST_EXPECT(result.isMember(jss::ledger_current_index)
&& result[jss::ledger_current_index] == 3);
BEAST_EXPECT(result.isMember(jss::current_ledger_size));
BEAST_EXPECT(result.isMember(jss::current_queue_size));
BEAST_EXPECT(result.isMember(jss::expected_ledger_size));
BEAST_EXPECT(!result.isMember(jss::max_queue_size));
BEAST_EXPECT(result.isMember(jss::drops));
auto const& drops = result[jss::drops];
BEAST_EXPECT(drops.isMember(jss::base_fee));
BEAST_EXPECT(drops.isMember(jss::median_fee));
BEAST_EXPECT(drops.isMember(jss::minimum_fee));
BEAST_EXPECT(drops.isMember(jss::open_ledger_fee));
BEAST_EXPECT(result.isMember(jss::levels));
auto const& levels = result[jss::levels];
BEAST_EXPECT(levels.isMember(jss::median_level));
BEAST_EXPECT(levels.isMember(jss::minimum_level));
BEAST_EXPECT(levels.isMember(jss::open_ledger_level));
BEAST_EXPECT(levels.isMember(jss::reference_level));
}
env.close();
fee = env.rpc("fee");
if (BEAST_EXPECT(fee.isMember(jss::result)) &&
BEAST_EXPECT(!RPC::contains_error(fee[jss::result])))
{
Env env(*this, FeatureBitset{});
auto fee = env.rpc("fee");
if(BEAST_EXPECT(fee.isMember(jss::result) &&
RPC::contains_error(fee[jss::result])))
{
auto const& result = fee[jss::result];
BEAST_EXPECT(result.isMember(jss::error) &&
result[jss::error] ==
RPC::get_error_info(rpcNOT_ENABLED).token);
}
auto const& result = fee[jss::result];
BEAST_EXPECT(result.isMember(jss::ledger_current_index)
&& result[jss::ledger_current_index] == 4);
BEAST_EXPECT(result.isMember(jss::current_ledger_size));
BEAST_EXPECT(result.isMember(jss::current_queue_size));
BEAST_EXPECT(result.isMember(jss::expected_ledger_size));
BEAST_EXPECT(result.isMember(jss::max_queue_size));
auto const& drops = result[jss::drops];
BEAST_EXPECT(drops.isMember(jss::base_fee));
BEAST_EXPECT(drops.isMember(jss::median_fee));
BEAST_EXPECT(drops.isMember(jss::minimum_fee));
BEAST_EXPECT(drops.isMember(jss::open_ledger_fee));
BEAST_EXPECT(result.isMember(jss::levels));
auto const& levels = result[jss::levels];
BEAST_EXPECT(levels.isMember(jss::median_level));
BEAST_EXPECT(levels.isMember(jss::minimum_level));
BEAST_EXPECT(levels.isMember(jss::open_ledger_level));
BEAST_EXPECT(levels.isMember(jss::reference_level));
}
}
@@ -2617,16 +2571,16 @@ public:
auto const metrics = env.app ().getTxQ ().getMetrics (
*env.current ());
if (!numToClear)
numToClear.emplace(metrics->txCount + 1);
numToClear.emplace(metrics.txCount + 1);
for (int i = 0; i < *numToClear; ++i)
{
auto inLedger = metrics->txInLedger + i;
auto inLedger = metrics.txInLedger + i;
totalFactor += inLedger * inLedger;
}
auto result =
mulDiv (metrics->medFeeLevel * totalFactor /
(metrics->txPerLedger * metrics->txPerLedger),
env.current ()->fees ().base, metrics->referenceFeeLevel)
mulDiv (metrics.medFeeLevel * totalFactor /
(metrics.txPerLedger * metrics.txPerLedger),
env.current ()->fees ().base, metrics.referenceFeeLevel)
.second;
// Subtract the fees already paid
result -= alreadyPaid;
@@ -2698,7 +2652,7 @@ public:
auto const metrics = env.app ().getTxQ ().getMetrics (
*env.current ());
std::uint64_t const totalFee =
calcTotalFee (100 * 2, metrics->txCount);
calcTotalFee (100 * 2, metrics.txCount);
BEAST_EXPECT(totalFee == 167578);
// Replacing the last tx with the large fee succeeds.
--aliceSeq;
@@ -2944,7 +2898,6 @@ public:
testQueuedFailure();
testMultiTxnPerAccount();
testTieBreaking();
testDisabled();
testAcctTxnID();
testMaximum();
testUnexpectedBalanceChange();

View File

@@ -77,7 +77,7 @@ supported_amendments()
feats.reserve(sa.size());
for (auto const& s : sa)
{
if (auto const f = getRegisteredFeature(s.substr(65)))
if (auto const f = getRegisteredFeature(s))
feats.push_back(*f);
else
Throw<std::runtime_error> ("Unknown feature: " + s + " in supportedAmendments.");

View File

@@ -2142,10 +2142,8 @@ public:
for (;;)
{
auto metrics = env.app().getTxQ().getMetrics(*env.current());
if (!BEAST_EXPECT(metrics))
break;
if (metrics->openLedgerFeeLevel >
metrics->minProcessingFeeLevel)
if (metrics.openLedgerFeeLevel >
metrics.minProcessingFeeLevel)
break;
env(noop(env.master));
}
@@ -2199,10 +2197,8 @@ public:
for (;;)
{
auto metrics = env.app().getTxQ().getMetrics(*env.current());
if (!BEAST_EXPECT(metrics))
break;
if (metrics->openLedgerFeeLevel >
metrics->minProcessingFeeLevel)
if (metrics.openLedgerFeeLevel >
metrics.minProcessingFeeLevel)
break;
env(noop(env.master), fee(47));
}

View File

@@ -1314,9 +1314,7 @@ class LedgerRPC_test : public beast::unit_test::suite
for (;;)
{
auto metrics = env.app().getTxQ().getMetrics(*env.current());
if (! BEAST_EXPECT(metrics))
break;
if (metrics->openLedgerFeeLevel > metrics->minProcessingFeeLevel)
if (metrics.openLedgerFeeLevel > metrics.minProcessingFeeLevel)
break;
env(noop(alice));
}

View File

@@ -290,14 +290,14 @@ class NoRippleCheckLimits_test : public beast::unit_test::suite
env.memoize(gw);
env (pay (env.master, gw, XRP(1000)),
seq (autofill),
fee (txq.getMetrics(*env.current())->openLedgerFeeLevel + 1),
fee (txq.getMetrics(*env.current()).openLedgerFeeLevel + 1),
sig (autofill));
env (fset (gw, asfDefaultRipple),
seq (autofill),
fee (txq.getMetrics(*env.current())->openLedgerFeeLevel + 1),
fee (txq.getMetrics(*env.current()).openLedgerFeeLevel + 1),
sig (autofill));
env (trust (alice, gw["USD"](10)),
fee (txq.getMetrics(*env.current())->openLedgerFeeLevel + 1));
fee (txq.getMetrics(*env.current()).openLedgerFeeLevel + 1));
env.close();
}