mirror of
				https://github.com/Xahau/xahaud.git
				synced 2025-11-04 02:35:48 +00:00 
			
		
		
		
	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:
		
				
					committed by
					
						
						Nik Bougalis
					
				
			
			
				
	
			
			
			
						parent
						
							a96cb8fc1c
						
					
				
				
					commit
					58f786cbb4
				
			@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
        */
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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");
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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 = [&]()
 | 
			
		||||
 
 | 
			
		||||
@@ -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 ();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -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                        );
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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                                                  );
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
 
 | 
			
		||||
@@ -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.");
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -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));
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user