22#include <xrpld/app/tx/applySteps.h>
24#include <xrpl/ledger/Dir.h>
25#include <xrpl/protocol/Feature.h>
26#include <xrpl/protocol/Indexes.h>
27#include <xrpl/protocol/TxFlags.h>
28#include <xrpl/protocol/jss.h>
46 Env env(*
this, features);
47 auto const baseFee = env.
current()->fees().base;
48 env.
fund(
XRP(5000),
"alice",
"bob");
53 auto const seq1 = env.
seq(
"alice");
65 auto const seq2 = env.
seq(
"alice");
84 Env env(*
this, features);
85 auto const baseFee = env.
current()->fees().base;
86 env.
fund(
XRP(5000),
"alice",
"bob");
90 auto const ts = env.
now() + 97s;
92 auto const seq = env.
seq(
"alice");
108 Env env(*
this, features);
109 auto const baseFee = env.
current()->fees().base;
110 env.
fund(
XRP(5000),
"alice",
"bob");
114 auto const ts = env.
now() + 117s;
116 auto const seq = env.
seq(
"alice");
140 testcase(
"Timing: Finish and Cancel -> Finish");
141 Env env(*
this, features);
142 auto const baseFee = env.
current()->fees().base;
143 env.
fund(
XRP(5000),
"alice",
"bob");
147 auto const fts = env.
now() + 117s;
148 auto const cts = env.
now() + 192s;
150 auto const seq = env.
seq(
"alice");
157 for (; env.
now() < fts; env.
close())
177 testcase(
"Timing: Finish and Cancel -> Cancel");
178 Env env(*
this, features);
179 auto const baseFee = env.
current()->fees().base;
180 env.
fund(
XRP(5000),
"alice",
"bob");
184 auto const fts = env.
now() + 109s;
185 auto const cts = env.
now() + 184s;
187 auto const seq = env.
seq(
"alice");
194 for (; env.
now() < fts; env.
close())
206 for (; env.
now() < cts; env.
close())
230 Env env(*
this, features);
232 auto const alice =
Account(
"alice");
233 auto const bob =
Account(
"bob");
235 env.
fund(
XRP(5000), alice, bob);
245 auto const seq = env.
seq(alice);
254 BEAST_EXPECT((*sle)[sfSourceTag] == 1);
255 BEAST_EXPECT((*sle)[sfDestinationTag] == 2);
256 if (features[fixIncludeKeyletFields])
258 BEAST_EXPECT((*sle)[sfSequence] ==
seq);
262 BEAST_EXPECT(!sle->isFieldPresent(sfSequence));
276 Env env(*
this, features - featureDepositAuth);
278 env.
fund(
XRP(5000),
"bob",
"george");
287 Env env(*
this, features);
289 env.
fund(
XRP(5000),
"bob",
"george");
303 testcase(
"Implied Finish Time (without fix1571)");
306 auto const baseFee = env.
current()->fees().base;
307 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
312 auto const seq1 = env.
seq(
"alice");
318 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5100));
324 auto const seq2 = env.
seq(
"alice");
334 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5200));
338 testcase(
"Implied Finish Time (with fix1571)");
340 Env env(*
this, features);
341 auto const baseFee = env.
current()->fees().base;
342 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
353 auto const seq = env.
seq(
"alice");
363 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5100));
375 Env env(*
this, features);
376 auto const baseFee = env.
current()->fees().base;
377 env.
fund(
XRP(5000),
"alice",
"bob",
"gw");
405 bool const withTokenEscrow =
406 env.
current()->rules().enabled(featureTokenEscrow);
410 auto const txResult =
468 auto const accountReserve =
drops(env.
current()->fees().reserve);
469 auto const accountIncrement =
472 env.
fund(accountReserve + accountIncrement +
XRP(50),
"daniel");
477 env.
fund(accountReserve + accountIncrement +
XRP(50),
"evan");
482 env.
fund(accountReserve,
"frank");
490 auto const seq = env.
seq(
"hannah");
502 auto const seq = env.
seq(
"ivan");
525 Env env(*
this, features);
526 auto const baseFee = env.
current()->fees().base;
527 env.
fund(
XRP(5000),
"alice",
"bob");
528 auto const seq = env.
seq(
"alice");
550 Env env(*
this, features);
551 auto const baseFee = env.
current()->fees().base;
552 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
553 auto const seq = env.
seq(
"alice");
577 Env env(*
this, features);
578 auto const baseFee = env.
current()->fees().base;
580 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
584 auto const seq = env.
seq(
"alice");
616 Env env(*
this, features);
617 auto const baseFee = env.
current()->fees().base;
619 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
625 auto const seq = env.
seq(
"alice");
644 Env env(*
this, features);
645 auto const baseFee = env.
current()->fees().base;
646 env.
fund(
XRP(5000),
"alice",
"bob");
647 auto const seq = env.
seq(
"alice");
688 Env env(*
this, features);
689 auto const baseFee = env.
current()->fees().base;
691 env.
fund(
XRP(5000),
"alice",
"bob");
692 auto const seq = env.
seq(
"alice");
727 Env env(*
this, features);
728 auto const baseFee = env.
current()->fees().base;
730 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
731 auto const seq = env.
seq(
"alice");
776 testcase(
"Escrow with CryptoConditions");
782 Env env(*
this, features);
783 auto const baseFee = env.
current()->fees().base;
784 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
785 auto const seq = env.
seq(
"alice");
786 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
790 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
794 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
799 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
807 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
813 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
819 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
828 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
834 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
840 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
850 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
853 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
857 Env env(*
this, features);
858 auto const baseFee = env.
current()->fees().base;
859 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
860 auto const seq = env.
seq(
"alice");
861 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
874 Env env(*
this, features);
875 auto const baseFee = env.
current()->fees().base;
876 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
878 auto const seq = env.
seq(
"alice");
882 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
885 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
893 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
897 Env env(*
this, features);
898 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
904 auto const p = v.
data();
905 auto const s = v.
size();
907 auto const ts = env.
now() + 1s;
940 auto const seq = env.
seq(
"alice");
941 auto const baseFee = env.
current()->fees().base;
955 Env env(*
this, features);
956 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
962 auto const cp = cv.
data();
963 auto const cs = cv.
size();
969 auto const fp = fv.
data();
970 auto const fs = fv.
size();
972 auto const ts = env.
now() + 1s;
1005 auto const seq = env.
seq(
"alice");
1006 auto const baseFee = env.
current()->fees().base;
1096 fee(150 * baseFee));
1102 Env env(*
this, features);
1103 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
1110 auto const seq = env.
seq(
"alice");
1111 auto const baseFee = env.
current()->fees().base;
1145 fee(150 * baseFee));
1151 Env env(*
this, features);
1152 env.
fund(
XRP(5000),
"alice",
"bob");
1155 {0xA2, 0x2B, 0x80, 0x20, 0x42, 0x4A, 0x70, 0x49, 0x49,
1156 0x52, 0x92, 0x67, 0xB6, 0x21, 0xB3, 0xD7, 0x91, 0x19,
1157 0xD7, 0x29, 0xB2, 0x38, 0x2C, 0xED, 0x8B, 0x29, 0x6C,
1158 0x3C, 0x02, 0x8F, 0xA9, 0x7D, 0x35, 0x0F, 0x6D, 0x07,
1159 0x81, 0x03, 0x06, 0x34, 0xD2, 0x82, 0x02, 0x03, 0xC8}};
1173 using namespace jtx;
1176 auto const alice =
Account(
"alice");
1177 auto const bruce =
Account(
"bruce");
1178 auto const carol =
Account(
"carol");
1183 Env env(*
this, features);
1184 env.
fund(
XRP(5000), alice, bruce, carol);
1185 auto const aseq = env.
seq(alice);
1186 auto const bseq = env.
seq(bruce);
1192 (*env.
meta())[sfTransactionResult] ==
1209 (*env.
meta())[sfTransactionResult] ==
1227 (*env.
meta())[sfTransactionResult] ==
1246 (*env.
meta())[sfTransactionResult] ==
1258 Env env(*
this, features);
1259 env.
fund(
XRP(5000), alice, bruce, carol);
1260 auto const aseq = env.
seq(alice);
1261 auto const bseq = env.
seq(bruce);
1266 (*env.
meta())[sfTransactionResult] ==
1273 (*env.
meta())[sfTransactionResult] ==
1353 using namespace jtx;
1355 Env env(*
this, features);
1356 auto const baseFee = env.
current()->fees().base;
1363 auto const jtx = env.
jt(
1375 BEAST_EXPECT(!pf.consequences.isBlocker());
1376 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1377 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(1000));
1390 BEAST_EXPECT(!pf.consequences.isBlocker());
1391 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1392 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1405 BEAST_EXPECT(!pf.consequences.isBlocker());
1406 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1407 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1416 using namespace jtx;
1423 Env env(*
this, features);
1424 auto const baseFee = env.
current()->fees().base;
1425 env.
fund(
XRP(5000), alice, bob);
1448 auto const ts = env.
now() + 97s;
1454 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1460 for (; env.
now() < ts; env.
close())
1466 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1480 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1484 Env env(*
this, features);
1485 auto const baseFee = env.
current()->fees().base;
1486 env.
fund(
XRP(5000), alice, bob);
1508 auto const ts = env.
now() + 117s;
1515 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1521 for (; env.
now() < ts; env.
close())
1527 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1537 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1544 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1556 using namespace jtx;
1562 Account const dillon{
"dillon "};
1565 char const credType[] =
"abcde";
1569 Env env(*
this, features - featureCredentials);
1570 env.
fund(
XRP(5000), alice, bob);
1573 auto const seq = env.
seq(alice);
1584 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1592 Env env(*
this, features);
1594 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1601 std::string const credIdx = jv[jss::result][jss::index].asString();
1603 auto const seq = env.
seq(alice);
1642 testcase(
"Escrow with credentials without depositPreauth");
1645 Env env(*
this, features);
1647 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1656 std::string const credIdx = jv[jss::result][jss::index].asString();
1658 auto const seq = env.
seq(alice);
1674 char const credType2[] =
"fghijk";
1680 auto const credIdxBob =
1682 env, bob, zelda, credType2)[jss::result][jss::index]
1685 auto const seq = env.
seq(alice);
1725 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 testWithFeats(FeatureBitset features)
void test1571(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.