22#include <xrpld/app/tx/applySteps.h>
23#include <xrpld/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);
268 Env env(*
this, features - featureDepositAuth);
270 env.
fund(
XRP(5000),
"bob",
"george");
279 Env env(*
this, features);
281 env.
fund(
XRP(5000),
"bob",
"george");
295 testcase(
"Implied Finish Time (without fix1571)");
298 auto const baseFee = env.
current()->fees().base;
299 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
304 auto const seq1 = env.
seq(
"alice");
310 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5100));
316 auto const seq2 = env.
seq(
"alice");
326 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5200));
330 testcase(
"Implied Finish Time (with fix1571)");
332 Env env(*
this, features);
333 auto const baseFee = env.
current()->fees().base;
334 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
345 auto const seq = env.
seq(
"alice");
355 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5100));
367 Env env(*
this, features);
368 auto const baseFee = env.
current()->fees().base;
369 env.
fund(
XRP(5000),
"alice",
"bob",
"gw");
397 bool const withTokenEscrow =
398 env.
current()->rules().enabled(featureTokenEscrow);
402 auto const txResult =
460 auto const accountReserve =
drops(env.
current()->fees().reserve);
461 auto const accountIncrement =
464 env.
fund(accountReserve + accountIncrement +
XRP(50),
"daniel");
469 env.
fund(accountReserve + accountIncrement +
XRP(50),
"evan");
474 env.
fund(accountReserve,
"frank");
482 auto const seq = env.
seq(
"hannah");
494 auto const seq = env.
seq(
"ivan");
517 Env env(*
this, features);
518 auto const baseFee = env.
current()->fees().base;
519 env.
fund(
XRP(5000),
"alice",
"bob");
520 auto const seq = env.
seq(
"alice");
542 Env env(*
this, features);
543 auto const baseFee = env.
current()->fees().base;
544 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
545 auto const seq = env.
seq(
"alice");
569 Env env(*
this, features);
570 auto const baseFee = env.
current()->fees().base;
572 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
576 auto const seq = env.
seq(
"alice");
608 Env env(*
this, features);
609 auto const baseFee = env.
current()->fees().base;
611 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
617 auto const seq = env.
seq(
"alice");
636 Env env(*
this, features);
637 auto const baseFee = env.
current()->fees().base;
638 env.
fund(
XRP(5000),
"alice",
"bob");
639 auto const seq = env.
seq(
"alice");
680 Env env(*
this, features);
681 auto const baseFee = env.
current()->fees().base;
683 env.
fund(
XRP(5000),
"alice",
"bob");
684 auto const seq = env.
seq(
"alice");
719 Env env(*
this, features);
720 auto const baseFee = env.
current()->fees().base;
722 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
723 auto const seq = env.
seq(
"alice");
768 testcase(
"Escrow with CryptoConditions");
774 Env env(*
this, features);
775 auto const baseFee = env.
current()->fees().base;
776 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
777 auto const seq = env.
seq(
"alice");
778 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
782 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
786 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
791 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
799 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
805 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
811 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
820 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
826 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
832 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
842 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
845 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
849 Env env(*
this, features);
850 auto const baseFee = env.
current()->fees().base;
851 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
852 auto const seq = env.
seq(
"alice");
853 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
866 Env env(*
this, features);
867 auto const baseFee = env.
current()->fees().base;
868 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
870 auto const seq = env.
seq(
"alice");
874 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
877 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
885 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
889 Env env(*
this, features);
890 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
896 auto const p = v.
data();
897 auto const s = v.
size();
899 auto const ts = env.
now() + 1s;
932 auto const seq = env.
seq(
"alice");
933 auto const baseFee = env.
current()->fees().base;
947 Env env(*
this, features);
948 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
954 auto const cp = cv.
data();
955 auto const cs = cv.
size();
961 auto const fp = fv.
data();
962 auto const fs = fv.
size();
964 auto const ts = env.
now() + 1s;
997 auto const seq = env.
seq(
"alice");
998 auto const baseFee = env.
current()->fees().base;
1088 fee(150 * baseFee));
1094 Env env(*
this, features);
1095 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
1102 auto const seq = env.
seq(
"alice");
1103 auto const baseFee = env.
current()->fees().base;
1137 fee(150 * baseFee));
1143 Env env(*
this, features);
1144 env.
fund(
XRP(5000),
"alice",
"bob");
1147 {0xA2, 0x2B, 0x80, 0x20, 0x42, 0x4A, 0x70, 0x49, 0x49,
1148 0x52, 0x92, 0x67, 0xB6, 0x21, 0xB3, 0xD7, 0x91, 0x19,
1149 0xD7, 0x29, 0xB2, 0x38, 0x2C, 0xED, 0x8B, 0x29, 0x6C,
1150 0x3C, 0x02, 0x8F, 0xA9, 0x7D, 0x35, 0x0F, 0x6D, 0x07,
1151 0x81, 0x03, 0x06, 0x34, 0xD2, 0x82, 0x02, 0x03, 0xC8}};
1165 using namespace jtx;
1168 auto const alice =
Account(
"alice");
1169 auto const bruce =
Account(
"bruce");
1170 auto const carol =
Account(
"carol");
1175 Env env(*
this, features);
1176 env.
fund(
XRP(5000), alice, bruce, carol);
1177 auto const aseq = env.
seq(alice);
1178 auto const bseq = env.
seq(bruce);
1184 (*env.
meta())[sfTransactionResult] ==
1201 (*env.
meta())[sfTransactionResult] ==
1219 (*env.
meta())[sfTransactionResult] ==
1238 (*env.
meta())[sfTransactionResult] ==
1250 Env env(*
this, features);
1251 env.
fund(
XRP(5000), alice, bruce, carol);
1252 auto const aseq = env.
seq(alice);
1253 auto const bseq = env.
seq(bruce);
1258 (*env.
meta())[sfTransactionResult] ==
1265 (*env.
meta())[sfTransactionResult] ==
1345 using namespace jtx;
1347 Env env(*
this, features);
1348 auto const baseFee = env.
current()->fees().base;
1355 auto const jtx = env.
jt(
1367 BEAST_EXPECT(!pf.consequences.isBlocker());
1368 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1369 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(1000));
1382 BEAST_EXPECT(!pf.consequences.isBlocker());
1383 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1384 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1397 BEAST_EXPECT(!pf.consequences.isBlocker());
1398 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1399 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1408 using namespace jtx;
1415 Env env(*
this, features);
1416 auto const baseFee = env.
current()->fees().base;
1417 env.
fund(
XRP(5000), alice, bob);
1440 auto const ts = env.
now() + 97s;
1446 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1452 for (; env.
now() < ts; env.
close())
1458 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1472 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1476 Env env(*
this, features);
1477 auto const baseFee = env.
current()->fees().base;
1478 env.
fund(
XRP(5000), alice, bob);
1500 auto const ts = env.
now() + 117s;
1507 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1513 for (; env.
now() < ts; env.
close())
1519 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1529 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1536 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1548 using namespace jtx;
1554 Account const dillon{
"dillon "};
1557 char const credType[] =
"abcde";
1561 Env env(*
this, features - featureCredentials);
1562 env.
fund(
XRP(5000), alice, bob);
1565 auto const seq = env.
seq(alice);
1576 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1584 Env env(*
this, features);
1586 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1593 std::string const credIdx = jv[jss::result][jss::index].asString();
1595 auto const seq = env.
seq(alice);
1634 testcase(
"Escrow with credentials without depositPreauth");
1637 Env env(*
this, features);
1639 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1648 std::string const credIdx = jv[jss::result][jss::index].asString();
1650 auto const seq = env.
seq(alice);
1666 char const credType2[] =
"fghijk";
1672 auto const credIdxBob =
1674 env, bob, zelda, credType2)[jss::result][jss::index]
1677 auto const seq = env.
seq(alice);
1717 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)
Json::Value cancel(AccountID const &account, Account const &from, std::uint32_t seq)
std::array< std::uint8_t, 39 > const cb2
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.
owner_count< ltTICKET > tickets
Match the number of tickets on the account.
XRP_t const XRP
Converts to XRP Issue or STAmount.
FeatureBitset supported_amendments()
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 "CancelAfter" time tag on a JTx.
Set the "FinishAfter" time tag on a JTx.
Set the sequence number on a JTx.
Set the source tag on a JTx.