2#include <test/jtx/Account.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/TestHelpers.h>
5#include <test/jtx/acctdelete.h>
6#include <test/jtx/amount.h>
7#include <test/jtx/credentials.h>
8#include <test/jtx/deposit.h>
9#include <test/jtx/directory.h>
10#include <test/jtx/fee.h>
11#include <test/jtx/noop.h>
12#include <test/jtx/pay.h>
13#include <test/jtx/permissioned_domains.h>
14#include <test/jtx/ter.h>
15#include <test/jtx/ticket.h>
16#include <test/jtx/txflags.h>
18#include <xrpl/basics/strHex.h>
19#include <xrpl/beast/unit_test/suite.h>
20#include <xrpl/json/to_string.h>
21#include <xrpl/ledger/ApplyView.h>
22#include <xrpl/ledger/ApplyViewImpl.h>
23#include <xrpl/ledger/helpers/CredentialHelpers.h>
24#include <xrpl/protocol/AccountID.h>
25#include <xrpl/protocol/Feature.h>
26#include <xrpl/protocol/Indexes.h>
27#include <xrpl/protocol/LedgerFormats.h>
28#include <xrpl/protocol/Protocol.h>
29#include <xrpl/protocol/SField.h>
30#include <xrpl/protocol/STTx.h>
31#include <xrpl/protocol/TER.h>
32#include <xrpl/protocol/TxFlags.h>
33#include <xrpl/protocol/jss.h>
49 char const credType[] =
"abcde";
50 char const uri[] =
"uri";
53 Account const subject{
"subject"};
56 Env env{*
this, features};
63 env.
fund(
XRP(5000), subject, issuer, other);
70 auto const sleCred = env.
le(credKey);
71 BEAST_EXPECT(
static_cast<bool>(sleCred));
75 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == subject.
id());
76 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.
id());
77 BEAST_EXPECT(!sleCred->getFieldU32(sfFlags));
80 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
81 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
84 jle.isObject() && jle.isMember(jss::result) &&
85 !jle[jss::result].isMember(jss::error) &&
86 jle[jss::result].isMember(jss::node) &&
87 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
88 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
89 jle[jss::result][jss::node][jss::Issuer] == issuer.
human() &&
90 jle[jss::result][jss::node][jss::Subject] == subject.
human() &&
91 jle[jss::result][jss::node][
"CredentialType"] ==
100 auto const sleCred = env.
le(credKey);
101 BEAST_EXPECT(
static_cast<bool>(sleCred));
105 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == subject.
id());
106 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.
id());
109 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
110 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
111 BEAST_EXPECT(sleCred->getFieldU32(sfFlags) == lsfAccepted);
117 BEAST_EXPECT(!env.
le(credKey));
124 jle.isObject() && jle.isMember(jss::result) &&
125 jle[jss::result].isMember(jss::error) &&
126 jle[jss::result][jss::error] ==
"entryNotFound");
138 auto const sleCred = env.
le(credKey);
139 BEAST_EXPECT(
static_cast<bool>(sleCred));
143 BEAST_EXPECT(sleCred->getAccountID(sfSubject) == issuer.
id());
144 BEAST_EXPECT(sleCred->getAccountID(sfIssuer) == issuer.
id());
145 BEAST_EXPECT(sleCred->isFlag(lsfAccepted));
147 sleCred->getFieldU64(sfIssuerNode) == sleCred->getFieldU64(sfSubjectNode));
149 BEAST_EXPECT(
checkVL(sleCred, sfCredentialType, credType));
150 BEAST_EXPECT(
checkVL(sleCred, sfURI, uri));
153 jle.isObject() && jle.isMember(jss::result) &&
154 !jle[jss::result].isMember(jss::error) &&
155 jle[jss::result].isMember(jss::node) &&
156 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
157 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
158 jle[jss::result][jss::node][jss::Issuer] == issuer.
human() &&
159 jle[jss::result][jss::node][jss::Subject] == issuer.
human() &&
160 jle[jss::result][jss::node][
"CredentialType"] ==
167 BEAST_EXPECT(!env.
le(credKey));
173 jle.isObject() && jle.isMember(jss::result) &&
174 jle[jss::result].isMember(jss::error) &&
175 jle[jss::result][jss::error] ==
"entryNotFound");
185 char const credType[] =
"abcde";
187 Account const issuer{
"issuer"};
188 Account const subject{
"subject"};
191 Env env{*
this, features};
194 env.
fund(
XRP(5000), issuer, subject, other);
198 testcase(
"Delete issuer before accept");
206 int const delta = env.
seq(issuer) + 255;
207 for (
int i = 0; i < delta; ++i)
209 auto const acctDelFee{
drops(env.
current()->fees().increment)};
216 BEAST_EXPECT(!env.
le(credKey));
222 jle.isObject() && jle.isMember(jss::result) &&
223 jle[jss::result].isMember(jss::error) &&
224 jle[jss::result][jss::error] ==
"entryNotFound");
233 testcase(
"Delete issuer after accept");
243 int const delta = env.
seq(issuer) + 255;
244 for (
int i = 0; i < delta; ++i)
246 auto const acctDelFee{
drops(env.
current()->fees().increment)};
253 BEAST_EXPECT(!env.
le(credKey));
259 jle.isObject() && jle.isMember(jss::result) &&
260 jle[jss::result].isMember(jss::error) &&
261 jle[jss::result][jss::error] ==
"entryNotFound");
270 testcase(
"Delete subject before accept");
278 int const delta = env.
seq(subject) + 255;
279 for (
int i = 0; i < delta; ++i)
281 auto const acctDelFee{
drops(env.
current()->fees().increment)};
288 BEAST_EXPECT(!env.
le(credKey));
294 jle.isObject() && jle.isMember(jss::result) &&
295 jle[jss::result].isMember(jss::error) &&
296 jle[jss::result][jss::error] ==
"entryNotFound");
305 testcase(
"Delete subject after accept");
315 int const delta = env.
seq(subject) + 255;
316 for (
int i = 0; i < delta; ++i)
318 auto const acctDelFee{
drops(env.
current()->fees().increment)};
325 BEAST_EXPECT(!env.
le(credKey));
331 jle.isObject() && jle.isMember(jss::result) &&
332 jle[jss::result].isMember(jss::error) &&
333 jle[jss::result][jss::error] ==
"entryNotFound");
346 uint32_t
const t = env.
current()->header().parentCloseTime.time_since_epoch().count();
347 jv[sfExpiration.jsonName] = t + 20;
361 BEAST_EXPECT(!env.
le(credKey));
368 jle.isObject() && jle.isMember(jss::result) &&
369 jle[jss::result].isMember(jss::error) &&
370 jle[jss::result][jss::error] ==
"entryNotFound");
385 BEAST_EXPECT(!env.
le(credKey));
390 jle.isObject() && jle.isMember(jss::result) &&
391 jle[jss::result].isMember(jss::error) &&
392 jle[jss::result][jss::error] ==
"entryNotFound");
405 BEAST_EXPECT(!env.
le(credKey));
410 jle.isObject() && jle.isMember(jss::result) &&
411 jle[jss::result].isMember(jss::error) &&
412 jle[jss::result][jss::error] ==
"entryNotFound");
422 char const credType[] =
"abcde";
424 Account const issuer{
"issuer"};
425 Account const subject{
"subject"};
429 Env env{*
this, features};
431 env.
fund(
XRP(5000), subject, issuer);
435 testcase(
"Credentials fail, no subject param.");
437 jv.removeMember(jss::Subject);
448 testcase(
"Credentials fail, no credentialType param.");
450 jv.removeMember(sfCredentialType.jsonName);
455 testcase(
"Credentials fail, empty credentialType param.");
462 "Credentials fail, credentialType length > "
463 "maxCredentialTypeLength.");
465 "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
466 "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p";
473 testcase(
"Credentials fail, URI length > 256.");
475 "abcdefghijklmnopqrstuvwxyz01234567890qwertyuiop[]"
476 "asdfghjkl;'zxcvbnm8237tr28weufwldebvfv8734t07p "
477 "9hfup;wDJFBVSD8f72 "
479 "djvbldafghwpEFHdjfaidfgio84763tfysgdvhjasbd "
480 "vujhgWQIE7F6WEUYFGWUKEYFVQW87FGWOEFWEFUYWVEF8723GFWEFB"
482 "fv28o37gfwEFB3872TFO8GSDSDVD";
490 testcase(
"Credentials fail, URI empty.");
497 testcase(
"Credentials fail, expiration in the past.");
501 env.
current()->header().parentCloseTime.time_since_epoch().count() - 1;
502 jv[sfExpiration.jsonName] = t;
507 testcase(
"Credentials fail, invalid fee.");
515 testcase(
"Credentials fail, duplicate.");
525 jle.isObject() && jle.isMember(jss::result) &&
526 !jle[jss::result].isMember(jss::error) &&
527 jle[jss::result].isMember(jss::node) &&
528 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
529 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
530 jle[jss::result][jss::node][jss::Issuer] == issuer.
human() &&
531 jle[jss::result][jss::node][jss::Subject] == subject.
human() &&
532 jle[jss::result][jss::node][
"CredentialType"] ==
537 testcase(
"Credentials fail, directory full");
573 Env env{*
this, features};
579 testcase(
"Credentials fail, subject doesn't exist.");
587 Env env{*
this, features};
593 testcase(
"Credentials fail, not enough reserve.");
607 char const credType[] =
"abcde";
608 Account const issuer{
"issuer"};
609 Account const subject{
"subject"};
613 Env env{*
this, features};
615 env.
fund(
XRP(5000), subject, issuer);
618 testcase(
"CredentialsAccept fail, Credential doesn't exist.");
624 testcase(
"CredentialsAccept fail, invalid Issuer account.");
632 testcase(
"CredentialsAccept fail, invalid credentialType param.");
639 Env env{*
this, features};
646 testcase(
"CredentialsAccept fail, not enough reserve.");
656 jle.isObject() && jle.isMember(jss::result) &&
657 !jle[jss::result].isMember(jss::error) &&
658 jle[jss::result].isMember(jss::node) &&
659 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
660 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
661 jle[jss::result][jss::node][jss::Issuer] == issuer.
human() &&
662 jle[jss::result][jss::node][jss::Subject] == subject.
human() &&
663 jle[jss::result][jss::node][
"CredentialType"] ==
670 Env env{*
this, features};
672 env.
fund(
XRP(5000), subject, issuer);
679 testcase(
"CredentialsAccept fail, invalid fee.");
684 testcase(
"CredentialsAccept fail, lsfAccepted already set.");
693 jle.isObject() && jle.isMember(jss::result) &&
694 !jle[jss::result].isMember(jss::error) &&
695 jle[jss::result].isMember(jss::node) &&
696 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
697 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
698 jle[jss::result][jss::node][jss::Issuer] == issuer.
human() &&
699 jle[jss::result][jss::node][jss::Subject] == subject.
human() &&
700 jle[jss::result][jss::node][
"CredentialType"] ==
705 char const credType2[] =
"efghi";
707 testcase(
"CredentialsAccept fail, expired credentials.");
710 env.
current()->header().parentCloseTime.time_since_epoch().count();
711 jv[sfExpiration.jsonName] = t;
722 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
723 jDelCred[jss::result].isMember(jss::error) &&
724 jDelCred[jss::result][jss::error] ==
"entryNotFound");
733 Env env{*
this, features};
735 env.
fund(
XRP(5000), issuer, subject, other);
739 testcase(
"CredentialsAccept fail, issuer doesn't exist.");
745 int const delta = env.
seq(issuer) + 255;
746 for (
int i = 0; i < delta; ++i)
748 auto const acctDelFee{
drops(env.
current()->fees().increment)};
759 jDelCred.isObject() && jDelCred.isMember(jss::result) &&
760 jDelCred[jss::result].isMember(jss::error) &&
761 jDelCred[jss::result][jss::error] ==
"entryNotFound");
771 char const credType[] =
"abcde";
772 Account const issuer{
"issuer"};
773 Account const subject{
"subject"};
778 Env env{*
this, features};
780 env.
fund(
XRP(5000), subject, issuer, other);
784 testcase(
"CredentialsDelete fail, no Credentials.");
790 testcase(
"CredentialsDelete fail, invalid Subject account.");
798 testcase(
"CredentialsDelete fail, invalid Issuer account.");
806 testcase(
"CredentialsDelete fail, invalid credentialType param.");
812 char const credType2[] =
"fghij";
825 jle.isObject() && jle.isMember(jss::result) &&
826 !jle[jss::result].isMember(jss::error) &&
827 jle[jss::result].isMember(jss::node) &&
828 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
829 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
830 jle[jss::result][jss::node][jss::Issuer] == issuer.
human() &&
831 jle[jss::result][jss::node][jss::Subject] == subject.
human() &&
832 jle[jss::result][jss::node][
"CredentialType"] ==
837 testcase(
"CredentialsDelete fail, time not expired yet.");
842 env.
current()->header().parentCloseTime.time_since_epoch().count() + 1000;
843 jv[sfExpiration.jsonName] = t;
855 jle.isObject() && jle.isMember(jss::result) &&
856 !jle[jss::result].isMember(jss::error) &&
857 jle[jss::result].isMember(jss::node) &&
858 jle[jss::result][jss::node].isMember(
"LedgerEntryType") &&
859 jle[jss::result][jss::node][
"LedgerEntryType"] == jss::Credential &&
860 jle[jss::result][jss::node][jss::Issuer] == issuer.
human() &&
861 jle[jss::result][jss::node][jss::Subject] == subject.
human() &&
862 jle[jss::result][jss::node][
"CredentialType"] ==
867 testcase(
"CredentialsDelete fail, no Issuer and Subject.");
870 jv.removeMember(jss::Subject);
871 jv.removeMember(jss::Issuer);
877 testcase(
"CredentialsDelete fail, invalid fee.");
886 testcase(
"deleteSLE fail, bad SLE.");
900 char const credType[] =
"abcde";
901 Account const issuer{
"issuer"};
902 Account const subject{
"subject"};
906 Env env{*
this, features};
908 env.
fund(
XRP(5000), subject, issuer);
912 testcase(
"Credentials fail, Feature is not enabled.");
925 char const credType[] =
"abcde";
926 Account const issuer{
"issuer"};
927 Account const subject{
"subject"};
933 env.
fund(
XRP(5000), subject, issuer);
947 params[jss::account] = subject.
human();
948 auto const jv = env.
rpc(
"json",
"account_tx",
to_string(params))[jss::result];
950 BEAST_EXPECT(jv[jss::transactions].size() == 4);
951 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
952 BEAST_EXPECT(tx0[jss::TransactionType] == jss::CredentialAccept);
953 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
954 BEAST_EXPECT(tx1[jss::TransactionType] == jss::CredentialCreate);
955 txHash0 = tx0[jss::hash].asString();
956 txHash1 = tx1[jss::hash].asString();
961 params[jss::account] = issuer.
human();
962 auto const jv = env.
rpc(
"json",
"account_tx",
to_string(params))[jss::result];
964 BEAST_EXPECT(jv[jss::transactions].size() == 4);
965 auto const& tx0(jv[jss::transactions][0u][jss::tx]);
966 BEAST_EXPECT(tx0[jss::TransactionType] == jss::CredentialAccept);
967 auto const& tx1(jv[jss::transactions][1u][jss::tx]);
968 BEAST_EXPECT(tx1[jss::TransactionType] == jss::CredentialCreate);
970 BEAST_EXPECT(txHash0 == tx0[jss::hash].asString());
971 BEAST_EXPECT(txHash1 == tx1[jss::hash].asString());
978 params[jss::account] = subject.
human();
979 auto jv = env.
rpc(
"json",
"account_objects",
to_string(params))[jss::result];
981 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
982 auto const& object(jv[jss::account_objects][0u]);
984 BEAST_EXPECT(
object[
"LedgerEntryType"].asString() == jss::Credential);
985 objectIdx =
object[jss::index].asString();
990 params[jss::account] = issuer.
human();
991 auto jv = env.
rpc(
"json",
"account_objects",
to_string(params))[jss::result];
993 BEAST_EXPECT(jv[jss::account_objects].size() == 1);
994 auto const& object(jv[jss::account_objects][0u]);
996 BEAST_EXPECT(
object[
"LedgerEntryType"].asString() == jss::Credential);
997 BEAST_EXPECT(objectIdx ==
object[jss::index].asString());
1007 bool const enabled = features[fixInvalidTxFlags];
1010 char const credType[] =
"abcde";
1011 Account const issuer{
"issuer"};
1012 Account const subject{
"subject"};
1015 using namespace jtx;
1016 Env env{*
this, features};
1018 env.
fund(
XRP(5000), subject, issuer);
1039 bool const fixEnabled = features[fixCleanup3_1_3];
1041 "removeExpired ignores deleteSLE failure " +
1046 char const credType[] =
"abcde";
1047 Account const issuer{
"issuer"};
1048 Account const subject{
"subject"};
1051 Env env{*
this, features};
1052 env.
fund(
XRP(10000), issuer, subject, becky);
1057 uint32_t
const expiration =
1058 env.
current()->header().parentCloseTime.time_since_epoch().count() + 40;
1059 jv[sfExpiration.jsonName] = expiration;
1064 std::string const credIdx = credLE[jss::result][jss::index].asString();
1071 auto const credKeylet =
1076 auto const sleCred = env.
current()->read(credKeylet);
1077 BEAST_EXPECT(sleCred && sleCred->isFlag(lsfAccepted));
1085 if (!BEAST_EXPECT(
jtx.stx))
1090 env(
pdomain::setTx(becky, {{.issuer = issuer, .credType = credType}}));
1093 if (!BEAST_EXPECT(!objects.empty()))
1095 auto const domain = objects.begin()->first;
1097 using namespace std::chrono_literals;
1102 auto const sleCred = env.
current()->read(credKeylet);
1115 if (!BEAST_EXPECT(sleIssuer))
1117 av.
erase(sleIssuer);
1121 BEAST_EXPECT(av.
exists(credKeylet));
1125 credHashes.
pushBack(credKeylet.key);
1129 auto sleCredAfter = av.
read(credKeylet);
1130 BEAST_EXPECT(sleCredAfter && sleCredAfter->isFlag(lsfAccepted));
1133 sleCredAfter = av.
read(credKeylet);
1134 BEAST_EXPECT(sleCredAfter && sleCredAfter->isFlag(lsfAccepted));
A generic endpoint for log messages.
static Sink & getNullSink()
Returns a Sink which does nothing.
TestcaseT testcase
Memberspace for declaring test cases.
Editable, discardable view that can build metadata for one tx.
void pushBack(uint256 const &v)
An immutable linear range of bytes.
SLE::pointer peek(Keylet const &k) override
Prepare to modify the SLE associated with key.
SLE::const_pointer read(Keylet const &k) const override
Return the state item associated with a key.
void erase(SLE::ref sle) override
Remove a peeked SLE.
bool exists(Keylet const &k) const override
Determine if a state item exists.
Immutable cryptographic account descriptor.
std::string const & human() const
Returns the human readable public key.
AccountID id() const
Returns the Account ID.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
SLE::const_pointer le(Account const &account) const
Return an account root.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
beast::Journal const journal
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
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.
TER deleteSLE(ApplyView &view, SLE::ref sleCredential, beast::Journal j)
bool checkExpired(SLE const &sleCredential, NetClock::time_point const &closed)
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Keylet account(AccountID const &id) noexcept
AccountID root.
Keylet credential(AccountID const &subject, AccountID const &issuer, Slice const &credType) noexcept
json::Value deleteCred(jtx::Account const &acc, 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 create(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)
Keylet keylet(test::jtx::Account const &subject, test::jtx::Account const &issuer, std::string_view credType)
json::Value authCredentials(jtx::Account const &account, std::vector< AuthorizeCredentials > const &auth)
auto bumpLastPage(Env &env, std::uint64_t newLastPage, Keylet directory, std::function< bool(ApplyView &, uint256, std::uint64_t)> adjust) -> std::expected< void, Error >
Move the position of the last page in the user's directory on open ledger to newLastPage.
auto maximumPageIndex(Env const &env) -> std::uint64_t
bool adjustOwnerNode(ApplyView &view, uint256 key, std::uint64_t page)
Implementation of adjust for the most common ledger entry, i.e.
std::map< uint256, json::Value > getObjects(Account const &account, Env &env, bool withType)
json::Value setTx(AccountID const &account, Credentials const &credentials, std::optional< uint256 > domain)
json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
XrpT const XRP
Converts to XRP Issue or STAmount.
json::Value noop(Account const &account)
The null transaction.
std::uint32_t ownerCount(Env const &env, Account const &account)
FeatureBitset testableAmendments()
json::Value acctdelete(Account const &account, Account const &dest)
Delete account.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
bool checkVL(Slice const &result, std::string const &expected)
static XRPAmount reserve(jtx::Env &env, std::uint32_t count)
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::size_t kMaxCredentialTypeLength
The maximum length of a CredentialType inside a Credential.
TER verifyValidDomain(ApplyView &view, AccountID const &account, uint256 domainID, beast::Journal j)
std::string strHex(FwdIt begin, FwdIt end)
std::string to_string(BaseUInt< Bits, Tag > const &a)
void open(soci::session &s, BasicConfig const &config, std::string const &dbName)
Open a soci session.
constexpr std::size_t kMaxCredentialUriLength
The maximum length of a URI inside a Credential.
bool isTesSuccess(TER x) noexcept
TERSubset< CanCvtToTER > TER
AccountID const & xrpAccount()
Compute AccountID from public key.
@ tecINSUFFICIENT_RESERVE
TER verifyDepositPreauth(STTx const &tx, ApplyView &view, AccountID const &src, AccountID const &dst, SLE::const_ref sleDst, beast::Journal j)
void run() override
Runs the suite.
void testDeleteFailed(FeatureBitset features)
void testCredentialsDelete(FeatureBitset features)
void testRemoveExpiredCorruption(FeatureBitset features)
void testCreateFailed(FeatureBitset features)
void testAcceptFailed(FeatureBitset features)
void testFlags(FeatureBitset features)
void testFeatureFailed(FeatureBitset features)
void testSuccessful(FeatureBitset features)