3#include <xrpld/app/tx/applySteps.h>
5#include <xrpl/ledger/Dir.h>
6#include <xrpl/protocol/Feature.h>
7#include <xrpl/protocol/Indexes.h>
8#include <xrpl/protocol/TxFlags.h>
9#include <xrpl/protocol/jss.h>
27 Env env(*
this, features);
28 auto const baseFee = env.
current()->fees().base;
29 env.
fund(
XRP(5000),
"alice",
"bob");
34 auto const seq1 = env.
seq(
"alice");
46 auto const seq2 = env.
seq(
"alice");
65 Env env(*
this, features);
66 auto const baseFee = env.
current()->fees().base;
67 env.
fund(
XRP(5000),
"alice",
"bob");
71 auto const ts = env.
now() + 97s;
73 auto const seq = env.
seq(
"alice");
89 Env env(*
this, features);
90 auto const baseFee = env.
current()->fees().base;
91 env.
fund(
XRP(5000),
"alice",
"bob");
95 auto const ts = env.
now() + 117s;
97 auto const seq = env.
seq(
"alice");
121 testcase(
"Timing: Finish and Cancel -> Finish");
122 Env env(*
this, features);
123 auto const baseFee = env.
current()->fees().base;
124 env.
fund(
XRP(5000),
"alice",
"bob");
128 auto const fts = env.
now() + 117s;
129 auto const cts = env.
now() + 192s;
131 auto const seq = env.
seq(
"alice");
138 for (; env.
now() < fts; env.
close())
158 testcase(
"Timing: Finish and Cancel -> Cancel");
159 Env env(*
this, features);
160 auto const baseFee = env.
current()->fees().base;
161 env.
fund(
XRP(5000),
"alice",
"bob");
165 auto const fts = env.
now() + 109s;
166 auto const cts = env.
now() + 184s;
168 auto const seq = env.
seq(
"alice");
175 for (; env.
now() < fts; env.
close())
187 for (; env.
now() < cts; env.
close())
211 Env env(*
this, features);
213 auto const alice =
Account(
"alice");
214 auto const bob =
Account(
"bob");
216 env.
fund(
XRP(5000), alice, bob);
226 auto const seq = env.
seq(alice);
235 BEAST_EXPECT((*sle)[sfSourceTag] == 1);
236 BEAST_EXPECT((*sle)[sfDestinationTag] == 2);
237 if (features[fixIncludeKeyletFields])
239 BEAST_EXPECT((*sle)[sfSequence] ==
seq);
243 BEAST_EXPECT(!sle->isFieldPresent(sfSequence));
257 Env env(*
this, features - featureDepositAuth);
259 env.
fund(
XRP(5000),
"bob",
"george");
268 Env env(*
this, features);
270 env.
fund(
XRP(5000),
"bob",
"george");
283 testcase(
"RequiresConditionOrFinishAfter");
285 Env env(*
this, features);
286 auto const baseFee = env.
current()->fees().base;
287 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
298 auto const seq = env.
seq(
"alice");
308 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5100));
312 auto const seqFt = env.
seq(
"alice");
333 Env env(*
this, features);
334 auto const baseFee = env.
current()->fees().base;
335 env.
fund(
XRP(5000),
"alice",
"bob",
"gw");
363 bool const withTokenEscrow =
364 env.
current()->rules().enabled(featureTokenEscrow);
368 auto const txResult =
426 auto const accountReserve =
drops(env.
current()->fees().reserve);
427 auto const accountIncrement =
430 env.
fund(accountReserve + accountIncrement +
XRP(50),
"daniel");
435 env.
fund(accountReserve + accountIncrement +
XRP(50),
"evan");
440 env.
fund(accountReserve,
"frank");
448 auto const seq = env.
seq(
"hannah");
460 auto const seq = env.
seq(
"ivan");
483 Env env(*
this, features);
484 auto const baseFee = env.
current()->fees().base;
485 env.
fund(
XRP(5000),
"alice",
"bob");
486 auto const seq = env.
seq(
"alice");
508 Env env(*
this, features);
509 auto const baseFee = env.
current()->fees().base;
510 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
511 auto const seq = env.
seq(
"alice");
535 Env env(*
this, features);
536 auto const baseFee = env.
current()->fees().base;
538 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
542 auto const seq = env.
seq(
"alice");
574 Env env(*
this, features);
575 auto const baseFee = env.
current()->fees().base;
577 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
583 auto const seq = env.
seq(
"alice");
602 Env env(*
this, features);
603 auto const baseFee = env.
current()->fees().base;
604 env.
fund(
XRP(5000),
"alice",
"bob");
605 auto const seq = env.
seq(
"alice");
646 Env env(*
this, features);
647 auto const baseFee = env.
current()->fees().base;
649 env.
fund(
XRP(5000),
"alice",
"bob");
650 auto const seq = env.
seq(
"alice");
685 Env env(*
this, features);
686 auto const baseFee = env.
current()->fees().base;
688 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
689 auto const seq = env.
seq(
"alice");
734 testcase(
"Escrow with CryptoConditions");
740 Env env(*
this, features);
741 auto const baseFee = env.
current()->fees().base;
742 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
743 auto const seq = env.
seq(
"alice");
744 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
748 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
752 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
757 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
765 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
771 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
777 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
786 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
792 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
798 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
808 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
811 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
815 Env env(*
this, features);
816 auto const baseFee = env.
current()->fees().base;
817 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
818 auto const seq = env.
seq(
"alice");
819 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
832 Env env(*
this, features);
833 auto const baseFee = env.
current()->fees().base;
834 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
836 auto const seq = env.
seq(
"alice");
840 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
843 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
851 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
855 Env env(*
this, features);
856 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
862 auto const p = v.
data();
863 auto const s = v.
size();
865 auto const ts = env.
now() + 1s;
898 auto const seq = env.
seq(
"alice");
899 auto const baseFee = env.
current()->fees().base;
913 Env env(*
this, features);
914 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
920 auto const cp = cv.
data();
921 auto const cs = cv.
size();
927 auto const fp = fv.
data();
928 auto const fs = fv.
size();
930 auto const ts = env.
now() + 1s;
963 auto const seq = env.
seq(
"alice");
964 auto const baseFee = env.
current()->fees().base;
1054 fee(150 * baseFee));
1060 Env env(*
this, features);
1061 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
1068 auto const seq = env.
seq(
"alice");
1069 auto const baseFee = env.
current()->fees().base;
1103 fee(150 * baseFee));
1109 Env env(*
this, features);
1110 env.
fund(
XRP(5000),
"alice",
"bob");
1113 {0xA2, 0x2B, 0x80, 0x20, 0x42, 0x4A, 0x70, 0x49, 0x49,
1114 0x52, 0x92, 0x67, 0xB6, 0x21, 0xB3, 0xD7, 0x91, 0x19,
1115 0xD7, 0x29, 0xB2, 0x38, 0x2C, 0xED, 0x8B, 0x29, 0x6C,
1116 0x3C, 0x02, 0x8F, 0xA9, 0x7D, 0x35, 0x0F, 0x6D, 0x07,
1117 0x81, 0x03, 0x06, 0x34, 0xD2, 0x82, 0x02, 0x03, 0xC8}};
1131 using namespace jtx;
1134 auto const alice =
Account(
"alice");
1135 auto const bruce =
Account(
"bruce");
1136 auto const carol =
Account(
"carol");
1141 Env env(*
this, features);
1142 env.
fund(
XRP(5000), alice, bruce, carol);
1143 auto const aseq = env.
seq(alice);
1144 auto const bseq = env.
seq(bruce);
1150 (*env.
meta())[sfTransactionResult] ==
1167 (*env.
meta())[sfTransactionResult] ==
1185 (*env.
meta())[sfTransactionResult] ==
1204 (*env.
meta())[sfTransactionResult] ==
1216 Env env(*
this, features);
1217 env.
fund(
XRP(5000), alice, bruce, carol);
1218 auto const aseq = env.
seq(alice);
1219 auto const bseq = env.
seq(bruce);
1224 (*env.
meta())[sfTransactionResult] ==
1231 (*env.
meta())[sfTransactionResult] ==
1311 using namespace jtx;
1313 Env env(*
this, features);
1314 auto const baseFee = env.
current()->fees().base;
1321 auto const jtx = env.
jt(
1333 BEAST_EXPECT(!pf.consequences.isBlocker());
1334 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1335 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(1000));
1348 BEAST_EXPECT(!pf.consequences.isBlocker());
1349 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1350 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1363 BEAST_EXPECT(!pf.consequences.isBlocker());
1364 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1365 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1374 using namespace jtx;
1381 Env env(*
this, features);
1382 auto const baseFee = env.
current()->fees().base;
1383 env.
fund(
XRP(5000), alice, bob);
1406 auto const ts = env.
now() + 97s;
1412 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1418 for (; env.
now() < ts; env.
close())
1424 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1438 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1442 Env env(*
this, features);
1443 auto const baseFee = env.
current()->fees().base;
1444 env.
fund(
XRP(5000), alice, bob);
1466 auto const ts = env.
now() + 117s;
1473 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1479 for (; env.
now() < ts; env.
close())
1485 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1495 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1502 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1514 using namespace jtx;
1520 Account const dillon{
"dillon "};
1523 char const credType[] =
"abcde";
1527 Env env(*
this, features - featureCredentials);
1528 env.
fund(
XRP(5000), alice, bob);
1531 auto const seq = env.
seq(alice);
1542 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1550 Env env(*
this, features);
1552 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1559 std::string const credIdx = jv[jss::result][jss::index].asString();
1561 auto const seq = env.
seq(alice);
1600 testcase(
"Escrow with credentials without depositPreauth");
1603 Env env(*
this, features);
1605 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1614 std::string const credIdx = jv[jss::result][jss::index].asString();
1616 auto const seq = env.
seq(alice);
1632 char const credType2[] =
"fghijk";
1638 auto const credIdxBob =
1640 env, bob, zelda, credType2)[jss::result][jss::index]
1643 auto const seq = env.
seq(alice);
1683 using namespace test::jtx;
std::string asString() const
Returns the unquoted string value.
testcase_t testcase
Memberspace for declaring test cases.
A class that simplifies iterating ledger directory pages.
const_iterator end() const
const_iterator begin() const
An immutable linear range of bytes.
Immutable cryptographic account descriptor.
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.
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
NetClock::time_point now()
Returns the current network time.
beast::Journal const journal
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
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.
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 escrow(AccountID const &src, std::uint32_t seq) noexcept
An escrow 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 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)
std::array< std::uint8_t, 7 > const fb2
std::array< std::uint8_t, 8 > const fb3
std::array< std::uint8_t, 39 > const cb1
std::array< std::uint8_t, 39 > const cb3
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)
std::array< std::uint8_t, 39 > const cb2
auto const cancel_time
Set the "CancelAfter" time tag on a JTx.
std::array< std::uint8_t, 4 > const fb1
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.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
FeatureBitset testable_amendments()
owner_count< ltTICKET > tickets
Match the number of tickets on the account.
XRP_t const XRP
Converts to XRP Issue or STAmount.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t asfDepositAuth
PreflightResult preflight(Application &app, Rules const &rules, STTx const &tx, ApplyFlags flags, beast::Journal j)
Gate a transaction based on static information.
constexpr std::uint32_t asfRequireDest
constexpr std::uint32_t tfPassive
@ tecCRYPTOCONDITION_ERROR
@ tecINSUFFICIENT_RESERVE
constexpr std::uint32_t asfDisallowXRP
void run() override
Runs the suite.
void testLockup(FeatureBitset features)
void testCredentials(FeatureBitset features)
void testFails(FeatureBitset features)
void testEscrowConditions(FeatureBitset features)
void testTags(FeatureBitset features)
void testMetaAndOwnership(FeatureBitset features)
void testConsequences(FeatureBitset features)
void testEnablement(FeatureBitset features)
void testRequiresConditionOrFinishAfter(FeatureBitset features)
void testWithFeats(FeatureBitset features)
void testEscrowWithTickets(FeatureBitset features)
void testDisallowXRP(FeatureBitset features)
void testTiming(FeatureBitset features)
Set the destination tag on a JTx.
Set the sequence number on a JTx.
Set the source tag on a JTx.