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");
302 testcase(
"RequiresConditionOrFinishAfter");
304 Env env(*
this, features);
305 auto const baseFee = env.
current()->fees().base;
306 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
317 auto const seq = env.
seq(
"alice");
327 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5100));
331 auto const seqFt = env.
seq(
"alice");
352 Env env(*
this, features);
353 auto const baseFee = env.
current()->fees().base;
354 env.
fund(
XRP(5000),
"alice",
"bob",
"gw");
382 bool const withTokenEscrow =
383 env.
current()->rules().enabled(featureTokenEscrow);
387 auto const txResult =
445 auto const accountReserve =
drops(env.
current()->fees().reserve);
446 auto const accountIncrement =
449 env.
fund(accountReserve + accountIncrement +
XRP(50),
"daniel");
454 env.
fund(accountReserve + accountIncrement +
XRP(50),
"evan");
459 env.
fund(accountReserve,
"frank");
467 auto const seq = env.
seq(
"hannah");
479 auto const seq = env.
seq(
"ivan");
502 Env env(*
this, features);
503 auto const baseFee = env.
current()->fees().base;
504 env.
fund(
XRP(5000),
"alice",
"bob");
505 auto const seq = env.
seq(
"alice");
527 Env env(*
this, features);
528 auto const baseFee = env.
current()->fees().base;
529 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
530 auto const seq = env.
seq(
"alice");
554 Env env(*
this, features);
555 auto const baseFee = env.
current()->fees().base;
557 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
561 auto const seq = env.
seq(
"alice");
593 Env env(*
this, features);
594 auto const baseFee = env.
current()->fees().base;
596 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
602 auto const seq = env.
seq(
"alice");
621 Env env(*
this, features);
622 auto const baseFee = env.
current()->fees().base;
623 env.
fund(
XRP(5000),
"alice",
"bob");
624 auto const seq = env.
seq(
"alice");
665 Env env(*
this, features);
666 auto const baseFee = env.
current()->fees().base;
668 env.
fund(
XRP(5000),
"alice",
"bob");
669 auto const seq = env.
seq(
"alice");
704 Env env(*
this, features);
705 auto const baseFee = env.
current()->fees().base;
707 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
708 auto const seq = env.
seq(
"alice");
753 testcase(
"Escrow with CryptoConditions");
759 Env env(*
this, features);
760 auto const baseFee = env.
current()->fees().base;
761 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
762 auto const seq = env.
seq(
"alice");
763 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
767 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
771 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
776 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
784 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
790 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
796 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
805 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
811 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
817 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
827 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
830 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
834 Env env(*
this, features);
835 auto const baseFee = env.
current()->fees().base;
836 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
837 auto const seq = env.
seq(
"alice");
838 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
851 Env env(*
this, features);
852 auto const baseFee = env.
current()->fees().base;
853 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
855 auto const seq = env.
seq(
"alice");
859 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
862 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
870 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
874 Env env(*
this, features);
875 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
881 auto const p = v.
data();
882 auto const s = v.
size();
884 auto const ts = env.
now() + 1s;
917 auto const seq = env.
seq(
"alice");
918 auto const baseFee = env.
current()->fees().base;
932 Env env(*
this, features);
933 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
939 auto const cp = cv.
data();
940 auto const cs = cv.
size();
946 auto const fp = fv.
data();
947 auto const fs = fv.
size();
949 auto const ts = env.
now() + 1s;
982 auto const seq = env.
seq(
"alice");
983 auto const baseFee = env.
current()->fees().base;
1073 fee(150 * baseFee));
1079 Env env(*
this, features);
1080 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
1087 auto const seq = env.
seq(
"alice");
1088 auto const baseFee = env.
current()->fees().base;
1122 fee(150 * baseFee));
1128 Env env(*
this, features);
1129 env.
fund(
XRP(5000),
"alice",
"bob");
1132 {0xA2, 0x2B, 0x80, 0x20, 0x42, 0x4A, 0x70, 0x49, 0x49,
1133 0x52, 0x92, 0x67, 0xB6, 0x21, 0xB3, 0xD7, 0x91, 0x19,
1134 0xD7, 0x29, 0xB2, 0x38, 0x2C, 0xED, 0x8B, 0x29, 0x6C,
1135 0x3C, 0x02, 0x8F, 0xA9, 0x7D, 0x35, 0x0F, 0x6D, 0x07,
1136 0x81, 0x03, 0x06, 0x34, 0xD2, 0x82, 0x02, 0x03, 0xC8}};
1150 using namespace jtx;
1153 auto const alice =
Account(
"alice");
1154 auto const bruce =
Account(
"bruce");
1155 auto const carol =
Account(
"carol");
1160 Env env(*
this, features);
1161 env.
fund(
XRP(5000), alice, bruce, carol);
1162 auto const aseq = env.
seq(alice);
1163 auto const bseq = env.
seq(bruce);
1169 (*env.
meta())[sfTransactionResult] ==
1186 (*env.
meta())[sfTransactionResult] ==
1204 (*env.
meta())[sfTransactionResult] ==
1223 (*env.
meta())[sfTransactionResult] ==
1235 Env env(*
this, features);
1236 env.
fund(
XRP(5000), alice, bruce, carol);
1237 auto const aseq = env.
seq(alice);
1238 auto const bseq = env.
seq(bruce);
1243 (*env.
meta())[sfTransactionResult] ==
1250 (*env.
meta())[sfTransactionResult] ==
1330 using namespace jtx;
1332 Env env(*
this, features);
1333 auto const baseFee = env.
current()->fees().base;
1340 auto const jtx = env.
jt(
1352 BEAST_EXPECT(!pf.consequences.isBlocker());
1353 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1354 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(1000));
1367 BEAST_EXPECT(!pf.consequences.isBlocker());
1368 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1369 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1382 BEAST_EXPECT(!pf.consequences.isBlocker());
1383 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1384 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1393 using namespace jtx;
1400 Env env(*
this, features);
1401 auto const baseFee = env.
current()->fees().base;
1402 env.
fund(
XRP(5000), alice, bob);
1425 auto const ts = env.
now() + 97s;
1431 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1437 for (; env.
now() < ts; env.
close())
1443 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1457 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1461 Env env(*
this, features);
1462 auto const baseFee = env.
current()->fees().base;
1463 env.
fund(
XRP(5000), alice, bob);
1485 auto const ts = env.
now() + 117s;
1492 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1498 for (; env.
now() < ts; env.
close())
1504 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1514 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1521 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1533 using namespace jtx;
1539 Account const dillon{
"dillon "};
1542 char const credType[] =
"abcde";
1546 Env env(*
this, features - featureCredentials);
1547 env.
fund(
XRP(5000), alice, bob);
1550 auto const seq = env.
seq(alice);
1561 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1569 Env env(*
this, features);
1571 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1578 std::string const credIdx = jv[jss::result][jss::index].asString();
1580 auto const seq = env.
seq(alice);
1619 testcase(
"Escrow with credentials without depositPreauth");
1622 Env env(*
this, features);
1624 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1633 std::string const credIdx = jv[jss::result][jss::index].asString();
1635 auto const seq = env.
seq(alice);
1651 char const credType2[] =
"fghijk";
1657 auto const credIdxBob =
1659 env, bob, zelda, credType2)[jss::result][jss::index]
1662 auto const seq = env.
seq(alice);
1702 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.