3#include <xrpl/protocol/Feature.h> 
    4#include <xrpl/protocol/jss.h> 
   27        Json::Value const meta = env.
rpc(
"tx", txHash)[jss::result][jss::meta];
 
   30        if (!BEAST_EXPECT(meta.
isMember(sfDeliveredAmount.jsonName)))
 
   36        BEAST_EXPECT(meta[sfDeliveredAmount.jsonName] == jsonExpect);
 
   37        BEAST_EXPECT(meta[jss::delivered_amount] == jsonExpect);
 
 
   51        jv[jss::TransactionType] = jss::PaymentChannelCreate;
 
   52        jv[jss::Account] = account.human();
 
   53        jv[jss::Destination] = to.
human();
 
   55        jv[sfSettleDelay.jsonName] = settleDelay.
count();
 
 
   75        env.fund(
XRP(10000), alice, becky, carol, gw);
 
   91        auto const acctDelFee{
drops(env.current()->fees().increment)};
 
  103        env(
trust(becky, gw[
"USD"](1000)));
 
  110        env(
offer(carol, gw[
"USD"](51), 
XRP(51)));
 
  113        env(
signers(carol, 1, {{alice, 1}, {becky, 1}}));
 
  132            auto const aliceOldBalance{env.balance(alice)};
 
  133            auto const beckyOldBalance{env.balance(becky)};
 
  149                env.balance(becky) ==
 
  150                aliceOldBalance + beckyOldBalance - acctDelFee);
 
  171        for (
int i = 0; i < 8; ++i)
 
  175            auto const beckyOldBalance{env.balance(becky)};
 
  176            auto const carolOldBalance{env.balance(carol)};
 
  182            BEAST_EXPECT(env.closed()->exists(
 
  186            BEAST_EXPECT(env.closed()->exists(
 
  199            BEAST_EXPECT(!env.closed()->exists(
 
  201            BEAST_EXPECT(!env.closed()->exists(
 
  203            BEAST_EXPECT(!env.closed()->exists(
 
  209                env.balance(becky) ==
 
  210                carolOldBalance + beckyOldBalance - acctDelFee);
 
 
  232        env.fund(
XRP(10000), alice, gw);
 
  236        for (
int i{0}; i < 45; ++i)
 
  238            env(
offer(alice, gw[
"USD"](1), 
XRP(1)));
 
  241        env.require(
offers(alice, 45));
 
  249        BEAST_EXPECT(env.closed()->exists(aliceRootKey));
 
  250        BEAST_EXPECT(env.closed()->exists(alicePageKey));
 
  253        auto const acctDelFee{
drops(env.current()->fees().increment)};
 
  254        auto const aliceBalance{env.balance(alice)};
 
  260        BEAST_EXPECT(!env.closed()->exists(aliceRootKey));
 
  261        BEAST_EXPECT(!env.closed()->exists(alicePageKey));
 
 
  281        env.fund(
XRP(100000), alice, becky, gw);
 
  287        for (
int i{0}; i < 200; ++i)
 
  289            env(
offer(alice, gw[
"USD"](1), 
XRP(1)));
 
  290            env(
offer(becky, gw[
"USD"](1), 
XRP(1)));
 
  293        env.require(
offers(alice, 200));
 
  294        env.require(
offers(becky, 200));
 
  308        auto const acctDelFee{
drops(env.current()->fees().increment)};
 
  319        using namespace std::chrono_literals;
 
  335        bool const withTokenEscrow =
 
  336            env.current()->rules().enabled(featureTokenEscrow);
 
  341            auto const USD = gw1[
"USD"];
 
  342            env.fund(
XRP(100000), carol, gw1);
 
  345            env.trust(USD(10000), carol);
 
  347            env(
pay(gw1, carol, USD(100)));
 
  370        Keylet const alicePayChanKey{
 
  374            alice, becky, 
XRP(57), 4s, env.now() + 2s, alice.
pk()));
 
  380        auto const beckyBalance{env.balance(becky)};
 
  391                               Keylet const& payChanKeylet,
 
  394            jv[jss::TransactionType] = jss::PaymentChannelClaim;
 
  396            jv[jss::Account] = account.human();
 
  397            jv[sfChannel.jsonName] = 
to_string(payChanKeylet.key);
 
  398            jv[sfPublicKey.jsonName] = 
strHex(pk.slice());
 
  401        env(payChanClose(alice, alicePayChanKey, alice.
pk()));
 
  406        env.enableFeature(fixPayChanRecipientOwnerDir);
 
  423        env(payChanClose(alice, gwPayChanKey, alice.
pk()));
 
  427        auto const aliceBalance{env.balance(alice)};
 
 
  449        env.fund(
XRP(10000), alice, becky);
 
  454        BEAST_EXPECT(env.closed()->exists(beckyAcctKey));
 
  456        using namespace std::chrono_literals;
 
  458        auto const payChanXRP = 
XRP(37);
 
  461            alice, becky, payChanXRP, 4s, env.now() + 1h, alice.
pk()));
 
  463        BEAST_EXPECT(env.closed()->exists(payChanKey));
 
  468        auto const beckyPreDelBalance{env.balance(becky)};
 
  470        auto const acctDelFee{
drops(env.current()->fees().increment)};
 
  476        BEAST_EXPECT(!env.closed()->exists(beckyAcctKey));
 
  482                drops(env.current()->fees().accountReserve(0)) - 
XRP(1)),
 
  487        env(
pay(alice, becky, 
XRP(10)));
 
  491        BEAST_EXPECT(env.closed()->exists(beckyAcctKey));
 
  492        BEAST_EXPECT(env.balance(becky) == 
XRP(10));
 
  496        auto payChanClaim = [&]() {
 
  498            jv[jss::TransactionType] = jss::PaymentChannelClaim;
 
  499            jv[jss::Account] = alice.
human();
 
  500            jv[sfChannel.jsonName] = 
to_string(payChanKey.key);
 
  501            jv[sfBalance.jsonName] =
 
  508        BEAST_EXPECT(env.balance(becky) == 
XRP(10) + payChanXRP);
 
 
  524        env.fund(
XRP(10000), alice, becky);
 
  532        BEAST_EXPECT(env.closed()->exists(aliceAcctKey));
 
  534        auto const alicePreDelBal{env.balance(alice)};
 
  535        auto const beckyPreDelBal{env.balance(becky)};
 
  537        auto const acctDelFee{
drops(env.current()->fees().increment)};
 
  543        BEAST_EXPECT(env.current()->exists(aliceAcctKey));
 
  544        BEAST_EXPECT(env.balance(alice) == alicePreDelBal);
 
  545        BEAST_EXPECT(env.balance(becky) == beckyPreDelBal);
 
  549        env.enableFeature(featureDeletableAccounts);
 
  553        BEAST_EXPECT(env.closed()->exists(aliceAcctKey));
 
  557        BEAST_EXPECT(!env.current()->exists(aliceAcctKey));
 
  559            env.balance(becky) == alicePreDelBal + beckyPreDelBal - acctDelFee);
 
  562        BEAST_EXPECT(!env.closed()->exists(aliceAcctKey));
 
 
  578        env.fund(
XRP(10000000), alice, gw);
 
  588        constexpr int offerCount{1001};
 
  589        for (
int i{0}; i < offerCount; ++i)
 
  591            env(
offer(alice, gw[currency](1), 
XRP(1)));
 
  596            if (currency[0] > 
'Z')
 
  601            if (currency[1] > 
'Z')
 
  606            if (currency[2] > 
'Z')
 
  622            BEAST_EXPECT(closed->exists(aliceOwnerDirKey));
 
  626                BEAST_EXPECT(closed->exists(
keylet::page(aliceOwnerDirKey, i)));
 
  636        auto const acctDelFee{
drops(env.current()->fees().increment)};
 
  641        env.require(
offers(alice, offerCount));
 
  644        env.require(
offers(alice, offerCount - 1));
 
  647        auto const alicePreDelBal{env.balance(alice)};
 
  657            BEAST_EXPECT(!closed->exists(aliceOwnerDirKey));
 
 
  678        testcase(
"Implicitly created trust line");
 
  683        auto const BUX{gw[
"BUX"]};
 
  685        env.fund(
XRP(10000), alice, gw);
 
  690        env(
offer(alice, BUX(30), 
XRP(30)));
 
  696        env.require(
balance(alice, BUX(30)));
 
  703        auto const acctDelFee{
drops(env.current()->fees().increment)};
 
 
  723        testcase(
"Balance too small for fee");
 
  731        env.fund(env.current()->fees().reserve, 
noripple(alice));
 
  736        env(
noop(alice), 
fee(env.balance(alice) - 
XRP(1)));
 
  739        auto const acctDelFee{
drops(env.current()->fees().increment)};
 
  740        BEAST_EXPECT(acctDelFee > env.balance(alice));
 
  746        auto const masterBalance{env.balance(env.master)};
 
  754            BEAST_EXPECT(env.balance(env.master) == masterBalance);
 
  759        BEAST_EXPECT(env.balance(alice) == 
XRP(1));
 
  765            BEAST_EXPECT(env.balance(env.master) == masterBalance);
 
 
  774        using namespace test::jtx;
 
  780        env.
fund(
XRP(100000), alice, bob);
 
  787        env.require(
owners(bob, 250));
 
  804        auto const acctDelFee{
drops(env.current()->fees().increment)};
 
  805        auto const bobOldBalance{env.balance(bob)};
 
 
  823        testcase(
"Destination Constraints");
 
  825        using namespace test::jtx;
 
  833        env.
fund(
XRP(100000), alice, becky, carol);
 
  850        auto const acctDelFee{
drops(env.current()->fees().increment)};
 
  869        auto const beckyOldBalance{env.balance(becky)};
 
 
  880                "Destination Constraints with DepositPreauth and Credentials");
 
  882            using namespace test::jtx;
 
  889            char const credType[] = 
"abcd";
 
  892            env.
fund(
XRP(100000), alice, becky, carol, daria);
 
  902            std::string const credIdx = jv[jss::result][jss::index].asString();
 
  907            auto const acctDelFee{
drops(env.current()->fees().increment)};
 
  967                    {
"48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6E" 
  984                    jNoCred.isObject() && jNoCred.isMember(jss::result) &&
 
  985                    jNoCred[jss::result].isMember(jss::error) &&
 
  986                    jNoCred[jss::result][jss::error] == 
"entryNotFound");
 
  989            testcase(
"Credentials that aren't required");
 
  997                        env, daria, carol, credType)[jss::result][jss::index]
 
 1008                auto const jNoCred =
 
 1012                    jNoCred.isObject() && jNoCred.isMember(jss::result) &&
 
 1013                    jNoCred[jss::result].isMember(jss::error) &&
 
 1014                    jNoCred[jss::result][jss::error] == 
"entryNotFound");
 
 1021                env.fund(
XRP(5000), eaton, fred);
 
 1030                        env, eaton, carol, credType)[jss::result][jss::index]
 
 1041                auto const acctDelFee{
drops(env.current()->fees().increment)};
 
 1051                auto const jNoCred =
 
 1055                    jNoCred.isObject() && jNoCred.isMember(jss::result) &&
 
 1056                    jNoCred[jss::result].isMember(jss::error) &&
 
 1057                    jNoCred[jss::result][jss::error] == 
"entryNotFound");
 
 1064                env.fund(
XRP(10000), john);
 
 1068                uint32_t 
const t = env.current()
 
 1070                                       .parentCloseTime.time_since_epoch()
 
 1073                jv[sfExpiration.jsonName] = t;
 
 1080                    jv[jss::result][jss::index].asString();
 
 1097                        jv.isObject() && jv.isMember(jss::result) &&
 
 1098                        jv[jss::result].isMember(jss::error) &&
 
 1099                        jv[jss::result][jss::error] == 
"entryNotFound");
 
 1105            testcase(
"Credentials feature disabled");
 
 1106            using namespace test::jtx;
 
 1113            env.fund(
XRP(100000), alice, becky, carol);
 
 1125            auto const acctDelFee{
drops(env.current()->fees().increment)};
 
 1128                "098B7F1B146470A1C5084DC7832C04A72939E3EBC58E68AB8B579BA072B0CE" 
 
 1147            testcase(
"Deleting Issuer deletes issued credentials");
 
 1149            using namespace test::jtx;
 
 1155            char const credType[] = 
"abcd";
 
 1158            env.
fund(
XRP(100000), alice, becky, carol);
 
 1170            std::string const credIdx = jv[jss::result][jss::index].asString();
 
 1175            auto const acctDelFee{
drops(env.current()->fees().increment)};
 
 1180                BEAST_EXPECT(!env.le(credIdx));
 
 1184                    jv.isObject() && jv.isMember(jss::result) &&
 
 1185                    jv[jss::result].isMember(jss::error) &&
 
 1186                    jv[jss::result][jss::error] == 
"entryNotFound");
 
 1191            testcase(
"Deleting Subject deletes issued credentials");
 
 1193            using namespace test::jtx;
 
 1199            char const credType[] = 
"abcd";
 
 1202            env.
fund(
XRP(100000), alice, becky, carol);
 
 1214            std::string const credIdx = jv[jss::result][jss::index].asString();
 
 1219            auto const acctDelFee{
drops(env.current()->fees().increment)};
 
 1224                BEAST_EXPECT(!env.le(credIdx));
 
 1228                    jv.isObject() && jv.isMember(jss::result) &&
 
 1229                    jv[jss::result].isMember(jss::error) &&
 
 1230                    jv[jss::result][jss::error] == 
"entryNotFound");
 
 
 
std::string asString() const
Returns the unquoted string value.
 
bool isMember(char const *key) const
Return true if the object has a member named key.
 
testcase_t testcase
Memberspace for declaring test cases.
 
Slice slice() const noexcept
 
Json::Value getJson(JsonOptions=JsonOptions::none) const override
 
void testBalanceTooSmallForFee()
 
void verifyDeliveredAmount(jtx::Env &env, STAmount const &amount)
 
void testDeleteCredentialsOwner()
 
void run() override
Runs the suite.
 
void testAmendmentEnable()
 
void testDestinationDepositAuthCredentials()
 
static Json::Value payChanCreate(jtx::Account const &account, jtx::Account const &to, STAmount const &amount, NetClock::duration const &settleDelay, NetClock::time_point const &cancelAfter, PublicKey const &pk)
 
void testImplicitlyCreatedTrustline()
 
Immutable cryptographic account descriptor.
 
PublicKey const & pk() const
Return the public key.
 
AccountID id() const
Returns the Account ID.
 
static Account const master
The master account.
 
std::string const & human() const
Returns the human readable public key.
 
A transaction testing environment.
 
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
 
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
 
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
 
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
 
Set a multisignature on a JTx.
 
Match the number of items in the account's owner directory.
 
Set the regular signature on a JTx.
 
Set the expected result code for a JTx The test will fail if the code doesn't match.
 
Set a ticket sequence on a JTx.
 
Keylet account(AccountID const &id) noexcept
AccountID root.
 
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
 
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
 
Keylet signers(AccountID const &account) noexcept
A SignerList.
 
static ticket_t const ticket
 
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
 
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
 
Keylet depositPreauth(AccountID const &owner, AccountID const &preauthorized) noexcept
A DepositPreauth.
 
Keylet payChan(AccountID const &src, AccountID const &dst, std::uint32_t seq) noexcept
A PaymentChannel.
 
Json::Value create(A const &account, A const &dest, STAmount const &sendMax)
Create a check.
 
Json::Value cancel(jtx::Account const &dest, uint256 const &checkId)
Cancel a check.
 
Json::Value create(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
 
Json::Value accept(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
 
Json::Value ledgerEntry(jtx::Env &env, jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
 
Json::Value auth(Account const &account, Account const &auth)
Preauthorize for deposit.
 
Json::Value authCredentials(jtx::Account const &account, std::vector< AuthorizeCredentials > const &auth)
 
Json::Value setValid(jtx::Account const &account)
 
Json::Value create(AccountID const &account, AccountID const &to, STAmount const &amount)
 
auto const finish_time
Set the "FinishAfter" time tag on a JTx.
 
Json::Value cancel(AccountID const &account, Account const &from, std::uint32_t seq)
 
auto const cancel_time
Set the "CancelAfter" time tag on a JTx.
 
Json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
 
Json::Value regkey(Account const &account, disabled_t)
Disable the regular key.
 
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
 
owner_count< ltOFFER > offers
Match the number of offers in the account's owner directory.
 
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
 
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
 
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
 
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
 
FeatureBitset testable_amendments()
 
void incLgrSeqForAccDel(jtx::Env &env, jtx::Account const &acc, std::uint32_t margin=0)
 
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
 
Json::Value acctdelete(Account const &account, Account const &dest)
Delete account.
 
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.
 
constexpr std::uint32_t asfDepositAuth
 
constexpr std::uint32_t asfAllowTrustLineLocking
 
constexpr std::uint32_t asfRequireDest
 
constexpr std::uint32_t tfImmediateOrCancel
 
std::string strHex(FwdIt begin, FwdIt end)
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
constexpr std::uint32_t tfClose
 
A pair of SHAMap key and LedgerEntryType.
 
T time_since_epoch(T... args)