3#include <xrpl/protocol/Feature.h> 
   15    return env.
current()->fees().accountReserve(count);
 
 
   76        IOU const USD = gw[
"USD"];
 
   80        env.
fund(
XRP(10000), alice, bob, carol, gw);
 
   82        env.
trust(USD(1000), alice, bob);
 
   85        env(
pay(gw, alice, USD(150)));
 
   86        env(
offer(carol, USD(100), 
XRP(100)));
 
   90        env(
pay(alice, bob, USD(50)));
 
   98        auto failedIouPayments = [
this, &env, &alice, &bob, &USD]() {
 
  115            BEAST_EXPECT(bobXrpBalance == env.
balance(bob, 
XRP));
 
  116            BEAST_EXPECT(bobUsdBalance == env.
balance(bob, USD));
 
  124        env(
pay(bob, alice, USD(25)));
 
  130            env(
pay(bob, alice, bobPaysXRP), 
fee(bobPaysFee));
 
  136        BEAST_EXPECT(env.
balance(bob, USD) == USD(25));
 
  153        env(
pay(alice, bob, USD(50)));
 
 
  172        auto const baseFee = env.
current()->fees().base;
 
  174        env.
fund(
XRP(10000), alice, bob);
 
  191            env(
pay(bob, alice, bobPaysXRP), 
fee(bobPaysFee));
 
  247        env(
pay(alice, bob, 
drops(baseFee - 1)));
 
 
  277        IOU const USD1(gw1[
"USD"]);
 
  278        IOU const USD2(gw2[
"USD"]);
 
  283                              bool withDepositAuth) {
 
  284            assert(!withDepositAuth || features[featureDepositAuth]);
 
  286            Env env(*
this, features);
 
  288            env.
fund(
XRP(10000), gw1, alice, bob);
 
  292            env.
trust(USD1(10), alice, bob);
 
  294            env(
pay(gw1, alice, USD1(10)));
 
  301            env(
pay(alice, bob, USD1(10)), 
path(gw1), 
ter(result));
 
  307                                 bool withDepositAuth) {
 
  308            assert(!withDepositAuth || features[featureDepositAuth]);
 
  310            Env env(*
this, features);
 
  312            env.
fund(
XRP(10000), gw1, gw2, alice);
 
  316            env(
pay(gw2, alice, USD2(10)));
 
  323            env(
pay(gw1, gw2, USD2(10)),
 
  330        for (
int i = 0; i < 8; ++i)
 
  332            auto const noRipplePrev = i & 0x1;
 
  333            auto const noRippleNext = i & 0x2;
 
  334            auto const withDepositAuth = i & 0x4;
 
  341            if (!withDepositAuth)
 
  354            if (!withDepositAuth)
 
 
 
  380    jvParams[jss::ledger_index] = jss::validated;
 
  381    jvParams[jss::deposit_preauth][jss::owner] = acc.
human();
 
  382    jvParams[jss::deposit_preauth][jss::authorized_credentials] =
 
  384    auto& arr(jvParams[jss::deposit_preauth][jss::authorized_credentials]);
 
  385    for (
auto const& o : 
auth)
 
  387        arr.append(o.toLEJson());
 
  389    return env.
rpc(
"json", 
"ledger_entry", 
to_string(jvParams));
 
 
  405            env.
fund(
XRP(10000), alice, becky);
 
  427            env.
fund(
XRP(10000), alice, becky);
 
  446            env.
fund(
XRP(10000), alice, becky);
 
  463            BEAST_EXPECT(env.
seq(alice) == aliceSeq);
 
  471            BEAST_EXPECT(env.
seq(alice) == aliceSeq);
 
 
  496        env.
fund(
XRP(10000), alice, becky);
 
  517            tx[sfUnauthorize.jsonName] = becky.human();
 
 
  603        IOU const USD(gw[
"USD"]);
 
  605        bool const supportsPreauth = {features[featureDepositPreauth]};
 
  611            Env env(*
this, features);
 
  612            env.
fund(
XRP(5000), alice, becky, gw);
 
  615            env.
trust(USD(1000), alice);
 
  616            env.
trust(USD(1000), becky);
 
  619            env(
pay(gw, alice, USD(500)));
 
  640            env(
pay(becky, becky, USD(10)),
 
  648                char const credType[] = 
"abcde";
 
  653                bool const supportsCredentials = features[featureCredentials];
 
  655                TER const expectCredentials(
 
  657                TER const expectPayment(
 
  674                    ter(expectCredentials));
 
  677                    ter(expectCredentials));
 
  682                    ? jv[jss::result][jss::index].asString()
 
  683                    : 
"48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6" 
  686                env(
pay(gw, becky, USD(100)),
 
  695                if (!supportsPreauth)
 
  697                    auto const seq1 = env.
seq(alice);
 
  717            Env env(*
this, features);
 
  718            env.
fund(
XRP(5000), alice, becky, carol, gw);
 
  721            env.
trust(USD(1000), alice);
 
  722            env.
trust(USD(1000), becky);
 
  723            env.
trust(USD(1000), carol);
 
  726            env(
pay(gw, alice, USD(1000)));
 
  730            env(
pay(alice, becky, 
XRP(100)));
 
  731            env(
pay(alice, becky, USD(100)));
 
  758            env(
pay(alice, becky, 
XRP(100)));
 
  759            env(
pay(alice, becky, USD(100)));
 
  776            env(
pay(alice, becky, 
XRP(100)));
 
  777            env(
pay(alice, becky, USD(100)));
 
  793            env(
pay(alice, becky, 
XRP(100)));
 
  794            env(
pay(alice, becky, USD(100)));
 
 
  804        char const credType[] = 
"abcde";
 
  805        Account const issuer{
"issuer"};
 
  812            testcase(
"Payment failure with disabled credentials rule.");
 
  816            env.
fund(
XRP(5000), issuer, bob, alice);
 
  835                "0E0B04ED60588A758B67E21FBBE95AC5A63598BA951761DC0EC9C08D7E" 
  837            env(
pay(alice, bob, 
XRP(10)),
 
  844            testcase(
"Payment with credentials.");
 
  848            env.
fund(
XRP(5000), issuer, alice, bob, john);
 
  858            std::string const credIdx = jv[jss::result][jss::index].asString();
 
  872                jDP.isObject() && jDP.isMember(jss::result) &&
 
  873                !jDP[jss::result].isMember(jss::error) &&
 
  874                jDP[jss::result].isMember(jss::node) &&
 
  875                jDP[jss::result][jss::node].isMember(
"LedgerEntryType") &&
 
  876                jDP[jss::result][jss::node][
"LedgerEntryType"] ==
 
  877                    jss::DepositPreauth);
 
  881                auto jv = 
pay(alice, bob, 
XRP(100));
 
  888            env(
pay(alice, bob, 
XRP(100)),
 
  914            testcase(
"Payment failure with invalid credentials.");
 
  918            env.
fund(
XRP(10000), issuer, alice, bob, maria);
 
  930            std::string const credIdx = jv[jss::result][jss::index].asString();
 
  944                env(
pay(alice, bob, 
XRP(100)),
 
  951                    bob, {{issuer, credType}, {issuer, credType}}),
 
  960                    "0E0B04ED60588A758B67E21FBBE95AC5A63598BA951761DC0EC9C08D7E" 
  963                env(
pay(alice, bob, 
XRP(100)),
 
  970                env(
pay(maria, bob, 
XRP(100)),
 
  977                char const credType2[] = 
"fghij";
 
  985                    jv[jss::result][jss::index].asString();
 
  988                env(
pay(alice, bob, 
XRP(100)),
 
  994            env(
pay(alice, bob, 
XRP(100)),
 
 
 1007        using namespace jtx;
 
 1009        char const credType[] = 
"abcde";
 
 1010        Account const issuer{
"issuer"};
 
 1016            testcase(
"Creating / deleting with credentials.");
 
 1020            env.
fund(
XRP(5000), issuer, alice, bob);
 
 1033                jv[sfUnauthorize.jsonName] = issuer.human();
 
 1040                jv[sfAuthorize.jsonName] = issuer.human();
 
 1047                jv[sfUnauthorize.jsonName] = issuer.human();
 
 1054                jv[sfAuthorize.jsonName] = issuer.human();
 
 1067                auto& arr(jv[sfAuthorizeCredentials.jsonName]);
 
 1070                cred[sfCredentialType.jsonName] =
 
 1073                credParent[jss::Credential] = cred;
 
 1074                arr.
append(std::move(credParent));
 
 1087                Account const a(
"a"), b(
"b"), c(
"c"), d(
"d"), e(
"e"), f(
"f"),
 
 1088                    g(
"g"), h(
"h"), i(
"i");
 
 1089                auto const& z = credType;
 
 1115                env.
fund(env.
current()->fees().accountReserve(0), john);
 
 1135                    jDP.isObject() && jDP.isMember(jss::result) &&
 
 1136                    !jDP[jss::result].isMember(jss::error) &&
 
 1137                    jDP[jss::result].isMember(jss::node) &&
 
 1138                    jDP[jss::result][jss::node].isMember(
"LedgerEntryType") &&
 
 1139                    jDP[jss::result][jss::node][
"LedgerEntryType"] ==
 
 1140                        jss::DepositPreauth);
 
 1144                    jDP[jss::result][jss::node][jss::Account] == bob.human());
 
 1145                auto const& credentials(
 
 1146                    jDP[jss::result][jss::node][
"AuthorizeCredentials"]);
 
 1147                BEAST_EXPECT(credentials.isArray() && credentials.size() == 1);
 
 1148                for (
auto const& o : credentials)
 
 1150                    auto const& c(o[jss::Credential]);
 
 1151                    BEAST_EXPECT(c[jss::Issuer].asString() == issuer.human());
 
 1153                        c[
"CredentialType"].asString() ==
 
 1169                    jDP.isObject() && jDP.isMember(jss::result) &&
 
 1170                    jDP[jss::result].isMember(jss::error) &&
 
 1171                    jDP[jss::result][jss::error] == 
"entryNotFound");
 
 
 1179        using namespace jtx;
 
 1180        char const credType[] = 
"abcde";
 
 1181        char const credType2[] = 
"fghijkl";
 
 1182        Account const issuer{
"issuer"};
 
 1186        IOU const USD = gw[
"USD"];
 
 1190            testcase(
"Payment failure with expired credentials.");
 
 1194            env.
fund(
XRP(10000), issuer, alice, bob, gw);
 
 1203                                   .parentCloseTime.time_since_epoch()
 
 1206            jv[sfExpiration.jsonName] = t;
 
 1218                                    .parentCloseTime.time_since_epoch()
 
 1221            jv[sfExpiration.jsonName] = t2;
 
 1232            std::string const credIdx = jv[jss::result][jss::index].asString();
 
 1234            std::string const credIdx2 = jv[jss::result][jss::index].asString();
 
 1241                bob, {{issuer, credType}, {issuer, credType2}}));
 
 1246                env(
pay(alice, bob, 
XRP(100)),
 
 1252                env(
pay(alice, bob, 
XRP(100)),
 
 1259                    auto const jDelCred =
 
 1262                        jDelCred.isObject() && jDelCred.isMember(jss::result) &&
 
 1263                        jDelCred[jss::result].isMember(jss::error) &&
 
 1264                        jDelCred[jss::result][jss::error] == 
"entryNotFound");
 
 1272                        jle.isObject() && jle.isMember(jss::result) &&
 
 1273                        !jle[jss::result].isMember(jss::error) &&
 
 1274                        jle[jss::result].isMember(jss::node) &&
 
 1275                        jle[jss::result][jss::node].isMember(
 
 1276                            "LedgerEntryType") &&
 
 1277                        jle[jss::result][jss::node][
"LedgerEntryType"] ==
 
 1279                        jle[jss::result][jss::node][jss::Issuer] ==
 
 1281                        jle[jss::result][jss::node][jss::Subject] ==
 
 1283                        jle[jss::result][jss::node][
"CredentialType"] ==
 
 1295                                       .parentCloseTime.time_since_epoch()
 
 1298                jv[sfExpiration.jsonName] = t;
 
 1306                    jv[jss::result][jss::index].asString();
 
 1316                env(
pay(gw, bob, USD(150)),
 
 1322                auto const jDelCred =
 
 1325                    jDelCred.isObject() && jDelCred.isMember(jss::result) &&
 
 1326                    jDelCred[jss::result].isMember(jss::error) &&
 
 1327                    jDelCred[jss::result][jss::error] == 
"entryNotFound");
 
 1337            testcase(
"Escrow failure with expired credentials.");
 
 1341            env.
fund(
XRP(5000), issuer, alice, bob, zelda);
 
 1348                                   .parentCloseTime.time_since_epoch()
 
 1351            jv[sfExpiration.jsonName] = t;
 
 1361            std::string const credIdx = jv[jss::result][jss::index].asString();
 
 1370            auto const seq = env.
seq(alice);
 
 1386                    "0E0B04ED60588A758B67E21FBBE95AC5A63598BA951761DC0EC9C08D7E" 
 1404            auto const jDelCred =
 
 1407                jDelCred.isObject() && jDelCred.isMember(jss::result) &&
 
 1408                jDelCred[jss::result].isMember(jss::error) &&
 
 1409                jDelCred[jss::result][jss::error] == 
"entryNotFound");
 
 
 1416        using namespace jtx;
 
 1426        env.
fund(
XRP(5000), stock, alice, bob);
 
 1438        for (
auto const& c : credentials)
 
 1439            env.
fund(
XRP(5000), c.issuer);
 
 1447            for (
auto const& c : credentials)
 
 1448                pubKey2Acc.
emplace(c.issuer.human(), c.issuer);
 
 1451            for (
int i = 0; i < 10; ++i)
 
 1459                auto const& authCred(
 
 1460                    dp[jss::result][jss::node][
"AuthorizeCredentials"]);
 
 1462                    authCred.isArray() &&
 
 1463                    authCred.size() == credentials.
size());
 
 1465                for (
auto const& o : authCred)
 
 1467                    auto const& c(o[jss::Credential]);
 
 1468                    auto issuer = c[jss::Issuer].asString();
 
 1470                    if (BEAST_EXPECT(pubKey2Acc.
contains(issuer)))
 
 1472                            pubKey2Acc.
at(issuer),
 
 1473                            c[
"CredentialType"].asString());
 
 1489            for (
int i = 0; i < 10; ++i)
 
 1497        testcase(
"Check duplicate credentials.");
 
 1501                credentials.
begin(), credentials.
end() - 1);
 
 1504            for (
auto const& c : copyCredentials)
 
 1506                auto credentials2 = copyCredentials;
 
 1514            for (
auto const& c : credentials)
 
 1525                                            c.credType)[jss::result][jss::index]
 
 1530            for (
auto const& h : credentialIDs)
 
 1532                auto credentialIDs2 = credentialIDs;
 
 1535                env(
pay(alice, bob, 
XRP(100)),
 
 
 1548        testPayment(supported - featureDepositPreauth - featureCredentials);
 
 
 
 1559BEAST_DEFINE_TESTSUITE(DepositAuth, app, 
ripple);
 
Value & append(Value const &value)
Append value to array at the end.
 
Value removeMember(char const *key)
Remove and return the named member.
 
std::string asString() const
Returns the unquoted string value.
 
testcase_t testcase
Memberspace for declaring test cases.
 
bool expect(Condition const &shouldBeTrue)
Evaluate a test condition.
 
Immutable cryptographic account descriptor.
 
std::string const & human() const
Returns the human readable public key.
 
A transaction testing environment.
 
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
 
void require(Args const &... args)
Check a set of requirements.
 
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.
 
NetClock::time_point now()
Returns the current network time.
 
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)
 
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
 
void memoize(Account const &account)
Associate AccountID with account.
 
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
 
Converts to IOU Issue or STAmount.
 
Match clear account flags.
 
Match the number of items in the account's owner directory.
 
Check a set of conditions.
 
Sets the SendMax 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.
 
T emplace_back(T... args)
 
@ arrayValue
array value (ordered list)
 
@ objectValue
object value (collection of name/value pairs).
 
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 unauth(Account const &account, Account const &unauth)
Remove preauthorization for deposit.
 
Json::Value auth(Account const &account, Account const &auth)
Preauthorize for deposit.
 
Json::Value unauthCredentials(jtx::Account const &account, std::vector< AuthorizeCredentials > const &auth)
 
Json::Value authCredentials(jtx::Account const &account, std::vector< AuthorizeCredentials > const &auth)
 
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 finish(AccountID const &account, AccountID const &from, std::uint32_t seq)
 
Json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
 
std::uint32_t ownerCount(Env const &env, Account const &account)
 
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
 
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()
 
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
 
owner_count< ltTICKET > tickets
Match the number of tickets on the account.
 
XRP_t const XRP
Converts to XRP Issue or STAmount.
 
static Json::Value ledgerEntryDepositPreauth(jtx::Env &env, jtx::Account const &acc, std::vector< jtx::deposit::AuthorizeCredentials > const &auth)
 
static bool hasDepositAuth(jtx::Env const &env, jtx::Account const &acct)
 
static XRPAmount reserve(jtx::Env &env, std::uint32_t count)
 
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
 
constexpr std::uint32_t asfDepositAuth
 
AccountID const & xrpAccount()
Compute AccountID from public key.
 
constexpr std::uint32_t tfPassive
 
std::string strHex(FwdIt begin, FwdIt end)
 
@ tecINSUFFICIENT_RESERVE
 
std::string to_string(base_uint< Bits, Tag > const &a)
 
constexpr std::uint32_t tfSell
 
TERSubset< CanCvtToTER > TER
 
constexpr std::uint32_t tfSetNoRipple
 
void run() override
Runs the suite.
 
void testCredentialsCreation()
 
void testPayment(FeatureBitset features)
 
void run() override
Runs the suite.
 
void testSortingCredentials()
 
void testCredentialsPayment()
 
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...
 
Set the sequence number on a JTx.