3#include <xrpl/basics/random.h> 
    4#include <xrpl/ledger/BookDirs.h> 
    5#include <xrpl/ledger/Sandbox.h> 
    6#include <xrpl/protocol/Feature.h> 
    7#include <xrpl/protocol/Protocol.h> 
    8#include <xrpl/protocol/TER.h> 
    9#include <xrpl/protocol/jss.h> 
   24        BEAST_EXPECT(i < 17577);
 
   28        for (
int j = 0; j != 3; ++j)
 
 
   49                p->setFieldU64(sfIndexNext, 0);
 
   51                p->setFieldU64(sfIndexNext, i + 1);
 
   54                p->setFieldU64(sfIndexPrevious, n - 1);
 
   56                p->setFieldU64(sfIndexPrevious, i - 1);
 
 
   72        testcase(
"Directory Ordering (with 'SortedDirectories' amendment)");
 
   75        env.
fund(
XRP(10000000), alice, gw);
 
   86            auto const view = env.
closed();
 
   96                auto const& v = p->getFieldV256(sfIndexes);
 
  105                for (
auto const& e : v)
 
  109                    BEAST_EXPECT(c->getFieldU32(sfSequence) >= minSeq);
 
  110                    BEAST_EXPECT(c->getFieldU32(sfSequence) < maxSeq);
 
  113                page = p->getFieldU64(sfIndexNext);
 
  123        for (
auto const& 
offer : book)
 
  126            BEAST_EXPECT(
offer->getFieldAmount(sfTakerPays) == USD(count));
 
  127            BEAST_EXPECT(
offer->getFieldAmount(sfTakerGets) == 
XRP(count));
 
 
  137        auto const alice = 
Account(
"alice");
 
  138        auto const bob = 
Account(
"bob");
 
  139        auto const charlie = 
Account(
"charlie");
 
  144        env.
fund(
XRP(1000000), alice, charlie, gw);
 
  151        env(
signers(alice, 1, {{bob, 1}}));
 
  173            auto cl = currencies;
 
  175            for (
auto const& c : cl)
 
  177                env(
trust(alice, c(50)));
 
  185            for (
auto const& c : cl)
 
  187                env(
trust(alice, c(0)));
 
  197            auto cl = currencies;
 
  201            for (
auto c : currencies)
 
  203                env(
trust(charlie, c(50)));
 
  205                env(
pay(gw, charlie, c(50)));
 
  218            for (
auto const& c : cl)
 
  220                env(
offer(charlie, 
XRP(50), c(50)));
 
  229            for (
auto const& c : cl)
 
  231                env(
pay(alice, charlie, c(50)));
 
 
  242        testcase(
"RIPD-1353 Empty Offer Directories");
 
  247        auto const gw = 
Account{
"gateway"};
 
  248        auto const alice = 
Account{
"alice"};
 
  249        auto const USD = gw[
"USD"];
 
  251        env.
fund(
XRP(10000), alice, gw);
 
  253        env.
trust(USD(1000), alice);
 
  254        env(
pay(gw, alice, USD(1000)));
 
  256        auto const firstOfferSeq = env.
seq(alice);
 
  259        for (
int i = 0; i < 3; ++i)
 
  265        for (
auto page : {0, 2, 1})
 
  290            env.
trust(USD(0), alice);
 
  291            env(
pay(alice, gw, alice[
"USD"](1000)));
 
 
  305        auto const gw = 
Account{
"gateway"};
 
  306        auto const alice = 
Account{
"alice"};
 
  307        auto const USD = gw[
"USD"];
 
  313            "fb71c9aa3310141da4b01d6c744a98286af2d72ab5448d5adc0910ca0c910880");
 
  316            "bad0f021aa3b2f6754a8fe82a5779730aa0bbbab82f17201ef24900efc2c7312");
 
  330                p->setFieldV256(sfIndexes, v);
 
  355                p1->setFieldV256(sfIndexes, v1);
 
  363                p2->setFieldV256(sfIndexes, v2);
 
  377            BEAST_EXPECT(p1->getFieldU64(sfIndexNext) == 0);
 
  378            BEAST_EXPECT(p1->getFieldU64(sfIndexPrevious) == 0);
 
  382            BEAST_EXPECT(p0->getFieldU64(sfIndexNext) == 1);
 
  383            BEAST_EXPECT(p0->getFieldU64(sfIndexPrevious) == 1);
 
 
  393        auto const gw = 
Account{
"gateway"};
 
  394        auto const alice = 
Account{
"alice"};
 
  395        auto const USD = gw[
"USD"];
 
  397        auto ledger_data = [
this](
Env& env) {
 
  399            params[jss::type] = jss::directory;
 
  400            params[jss::ledger_index] = 
"validated";
 
  402                env.rpc(
"json", 
"ledger_data", 
to_string(params))[jss::result];
 
  403            BEAST_EXPECT(!result.isMember(jss::marker));
 
  409        env.
fund(
XRP(10000), alice, gw);
 
  411        env.
trust(USD(1000), alice);
 
  412        env(
pay(gw, alice, USD(1000)));
 
  416            auto const jrr = ledger_data(env);
 
  417            auto const& jstate = jrr[jss::state];
 
  419            for (
auto const& directory : jstate)
 
  422                    directory[
"LedgerEntryType"] ==
 
  426                BEAST_EXPECT(!directory.isMember(
"PreviousTxnID"));
 
  427                BEAST_EXPECT(!directory.isMember(
"PreviousTxnLgrSeq"));
 
  438        auto const txID = 
to_string(env.
tx()->getTransactionID());
 
  439        auto const ledgerSeq = env.
current()->info().seq;
 
  446            auto const jrr = ledger_data(env);
 
  447            auto const& jstate = jrr[jss::state];
 
  449            for (
auto const& directory : jstate)
 
  452                    directory[
"LedgerEntryType"] ==
 
  454                if (directory[jss::Owner] == gw.human())
 
  458                    BEAST_EXPECT(!directory.isMember(
"PreviousTxnID"));
 
  459                    BEAST_EXPECT(!directory.isMember(
"PreviousTxnLgrSeq"));
 
  467                        directory.isMember(
"PreviousTxnID") &&
 
  468                        directory[
"PreviousTxnID"].asString() == txID);
 
  470                        directory.isMember(
"PreviousTxnLgrSeq") &&
 
  471                        directory[
"PreviousTxnLgrSeq"].asUInt() == ledgerSeq);
 
 
  480        using namespace test::jtx;
 
  483        auto const testCase = [&, 
this](
FeatureBitset features, 
auto setup) {
 
  484            using namespace test::jtx;
 
  486            Env env(*
this, features);
 
  490            auto const [lastPage, full] = setup(env);
 
  493            for (
int i = 0; i < 63; ++i)
 
  507                    auto sle = view.peek({ltCREDENTIAL, key});
 
  508                    if (!BEAST_EXPECT(sle))
 
  511                    BEAST_EXPECT(page == lastPage);
 
  512                    sle->setFieldU64(sfIssuerNode, page);
 
  527            for (
int i = 0; i < 64; ++i)
 
  536            BEAST_EXPECT(sle == 
nullptr);
 
  545                testcase(
"directory full without fixDirectoryLimit");
 
  551                testcase(
"directory not full with fixDirectoryLimit");
 
  557                testcase(
"directory full with fixDirectoryLimit");
 
 
  565        testDirectoryOrdering();
 
 
 
testcase_t testcase
Memberspace for declaring test cases.
 
Writeable view to a ledger, for applying a transaction.
 
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
 
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
 
void push_back(uint256 const &v)
 
Discardable, editable view to a ledger.
 
void update(std::shared_ptr< SLE > const &sle) override
Indicate changes to a peeked SLE.
 
void insert(std::shared_ptr< SLE > const &sle) override
Insert a new state SLE.
 
std::optional< key_type > succ(key_type const &key, std::optional< key_type > const &last=std::nullopt) const override
Return the key of the next state item.
 
std::shared_ptr< SLE > peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
 
Immutable cryptographic account descriptor.
 
AccountID id() const
Returns the Account ID.
 
A transaction testing environment.
 
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
 
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
 
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
 
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
 
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
 
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
 
void enableFeature(uint256 const feature)
 
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
 
Set the expected result code for a JTx The test will fail if the code doesn't match.
 
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
 
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
 
Keylet unchecked(uint256 const &key) noexcept
Any ledger entry.
 
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
 
Json::Value create(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
 
Json::Value deleteCred(jtx::Account const &acc, jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
 
auto bumpLastPage(Env &env, std::uint64_t newLastPage, Keylet directory, std::function< bool(ApplyView &, uint256, std::uint64_t)> adjust) -> Expected< void, Error >
Move the position of the last page in the user's directory on open ledger to newLastPage.
 
bool checkArraySize(Json::Value const &val, unsigned int size)
 
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
 
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
 
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
 
FeatureBitset testable_amendments()
 
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
 
XRP_t const XRP
Converts to XRP Issue or STAmount.
 
Json::Value offer_cancel(Account const &account, std::uint32_t offerSeq)
Cancel an offer.
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
 
std::uint64_t constexpr dirNodeMaxPages
The maximum number of pages allowed in a directory.
 
bool dirIsEmpty(ReadView const &view, Keylet const &k)
Returns true if the directory is empty.
 
std::size_t constexpr dirNodeMaxEntries
The maximum number of entries per directory page.
 
uint256 getQualityNext(uint256 const &uBase)
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
uint256 getBookBase(Book const &book)
 
beast::xor_shift_engine & default_prng()
Return the default random engine.
 
std::string currcode(std::size_t i)
 
void makePages(Sandbox &sb, uint256 const &base, std::uint64_t n)
 
void testDirectoryOrdering()
 
void run() override
Runs the suite.