3#include <xrpld/app/ledger/Ledger.h> 
    4#include <xrpld/app/misc/FeeVote.h> 
    5#include <xrpld/app/tx/apply.h> 
    7#include <xrpl/basics/BasicConfig.h> 
    8#include <xrpl/ledger/View.h> 
    9#include <xrpl/protocol/Feature.h> 
   10#include <xrpl/protocol/Indexes.h> 
   11#include <xrpl/protocol/PublicKey.h> 
   12#include <xrpl/protocol/STTx.h> 
   13#include <xrpl/protocol/SecretKey.h> 
   35    auto fill = [&](
auto& obj) {
 
   37        obj.setFieldU32(sfLedgerSequence, 
seq);
 
   39        if (rules.
enabled(featureXRPFees))
 
   50                sfReserveIncrementDrops,
 
   68    return STTx(ttFEE, fill);
 
 
   75    bool missingRequiredFields = 
true,
 
   76    bool wrongFeatureFields = 
false,
 
   79    auto fill = [&](
auto& obj) {
 
   81        obj.setFieldU32(sfLedgerSequence, 
seq);
 
   83        if (wrongFeatureFields)
 
   85            if (rules.
enabled(featureXRPFees))
 
   87                obj.setFieldU64(sfBaseFee, 10 + uniqueValue);
 
   88                obj.setFieldU32(sfReserveBase, 200000);
 
   89                obj.setFieldU32(sfReserveIncrement, 50000);
 
   90                obj.setFieldU32(sfReferenceFeeUnits, 10);
 
   94                obj.setFieldAmount(sfBaseFeeDrops, 
XRPAmount{10 + uniqueValue});
 
   95                obj.setFieldAmount(sfReserveBaseDrops, 
XRPAmount{200000});
 
   96                obj.setFieldAmount(sfReserveIncrementDrops, 
XRPAmount{50000});
 
   99        else if (!missingRequiredFields)
 
  102            if (rules.
enabled(featureXRPFees))
 
  104                obj.setFieldAmount(sfBaseFeeDrops, 
XRPAmount{10 + uniqueValue});
 
  105                obj.setFieldAmount(sfReserveBaseDrops, 
XRPAmount{200000});
 
  106                obj.setFieldAmount(sfReserveIncrementDrops, 
XRPAmount{50000});
 
  110                obj.setFieldU64(sfBaseFee, 10 + uniqueValue);
 
  111                obj.setFieldU32(sfReserveBase, 200000);
 
  112                obj.setFieldU32(sfReserveIncrement, 50000);
 
  113                obj.setFieldU32(sfReferenceFeeUnits, 10);
 
  119    return STTx(ttFEE, fill);
 
 
  140    auto checkEquality = [&](
auto const& field, 
auto const& expected) {
 
  141        if (!feeObject->isFieldPresent(field))
 
  143        return feeObject->at(field) == expected;
 
  146    if (rules.
enabled(featureXRPFees))
 
  148        if (feeObject->isFieldPresent(sfBaseFee) ||
 
  149            feeObject->isFieldPresent(sfReserveBase) ||
 
  150            feeObject->isFieldPresent(sfReserveIncrement) ||
 
  151            feeObject->isFieldPresent(sfReferenceFeeUnits))
 
  162                sfReserveIncrementDrops,
 
  168        if (feeObject->isFieldPresent(sfBaseFeeDrops) ||
 
  169            feeObject->isFieldPresent(sfReserveBaseDrops) ||
 
  170            feeObject->isFieldPresent(sfReserveIncrementDrops))
 
  174        if (!checkEquality(sfBaseFee, expected.
baseFee))
 
  176        if (!checkEquality(sfReserveBase, expected.
reserveBase))
 
 
  191    for (
auto i = txSet->begin(); i != txSet->end(); ++i)
 
  193        auto const data = i->slice();
 
 
  210            BEAST_EXPECT(setup.reference_fee == defaultSetup.
reference_fee);
 
  212            BEAST_EXPECT(setup.owner_reserve == defaultSetup.
owner_reserve);
 
  217                {
"reference_fee = 50",
 
  218                 "account_reserve = 1234567",
 
  219                 "owner_reserve = 1234"});
 
  221            BEAST_EXPECT(setup.reference_fee == 50);
 
  222            BEAST_EXPECT(setup.account_reserve == 1234567);
 
  223            BEAST_EXPECT(setup.owner_reserve == 1234);
 
  228                {
"reference_fee = blah",
 
  229                 "account_reserve = yada",
 
  230                 "owner_reserve = foo"});
 
  233            BEAST_EXPECT(setup.reference_fee == defaultSetup.
reference_fee);
 
  235            BEAST_EXPECT(setup.owner_reserve == defaultSetup.
owner_reserve);
 
  240                {
"reference_fee = -50",
 
  241                 "account_reserve = -1234567",
 
  242                 "owner_reserve = -1234"});
 
  245            BEAST_EXPECT(setup.reference_fee == defaultSetup.
reference_fee);
 
  247                setup.account_reserve == 
static_cast<std::uint32_t>(-1234567));
 
  258                {
"reference_fee = " + big64,
 
  259                 "account_reserve = " + big64,
 
  260                 "owner_reserve = " + big64});
 
  263            BEAST_EXPECT(setup.reference_fee == defaultSetup.
reference_fee);
 
  265            BEAST_EXPECT(setup.owner_reserve == defaultSetup.
owner_reserve);
 
 
  272        testcase(
"Basic SetFee transaction");
 
  291                .reserveBase = 200000,
 
  292                .reserveIncrement = 50000,
 
  293                .referenceFeeUnits = 10};
 
  294            auto feeTx = 
createFeeTx(ledger->rules(), ledger->seq(), fields);
 
  298            accum.
apply(*ledger);
 
  320                .reserveIncrementDrops = 
XRPAmount{50000}};
 
  322            auto feeTx = 
createFeeTx(ledger->rules(), ledger->seq(), fields);
 
  326            accum.
apply(*ledger);
 
 
  336        testcase(
"Fee Transaction Validation");
 
  352                ledger->rules(), ledger->seq(), 
true, 
false, 1);
 
  358                ledger->rules(), ledger->seq(), 
false, 
true, 2);
 
  376                ledger->rules(), ledger->seq(), 
true, 
false, 3);
 
  382                ledger->rules(), ledger->seq(), 
false, 
true, 4);
 
 
  390        testcase(
"Pseudo Transaction Properties");
 
  406            {.baseFeeDrops = XRPAmount{10},
 
  408             .reserveIncrementDrops = 
XRPAmount{50000}});
 
  411        BEAST_EXPECT(feeTx.getAccountID(sfAccount) == 
AccountID());
 
  412        BEAST_EXPECT(feeTx.getFieldAmount(sfFee) == 
XRPAmount{0});
 
  413        BEAST_EXPECT(feeTx.getSigningPubKey().empty());
 
  414        BEAST_EXPECT(feeTx.getSignature().empty());
 
  415        BEAST_EXPECT(!feeTx.isFieldPresent(sfSigners));
 
  416        BEAST_EXPECT(feeTx.getFieldU32(sfSequence) == 0);
 
  417        BEAST_EXPECT(!feeTx.isFieldPresent(sfPreviousTxnID));
 
 
  429        testcase(
"Multiple Fee Updates");
 
  444            .reserveIncrementDrops = 
XRPAmount{50000}};
 
  445        auto feeTx1 = 
createFeeTx(ledger->rules(), ledger->seq(), fields1);
 
  450            accum.
apply(*ledger);
 
  462            .reserveIncrementDrops = 
XRPAmount{75000}};
 
  463        auto feeTx2 = 
createFeeTx(ledger->rules(), ledger->seq(), fields2);
 
  468            accum.
apply(*ledger);
 
 
  478        testcase(
"Wrong Ledger Sequence");
 
  494            {.baseFeeDrops = XRPAmount{10},
 
  496             .reserveIncrementDrops = 
XRPAmount{50000}});
 
 
  509        testcase(
"Partial Field Updates");
 
  511        jtx::Env env(*
this, jtx::testable_amendments() | featureXRPFees);
 
  524            .reserveIncrementDrops = 
XRPAmount{50000}};
 
  525        auto feeTx1 = 
createFeeTx(ledger->rules(), ledger->seq(), fields1);
 
  530            accum.
apply(*ledger);
 
  542        auto feeTx2 = 
createFeeTx(ledger->rules(), ledger->seq(), fields2);
 
  547            accum.
apply(*ledger);
 
 
  557        testcase(
"Single Invalid Transaction");
 
  559        jtx::Env env(*
this, jtx::testable_amendments() | featureXRPFees);
 
  571        auto invalidTx = 
STTx(ttFEE, [&](
auto& obj) {
 
  575            obj.setFieldU32(sfLedgerSequence, ledger->seq());
 
  576            obj.setFieldAmount(sfBaseFeeDrops, 
XRPAmount{10});
 
  577            obj.setFieldAmount(sfReserveBaseDrops, 
XRPAmount{200000});
 
  578            obj.setFieldAmount(sfReserveIncrementDrops, 
XRPAmount{50000});
 
 
  588        testcase(
"doValidation");
 
  622            auto const& currentFees = ledger->fees();
 
  624            feeVote->doValidation(currentFees, ledger->rules(), *val);
 
  626            BEAST_EXPECT(val->isFieldPresent(sfBaseFeeDrops));
 
  628                val->getFieldAmount(sfBaseFeeDrops) ==
 
  655            auto const& currentFees = ledger->fees();
 
  657            feeVote->doValidation(currentFees, ledger->rules(), *val);
 
  660            BEAST_EXPECT(val->isFieldPresent(sfBaseFee));
 
  661            BEAST_EXPECT(val->getFieldU64(sfBaseFee) == setup.
reference_fee);
 
 
  668        testcase(
"doVoting");
 
  694        for (
int i = 0; i < 256 - 1; ++i)
 
  699        BEAST_EXPECT(ledger->isFlagLedger());
 
  704        for (
int i = 0; i < 5; i++)
 
  722                        sfReserveIncrementDrops,
 
  734        feeVote->doVoting(ledger, validations, txSet);
 
  736        auto const txs = 
getTxs(txSet);
 
  737        BEAST_EXPECT(txs.size() == 1);
 
  738        auto const& feeTx = txs[0];
 
  740        BEAST_EXPECT(feeTx.getTxnType() == ttFEE);
 
  742        BEAST_EXPECT(feeTx.getAccountID(sfAccount) == 
AccountID());
 
  743        BEAST_EXPECT(feeTx.getFieldU32(sfLedgerSequence) == ledger->seq() + 1);
 
  745        BEAST_EXPECT(feeTx.isFieldPresent(sfBaseFeeDrops));
 
  746        BEAST_EXPECT(feeTx.isFieldPresent(sfReserveBaseDrops));
 
  747        BEAST_EXPECT(feeTx.isFieldPresent(sfReserveIncrementDrops));
 
  750        BEAST_EXPECT(!feeTx.isFieldPresent(sfBaseFee));
 
  751        BEAST_EXPECT(!feeTx.isFieldPresent(sfReserveBase));
 
  752        BEAST_EXPECT(!feeTx.isFieldPresent(sfReserveIncrement));
 
  753        BEAST_EXPECT(!feeTx.isFieldPresent(sfReferenceFeeUnits));
 
  757            feeTx.getFieldAmount(sfBaseFeeDrops) ==
 
  760            feeTx.getFieldAmount(sfReserveBaseDrops) ==
 
  763            feeTx.getFieldAmount(sfReserveIncrementDrops) ==
 
 
  772        testTransactionValidation();
 
  773        testPseudoTransactionProperties();
 
  774        testMultipleFeeUpdates();
 
  775        testWrongLedgerSequence();
 
  776        testPartialFieldUpdates();
 
  777        testSingleInvalidTransaction();
 
 
 
testcase_t testcase
Memberspace for declaring test cases.
 
virtual Config & config()=0
 
virtual beast::Journal journal(std::string const &name)=0
 
virtual TimeKeeper & timeKeeper()=0
 
virtual Family & getNodeFamily()=0
 
Manager to process fee votes.
 
Writable ledger view that accumulates state and tx changes.
 
void apply(TxsRawView &to) const
Apply changes.
 
Rules controlling protocol behavior.
 
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
 
void setFieldAmount(SField const &field, STAmount const &)
 
void setFieldU32(SField const &field, std::uint32_t)
 
Holds a collection of configuration values.
 
void append(std::vector< std::string > const &lines)
Append a set of lines to this section.
 
time_point now() const override
Returns the current time, using the server's clock.
 
time_point closeTime() const
Returns the predicted close time, in network time.
 
void testPartialFieldUpdates()
 
void testSingleInvalidTransaction()
 
void testMultipleFeeUpdates()
 
void testPseudoTransactionProperties()
 
void testWrongLedgerSequence()
 
void run() override
Runs the suite.
 
void testTransactionValidation()
 
A transaction testing environment.
 
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
 
beast::Journal const journal
 
Keylet const & fees() noexcept
The (fixed) index of the object containing the ledger fees.
 
auto const data
General field definitions, or fields used in multiple transaction namespaces.
 
FeatureBitset testable_amendments()
 
bool applyFeeAndTestResult(jtx::Env &env, OpenView &view, STTx const &tx)
 
STTx createFeeTx(Rules const &rules, std::uint32_t seq, FeeSettingsFields const &fields)
 
std::vector< STTx > getTxs(std::shared_ptr< SHAMap > const &txSet)
 
STTx createInvalidFeeTx(Rules const &rules, std::uint32_t seq, bool missingRequiredFields=true, bool wrongFeatureFields=false, std::uint32_t uniqueValue=42)
 
bool verifyFeeObject(std::shared_ptr< Ledger const > const &ledger, Rules const &rules, FeeSettingsFields const &expected)
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
base_uint< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
 
std::unique_ptr< FeeVote > make_FeeVote(FeeSetup const &setup, beast::Journal journal)
Create an instance of the FeeVote logic.
 
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
 
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
 
NodeID calcNodeID(PublicKey const &)
Calculate the 160-bit node ID from a node public key.
 
ApplyResult apply(Application &app, OpenView &view, STTx const &tx, ApplyFlags flags, beast::Journal journal)
Apply a transaction to an OpenView.
 
FeeSetup setup_FeeVote(Section const §ion)
 
create_genesis_t const create_genesis
 
Fee schedule for startup / standalone, and to vote for.
 
XRPAmount reference_fee
The cost of a reference transaction in drops.
 
XRPAmount owner_reserve
The per-owned item reserve requirement in drops.
 
XRPAmount account_reserve
The account reserve requirement in drops.
 
std::optional< XRPAmount > reserveBaseDrops
 
std::optional< std::uint32_t > reserveBase
 
std::optional< std::uint32_t > reserveIncrement
 
std::optional< XRPAmount > reserveIncrementDrops
 
std::optional< std::uint32_t > referenceFeeUnits
 
std::optional< std::uint64_t > baseFee
 
std::optional< XRPAmount > baseFeeDrops
 
Set the sequence number on a JTx.