diff --git a/docs/source.dox b/docs/source.dox index 474d437ff..fb2fa12ff 100644 --- a/docs/source.dox +++ b/docs/source.dox @@ -105,6 +105,9 @@ WARN_LOGFILE = #--------------------------------------------------------------------------- INPUT = \ \ + ../src/ripple/app/misc/TxQ.h \ + ../src/ripple/app/tx/apply.h \ + ../src/ripple/app/tx/applySteps.h \ ../src/ripple/protocol/STObject.h \ ../src/ripple/protocol/JsonFields.h \ ../src/test/jtx/AbstractClient.h \ diff --git a/src/ripple/app/misc/NetworkOPs.cpp b/src/ripple/app/misc/NetworkOPs.cpp index ded313bb9..239bd85af 100644 --- a/src/ripple/app/misc/NetworkOPs.cpp +++ b/src/ripple/app/misc/NetworkOPs.cpp @@ -1609,8 +1609,8 @@ NetworkOPsImp::ServerFeeSummary::operator !=(NetworkOPsImp::ServerFeeSummary con if(em && b.em) { - return (em->minFeeLevel != b.em->minFeeLevel || - em->expFeeLevel != b.em->expFeeLevel || + return (em->minProcessingFeeLevel != b.em->minProcessingFeeLevel || + em->openLedgerFeeLevel != b.em->openLedgerFeeLevel || em->referenceFeeLevel != b.em->referenceFeeLevel); } @@ -1653,12 +1653,12 @@ void NetworkOPsImp::pubServer () { auto const loadFactor = std::max(static_cast(f.loadFactorServer), - mulDiv(f.em->expFeeLevel, f.loadBaseServer, + mulDiv(f.em->openLedgerFeeLevel, f.loadBaseServer, f.em->referenceFeeLevel).second); jvObj [jss::load_factor] = clamp(loadFactor); - jvObj [jss::load_factor_fee_escalation] = clamp(f.em->expFeeLevel); - jvObj [jss::load_factor_fee_queue] = clamp(f.em->minFeeLevel); + jvObj [jss::load_factor_fee_escalation] = clamp(f.em->openLedgerFeeLevel); + jvObj [jss::load_factor_fee_queue] = clamp(f.em->minProcessingFeeLevel); jvObj [jss::load_factor_fee_reference] = clamp(f.em->referenceFeeLevel); @@ -2195,7 +2195,7 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin, bool counters) auto const loadFactorServer = app_.getFeeTrack().getLoadFactor(); auto const loadBaseServer = app_.getFeeTrack().getLoadBase(); auto const loadFactorFeeEscalation = escalationMetrics ? - escalationMetrics->expFeeLevel : 1; + escalationMetrics->openLedgerFeeLevel : 1; auto const loadBaseFeeEscalation = escalationMetrics ? escalationMetrics->referenceFeeLevel : 1; @@ -2221,7 +2221,7 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin, bool counters) max32, loadFactorFeeEscalation)); info[jss::load_factor_fee_queue] = static_cast (std::min( - max32, escalationMetrics->minFeeLevel)); + max32, escalationMetrics->minProcessingFeeLevel)); info[jss::load_factor_fee_reference] = static_cast (std::min( max32, loadBaseFeeEscalation)); @@ -2258,11 +2258,12 @@ Json::Value NetworkOPsImp::getServerInfo (bool human, bool admin, bool counters) info[jss::load_factor_fee_escalation] = static_cast (loadFactorFeeEscalation) / escalationMetrics->referenceFeeLevel; - if (escalationMetrics->minFeeLevel != + if (escalationMetrics->minProcessingFeeLevel != escalationMetrics->referenceFeeLevel) info[jss::load_factor_fee_queue] = - static_cast (escalationMetrics->minFeeLevel) / - escalationMetrics->referenceFeeLevel; + static_cast ( + escalationMetrics->minProcessingFeeLevel) / + escalationMetrics->referenceFeeLevel; } } diff --git a/src/ripple/app/misc/TxQ.h b/src/ripple/app/misc/TxQ.h index 1657e5deb..3530efab9 100644 --- a/src/ripple/app/misc/TxQ.h +++ b/src/ripple/app/misc/TxQ.h @@ -39,7 +39,7 @@ class Config; Once enough transactions are added to the open ledger, the required fee will jump dramatically. If additional transactions are added, - the fee will grow exponentially. + the fee will grow exponentially from there. Transactions that don't have a high enough fee to be applied to the ledger are added to the queue in order from highest fee level to @@ -47,30 +47,95 @@ class Config; are first applied from the queue to the open ledger in fee level order until either all transactions are applied or the fee again jumps too high for the remaining transactions. + + For further information and a high-level overview of how transactions + are processed with the `TxQ`, see FeeEscalation.md */ class TxQ { public: + /// Fee level for single-signed reference transaction. static constexpr std::uint64_t baseLevel = 256; + /** + Structure used to customize @ref TxQ behavior. + */ struct Setup { + /// Default constructor explicit Setup() = default; + /** Number of ledgers' worth of transactions to allow + in the queue. For example, if the last ledger had + 150 transactions, then up to 3000 transactions can + be queued. + + Can be overridden by @ref queueSizeMin + */ std::size_t ledgersInQueue = 20; + /** The smallest limit the queue is allowed. + + Will allow more than `ledgersInQueue` in the queue + if ledgers are small. + */ std::size_t queueSizeMin = 2000; + /** Extra percentage required on the fee level of a queued + transaction to replace that transaction with another + with the same sequence number. + + If queued transaction for account "Alice" with seq 45 + has a fee level of 512, a replacement transaction for + "Alice" with seq 45 must have a fee level of at least + 512 * (1 + 0.25) = 640 to be considered. + */ std::uint32_t retrySequencePercent = 25; - // TODO: eahennis. Can we remove the multi tx factor? + /** Extra percentage required on the fee level of a + queued transaction to queue the transaction with + the next sequence number. + + If queued transaction for account "Alice" with seq 45 + has a fee level of 512, a transaction with seq 46 must + have a fee level of at least + 512 * (1 + -0.90) = 51.2 ~= 52 to + be considered. + + @todo eahennis. Can we remove the multi tx factor? + */ std::int32_t multiTxnPercent = -90; + /// Minimum value of the escalation multiplier, regardless + /// of the prior ledger's median fee level. std::uint32_t minimumEscalationMultiplier = baseLevel * 500; + /// Minimum number of transactions to allow into the ledger + /// before escalation, regardless of the prior ledger's size. std::uint32_t minimumTxnInLedger = 5; + /// Like @ref minimumTxnInLedger for standalone mode. + /// Primarily so that tests don't need to worry about queuing. std::uint32_t minimumTxnInLedgerSA = 1000; + /// Number of transactions per ledger that fee escalation "works + /// towards". std::uint32_t targetTxnInLedger = 50; + /** Optional maximum allowed value of transactions per ledger before + fee escalation kicks in. By default, the maximum is an emergent + property of network, validator, and consensus performance. This + setting can override that behavior to prevent fee escalation from + allowing more than `maximumTxnInLedger` "cheap" transactions into + the open ledger. + + @todo eahennis. This setting seems to go against our goals and + values. Can it be removed? + */ boost::optional maximumTxnInLedger; + /// Maximum number of transactions that can be queued by one account. std::uint32_t maximumTxnPerAccount = 10; + /** Minimum difference between the current ledger sequence and a + transaction's `LastLedgerSequence` for the transaction to be + queueable. Decreases the chance a transaction will get queued + and broadcast only to expire before it gets a chance to be + processed. + */ std::uint32_t minimumLastLedgerBuffer = 2; - /* So we don't deal with infinite fee levels, treat - any transaction with a 0 base fee (ie. SetRegularKey + /** So we don't deal with "infinite" fee levels, treat + any transaction with a 0 base fee (ie SetRegularKey password recovery) as having this fee level. Should the network behavior change in the future such that these transactions are unable to be processed, @@ -78,56 +143,115 @@ public: bikeshedding for now. */ std::uint64_t zeroBaseFeeTransactionFeeLevel = 256000; + /// Use standalone mode behavior. bool standAlone = false; }; + /** + Structure returned by @ref TxQ::getMetrics, expressed in + reference fee level units. + */ struct Metrics { + /// Default constructor explicit Metrics() = default; - std::size_t txCount; // Transactions in the queue - boost::optional txQMaxSize; // Max txns in queue - std::size_t txInLedger; // Amount currently in the ledger - std::size_t txPerLedger; // Amount expected per ledger - std::uint64_t referenceFeeLevel; // Reference transaction fee level - std::uint64_t minFeeLevel; // Minimum fee level to get in the queue - std::uint64_t medFeeLevel; // Median fee level of the last ledger - std::uint64_t expFeeLevel; // Estimated fee level to get in next ledger + /// Number of transactions in the queue + std::size_t txCount; + /// Max transactions currently allowed in queue + boost::optional txQMaxSize; + /// Number of transactions currently in the open ledger + std::size_t txInLedger; + /// Number of transactions expected per ledger + std::size_t txPerLedger; + /// Reference transaction fee level + std::uint64_t referenceFeeLevel; + /// Minimum fee level for a transaction to be considered for + /// the open ledger or the queue + std::uint64_t minProcessingFeeLevel; + /// Median fee level of the last ledger + std::uint64_t medFeeLevel; + /// Minimum fee level to get into the current open ledger, + /// bypassing the queue + std::uint64_t openLedgerFeeLevel; }; + /** + Structure returned by @ref TxQ::getAccountTxs to describe + transactions in the queue for an account. + */ struct AccountTxDetails { + /// Default constructor explicit AccountTxDetails() = default; + /// Fee level of the queued transaction uint64_t feeLevel; + /// LastValidLedger field of the queued transaction, if any boost::optional lastValid; + /** Potential @ref TxConsequences of applying the queued transaction + to the open ledger, if known. + + @note `consequences` is lazy-computed, so may not be known at any + given time. + */ boost::optional consequences; }; + /** + Structure that describes a transaction in the queue + waiting to be applied to the current open ledger. + A collection of these is returned by @ref TxQ::getTxs. + */ struct TxDetails : AccountTxDetails { + /// Default constructor explicit TxDetails() = default; + /// The account the transaction is queued for AccountID account; + /// The full transaction std::shared_ptr txn; + /** Number of times the transactor can return a retry / `ter` result + when attempting to apply this transaction to the open ledger + from the queue. If the transactor returns `ter` and no retries are + left, this transaction will be dropped. + */ int retriesRemaining; + /** The *intermediate* result returned by @ref preflight before + this transaction was queued, or after it is queued, but before + a failed attempt to `apply` it to the open ledger. This will + usually be `tesSUCCESS`, but there are some edge cases where + it has another value. Those edge cases are interesting enough + that this value is made available here. Specifically, if the + `rules` change between attempts, `preflight` will be run again + in `TxQ::MaybeTx::apply`. + */ TER preflightResult; + /** If the transactor attempted to apply the transaction to the open + ledger from the queue and *failed*, then this is the transactor + result from the last attempt. Should never be a `tec`, `tef`, + `tem`, or `tesSUCCESS`, because those results cause the + transaction to be removed from the queue. + */ boost::optional lastResult; }; + /// Constructor TxQ(Setup const& setup, beast::Journal j); + /// Destructor virtual ~TxQ(); /** Add a new transaction to the open ledger, hold it in the queue, or reject it. - @return A pair with the TER and a bool indicating - whether or not the transaction was applied. - If the transaction is queued, will return - { terQUEUED, false }. + @return A pair with the `TER` and a `bool` indicating + whether or not the transaction was applied to + the open ledger. If the transaction is queued, + will return `{ terQUEUED, false }`. */ std::pair apply(Application& app, OpenView& view, @@ -136,17 +260,29 @@ public: /** Fill the new open ledger with transactions from the queue. - As we apply more transactions to the ledger, the required - fee will increase. - @return Whether any txs were added to the view. + @note As more transactions are applied to the ledger, the + required fee may increase. The required fee may rise above + the fee level of the queued items before the queue is emptied, + which will end the process, leaving those in the queue for + the next open ledger. + + @return Whether any transactions were added to the `view`. */ bool accept(Application& app, OpenView& view); /** - Update stats and clean up the queue in preparation for + Update fee metrics and clean up the queue in preparation for the next ledger. + + @note Fee metrics are updated based on the fee levels of the + txs in the validated ledger and whether consensus is slow. + Maximum queue size is adjusted to be enough to hold + `ledgersInQueue` ledgers or `queueSizeMin` transactions. + Any transactions for which the `LastLedgerSequence` has + passed are removed from the queue, and any account objects + that have no candidates under them are removed. */ void processClosedLedger(Application& app, @@ -154,8 +290,8 @@ public: /** Returns fee metrics in reference fee level units. - @returns Uninitialized @ref optional if the FeeEscalation - amendment is not enabled. + @returns Uninitialized boost::optional if the + FeeEscalation amendment is not enabled. */ boost::optional getMetrics(OpenView const& view, @@ -164,9 +300,9 @@ public: /** Returns information about the transactions currently in the queue for the account. - @returns Uninitialized @ref optional if the FeeEscalation - amendment is not enabled, OR if the account has no transactions - in the queue. + @returns Empty `map` if the + FeeEscalation amendment is not enabled, OR if the + account has no transactions in the queue. */ std::map getAccountTxs(AccountID const& account, ReadView const& view) const; @@ -174,46 +310,53 @@ public: /** Returns information about all transactions currently in the queue. - @returns Uninitialized @ref optional if the FeeEscalation + @returns Empty `vector` if the FeeEscalation amendment is not enabled, OR if there are no transactions in the queue. */ std::vector getTxs(ReadView const& view) const; - /** Packages up fee metrics for the `fee` RPC command. + /** Summarize current fee metrics for the `fee` RPC command. + + @returns a `Json objectvalue` */ Json::Value doRPC(Application& app) const; private: + /** + Track and use the fee escalation metrics of the + current open ledger. Does the work of scaling fees + as the open ledger grows. + */ class FeeMetrics { private: - // Fee escalation - - // Minimum value of txnsExpected. + /// Minimum value of txnsExpected. std::size_t const minimumTxnCount_; - // Limit of the txnsExpected value after a - // time leap. + /// Number of transactions per ledger that fee escalation "works + /// towards". std::size_t const targetTxnCount_; - // Maximum value of txnsExpected + /// Maximum value of txnsExpected boost::optional const maximumTxnCount_; - // Number of transactions expected per ledger. - // One more than this value will be accepted - // before escalation kicks in. + /// Number of transactions expected per ledger. + /// One more than this value will be accepted + /// before escalation kicks in. std::size_t txnsExpected_; - // Recent history of transaction counts that - // exceed the targetTxnCount_ + /// Recent history of transaction counts that + /// exceed the targetTxnCount_ boost::circular_buffer recentTxnCounts_; - // Minimum value of escalationMultiplier. + /// Minimum value of escalationMultiplier. std::uint64_t const minimumMultiplier_; - // Based on the median fee of the LCL. Used - // when fee escalation kicks in. + /// Based on the median fee of the LCL. Used + /// when fee escalation kicks in. std::uint64_t escalationMultiplier_; + /// Journal beast::Journal j_; public: + /// Constructor FeeMetrics(Setup const& setup, beast::Journal j) : minimumTxnCount_(setup.standAlone ? setup.minimumTxnInLedgerSA : @@ -236,9 +379,11 @@ private: Updates fee metrics based on the transactions in the ReadView for use in fee escalation calculations. + @param app Rippled Application object. @param view View of the LCL that was just closed or received. @param timeLeap Indicates that rippled is under load so fees should grow faster. + @param setup Customization params. */ std::size_t update(Application& app, @@ -258,6 +403,7 @@ private: std::uint64_t const escalationMultiplier; }; + /// Get the current @ref Snapshot Snapshot getSnapshot() const { @@ -267,19 +413,54 @@ private: }; } + /** Use the number of transactions in the current open ledger + to compute the fee level a transaction must pay to bypass the + 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. + */ static std::uint64_t scaleFeeLevel(Snapshot const& snapshot, OpenView const& view, std::uint32_t txCountPadding = 0); /** - Returns the total fee level for all transactions in a series. - Assumes that there are already more than txnsExpected_ txns in - the view. If there aren't, the math still works, but the level - will be high. + Computes the total fee level for all transactions in a series. + Assumes that there are already more than @ref txnsExpected_ txns + between the view and `extraCount`. If there aren't, the result + will be sensible (e.g. there won't be any underflows or + overflows), but the level will be higher than actually required. - Returns: A `std::pair` as returned from `mulDiv` indicating whether - the calculation result is safe. + @note A "series" is a set of transactions for the same account + with sequential sequence numbers. In the context of this + function, the series is already in the queue, and the series + starts with the account's current sequence number. This + function is called by @ref tryClearAccountQueue to figure + out if a newly submitted transaction is paying enough to + get all of the queued transactions plus itself out of the + queue and into the open ledger while accounting for the + escalating fee as each one is processed. The idea is that + if a series of transactions are taking too long to get out + of the queue, a user can "rescue" them without having to + resubmit each one with an individually higher fee. + + @param view Current open / working ledger. (May be a sandbox.) + @param extraCount Number of additional transactions to count as + in the ledger. (If `view` is a sandbox, should be the number of + transactions in the parent ledger.) + @param seriesSize Total number of transactions in the series to be + processed. + + @return A `std::pair` as returned from @ref `mulDiv` indicating + whether the calculation result overflows. */ static std::pair @@ -287,34 +468,65 @@ private: std::size_t extraCount, std::size_t seriesSize); }; + /** + Represents transactions in the queue which may be applied + later to the open ledger. + */ class MaybeTx { public: - // Used by the TxQ::FeeHook and TxQ::FeeMultiSet below - // to put each MaybeTx object into more than one - // set without copies, pointers, etc. + /// Used by the TxQ::FeeHook and TxQ::FeeMultiSet below + /// to put each MaybeTx object into more than one + /// set without copies, pointers, etc. boost::intrusive::set_member_hook<> byFeeListHook; + /// The complete transaction. std::shared_ptr txn; + /// Potential @ref TxConsequences of applying this transaction + /// to the open ledger. boost::optional consequences; + /// Computed fee level that the transaction will pay. uint64_t const feeLevel; + /// Transaction ID. TxID const txID; + /// Prior transaction ID (`sfAccountTxnID` field). boost::optional priorTxID; + /// Account submitting the transaction. AccountID const account; + /// Expiration ledger for the transaction + /// (`sfLastLedgerSequence` field). boost::optional lastValid; + /** + A transaction at the front of the queue will be given + several attempts to succeed before being dropped from + the queue. If dropped, one of the account's penalty + flags will be set, and other transactions may have + their `retriesRemaining` forced down as part of the + penalty. + */ int retriesRemaining; + /// Transaction sequence number (`sfSequence` field). TxSeq const sequence; + /// Flags provided to `apply`. If the transaction is later + /// attempted with different flags, it will need to be + /// `preflight`ed again. ApplyFlags const flags; boost::optional lastResult; - // Invariant: pfresult is never allowed to be empty. The - // boost::optional is leveraged to allow `emplace`d - // construction and replacement without a copy - // assignment operation. + /** Cached result of the `preflight` operation. Because + `preflight` is expensive, minimize the number of times + it needs to be done. + @invariant `pfresult` is never allowed to be empty. The + `boost::optional` is leveraged to allow `emplace`d + construction and replacement without a copy + assignment operation. + */ boost::optional pfresult; - /* In TxQ::accept, the required fee level may be low + /** Starting retry count for newly queued transactions. + + In TxQ::accept, the required fee level may be low enough that this transaction gets a chance to apply to the ledger, but it may get a retry ter result for another reason (eg. insufficient balance). When that @@ -329,33 +541,42 @@ private: static constexpr int retriesAllowed = 10; public: + /// Constructor MaybeTx(std::shared_ptr const&, TxID const& txID, std::uint64_t feeLevel, ApplyFlags const flags, PreflightResult const& pfresult); + /// Attempt to apply the queued transaction to the open ledger. std::pair apply(Application& app, OpenView& view, beast::Journal j); }; + /// Used for sorting @ref MaybeTx by `feeLevel` class GreaterFee { public: + /// Default constructor explicit GreaterFee() = default; + /// Is the fee level of `lhs` greater than the fee level of `rhs`? bool operator()(const MaybeTx& lhs, const MaybeTx& rhs) const { return lhs.feeLevel > rhs.feeLevel; } }; + /** Used to represent an account to the queue, and stores the + transactions queued for that account by sequence. + */ class TxQAccount { public: using TxMap = std::map ; + /// The account AccountID const account; - // Sequence number will be used as the key. + /// Sequence number will be used as the key. TxMap transactions; /* If this account has had any transaction retry more than `retriesAllowed` times so that it was dropped from the @@ -373,24 +594,34 @@ private: bool dropPenalty = false; public: + /// Construct from a transaction explicit TxQAccount(std::shared_ptr const& txn); + /// Construct from an account explicit TxQAccount(const AccountID& account); + /// Return the number of transactions currently queued for this account std::size_t getTxnCount() const { return transactions.size(); } + /// Checks if this account has no transactions queued bool empty() const { return !getTxnCount(); } + /// Add a transaction candidate to this account for queuing MaybeTx& add(MaybeTx&&); + /** Remove the candidate with given sequence number from this + account. + + @return Whether a candidate was removed + */ bool remove(TxSeq const& sequence); }; @@ -405,41 +636,68 @@ private: using AccountMap = std::map ; + /// Setup parameters used to control the behavior of the queue Setup const setup_; + /// Journal beast::Journal j_; - // These members must always and only be accessed under - // locked mutex_ + /** Tracks the current state of the queue. + @note This member must always and only be accessed under + locked mutex_ + */ FeeMetrics feeMetrics_; + /** The queue itself: the collection of transactions ordered + by fee level. + @note This member must always and only be accessed under + locked mutex_ + */ FeeMultiSet byFee_; + /** All of the accounts which currently have any transactions + in the queue. Entries are created and destroyed dynamically + as transactions are added and removed. + @note This member must always and only be accessed under + locked mutex_ + */ AccountMap byAccount_; + /** Maximum number of transactions allowed in the queue based + on the current metrics. If uninitialized, there is no limit, + but that condition cannot last for long in practice. + @note This member must always and only be accessed under + locked mutex_ + */ boost::optional maxSize_; - // Most queue operations are done under the master lock, - // but use this mutex for the RPC "fee" command, which isn't. + /** Most queue operations are done under the master lock, + but use this mutex for the RPC "fee" command, which isn't. + */ std::mutex mutable mutex_; private: + /// Is the queue at least `fillPercentage` full? template bool isFull() const; + /** Checks if the indicated transaction fits the conditions + for being stored in the queue. + */ bool canBeHeld(STTx const&, OpenView const&, AccountMap::iterator, boost::optional); - // Erase and return the next entry in byFee_ (lower fee level) + /// Erase and return the next entry in byFee_ (lower fee level) FeeMultiSet::iterator_type erase(FeeMultiSet::const_iterator_type); - // Erase and return the next entry for the account (if fee level - // is higher), or next entry in byFee_ (lower fee level). - // Used to get the next "applyable" MaybeTx for accept(). + /** Erase and return the next entry for the account (if fee level + is higher), or next entry in byFee_ (lower fee level). + Used to get the next "applyable" MaybeTx for accept(). + */ FeeMultiSet::iterator_type eraseAndAdvance(FeeMultiSet::const_iterator_type); - // Erase a range of items, based on TxQAccount::TxMap iterators + /// Erase a range of items, based on TxQAccount::TxMap iterators TxQAccount::TxMap::iterator erase(TxQAccount& txQAccount, TxQAccount::TxMap::const_iterator begin, TxQAccount::TxMap::const_iterator end); - /* + /** All-or-nothing attempt to try to apply all the queued txs for `accountIter` up to and including `tx`. */ @@ -454,9 +712,15 @@ private: }; +/** + Build a @ref TxQ::Setup object from application configuration. +*/ TxQ::Setup setup_TxQ(Config const&); +/** + @ref TxQ object factory. +*/ std::unique_ptr make_TxQ(TxQ::Setup const&, beast::Journal); diff --git a/src/ripple/app/misc/impl/TxQ.cpp b/src/ripple/app/misc/impl/TxQ.cpp index b3ed33a50..9ebfbe01a 100644 --- a/src/ripple/app/misc/impl/TxQ.cpp +++ b/src/ripple/app/misc/impl/TxQ.cpp @@ -1389,10 +1389,10 @@ TxQ::getMetrics(OpenView const& view, std::uint32_t txCountPadding) const result.txInLedger = view.txCount(); result.txPerLedger = snapshot.txnsExpected; result.referenceFeeLevel = baseLevel; - result.minFeeLevel = isFull() ? byFee_.rbegin()->feeLevel + 1 : + result.minProcessingFeeLevel = isFull() ? byFee_.rbegin()->feeLevel + 1 : baseLevel; result.medFeeLevel = snapshot.escalationMultiplier; - result.expFeeLevel = FeeMetrics::scaleFeeLevel(snapshot, view, + result.openLedgerFeeLevel = FeeMetrics::scaleFeeLevel(snapshot, view, txCountPadding); return result; @@ -1496,9 +1496,9 @@ TxQ::doRPC(Application& app) const ret[jss::max_queue_size] = to_string(*metrics->txQMaxSize); levels[jss::reference_level] = to_string(metrics->referenceFeeLevel); - levels[jss::minimum_level] = to_string(metrics->minFeeLevel); + levels[jss::minimum_level] = to_string(metrics->minProcessingFeeLevel); levels[jss::median_level] = to_string(metrics->medFeeLevel); - levels[jss::open_ledger_level] = to_string(metrics->expFeeLevel); + levels[jss::open_ledger_level] = to_string(metrics->openLedgerFeeLevel); auto const baseFee = view->fees().base; auto& drops = ret[jss::drops] = Json::Value(); @@ -1508,16 +1508,16 @@ TxQ::doRPC(Application& app) const metrics->referenceFeeLevel, baseFee, metrics->referenceFeeLevel).second); drops[jss::minimum_fee] = to_string(mulDiv( - metrics->minFeeLevel, baseFee, + metrics->minProcessingFeeLevel, baseFee, metrics->referenceFeeLevel).second); drops[jss::median_fee] = to_string(mulDiv( metrics->medFeeLevel, baseFee, metrics->referenceFeeLevel).second); auto escalatedFee = mulDiv( - metrics->expFeeLevel, baseFee, + metrics->openLedgerFeeLevel, baseFee, metrics->referenceFeeLevel).second; if (mulDiv(escalatedFee, metrics->referenceFeeLevel, - baseFee).second < metrics->expFeeLevel) + baseFee).second < metrics->openLedgerFeeLevel) ++escalatedFee; drops[jss::open_ledger_fee] = to_string(escalatedFee); diff --git a/src/ripple/rpc/impl/TransactionSign.cpp b/src/ripple/rpc/impl/TransactionSign.cpp index 3c1fff6e3..3faec9c14 100644 --- a/src/ripple/rpc/impl/TransactionSign.cpp +++ b/src/ripple/rpc/impl/TransactionSign.cpp @@ -707,10 +707,10 @@ Json::Value checkFee ( { auto const baseFee = ledger->fees().base; auto escalatedFee = mulDiv( - metrics->expFeeLevel, baseFee, + metrics->openLedgerFeeLevel, baseFee, metrics->referenceFeeLevel).second; if (mulDiv(escalatedFee, metrics->referenceFeeLevel, - baseFee).second < metrics->expFeeLevel) + baseFee).second < metrics->openLedgerFeeLevel) ++escalatedFee; fee = std::max(fee, escalatedFee); } diff --git a/src/test/app/TxQ_test.cpp b/src/test/app/TxQ_test.cpp index 0c165e31a..344137108 100644 --- a/src/test/app/TxQ_test.cpp +++ b/src/test/app/TxQ_test.cpp @@ -59,13 +59,13 @@ class TxQ_test : public beast::unit_test::suite BEAST_EXPECT(metrics.txQMaxSize == expectedMaxCount); BEAST_EXPECT(metrics.txInLedger == expectedInLedger); BEAST_EXPECT(metrics.txPerLedger == expectedPerLedger); - BEAST_EXPECT(metrics.minFeeLevel == expectedMinFeeLevel); + BEAST_EXPECT(metrics.minProcessingFeeLevel == expectedMinFeeLevel); BEAST_EXPECT(metrics.medFeeLevel == expectedMedFeeLevel); auto expectedCurFeeLevel = expectedInLedger > expectedPerLedger ? expectedMedFeeLevel * expectedInLedger * expectedInLedger / (expectedPerLedger * expectedPerLedger) : metrics.referenceFeeLevel; - BEAST_EXPECT(metrics.expFeeLevel == expectedCurFeeLevel); + BEAST_EXPECT(metrics.openLedgerFeeLevel == expectedCurFeeLevel); } void @@ -91,7 +91,7 @@ class TxQ_test : public beast::unit_test::suite return fee(none); // Don't care about the overflow flag - return fee(mulDiv(metrics->expFeeLevel, + return fee(mulDiv(metrics->openLedgerFeeLevel, view.fees().base, metrics->referenceFeeLevel).second + 1); } diff --git a/src/test/rpc/JSONRPC_test.cpp b/src/test/rpc/JSONRPC_test.cpp index 7ab30ac9a..a1fc6b50a 100644 --- a/src/test/rpc/JSONRPC_test.cpp +++ b/src/test/rpc/JSONRPC_test.cpp @@ -2203,7 +2203,8 @@ public: auto metrics = env.app().getTxQ().getMetrics(*env.current()); if (!BEAST_EXPECT(metrics)) break; - if (metrics->expFeeLevel > metrics->minFeeLevel) + if (metrics->openLedgerFeeLevel > + metrics->minProcessingFeeLevel) break; env(noop(env.master)); } diff --git a/src/test/rpc/LedgerRPC_test.cpp b/src/test/rpc/LedgerRPC_test.cpp index 8bc8e08f8..3170c9ff2 100644 --- a/src/test/rpc/LedgerRPC_test.cpp +++ b/src/test/rpc/LedgerRPC_test.cpp @@ -1313,7 +1313,7 @@ class LedgerRPC_test : public beast::unit_test::suite auto metrics = env.app().getTxQ().getMetrics(*env.current()); if (! BEAST_EXPECT(metrics)) break; - if (metrics->expFeeLevel > metrics->minFeeLevel) + if (metrics->openLedgerFeeLevel > metrics->minProcessingFeeLevel) break; env(noop(alice)); } diff --git a/src/test/rpc/NoRippleCheck_test.cpp b/src/test/rpc/NoRippleCheck_test.cpp index db2773d78..87b411840 100644 --- a/src/test/rpc/NoRippleCheck_test.cpp +++ b/src/test/rpc/NoRippleCheck_test.cpp @@ -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())->expFeeLevel + 1), + fee (txq.getMetrics(*env.current())->openLedgerFeeLevel + 1), sig (autofill)); env (fset (gw, asfDefaultRipple), seq (autofill), - fee (txq.getMetrics(*env.current())->expFeeLevel + 1), + fee (txq.getMetrics(*env.current())->openLedgerFeeLevel + 1), sig (autofill)); env (trust (alice, gw["USD"](10)), - fee (txq.getMetrics(*env.current())->expFeeLevel + 1)); + fee (txq.getMetrics(*env.current())->openLedgerFeeLevel + 1)); env.close(); }