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));
258 Env env(*
this, features);
260 env.
fund(
XRP(5000),
"bob",
"george");
273 testcase(
"RequiresConditionOrFinishAfter");
275 Env env(*
this, features);
276 auto const baseFee = env.
current()->fees().base;
277 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
288 auto const seq = env.
seq(
"alice");
298 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5100));
302 auto const seqFt = env.
seq(
"alice");
323 Env env(*
this, features);
324 auto const baseFee = env.
current()->fees().base;
325 env.
fund(
XRP(5000),
"alice",
"bob",
"gw");
353 bool const withTokenEscrow =
354 env.
current()->rules().enabled(featureTokenEscrow);
358 auto const txResult =
416 auto const accountReserve =
drops(env.
current()->fees().reserve);
417 auto const accountIncrement =
420 env.
fund(accountReserve + accountIncrement +
XRP(50),
"daniel");
425 env.
fund(accountReserve + accountIncrement +
XRP(50),
"evan");
430 env.
fund(accountReserve,
"frank");
438 auto const seq = env.
seq(
"hannah");
450 auto const seq = env.
seq(
"ivan");
473 Env env(*
this, features);
474 auto const baseFee = env.
current()->fees().base;
475 env.
fund(
XRP(5000),
"alice",
"bob");
476 auto const seq = env.
seq(
"alice");
498 Env env(*
this, features);
499 auto const baseFee = env.
current()->fees().base;
500 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
501 auto const seq = env.
seq(
"alice");
525 Env env(*
this, features);
526 auto const baseFee = env.
current()->fees().base;
528 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
532 auto const seq = env.
seq(
"alice");
564 Env env(*
this, features);
565 auto const baseFee = env.
current()->fees().base;
567 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
573 auto const seq = env.
seq(
"alice");
592 Env env(*
this, features);
593 auto const baseFee = env.
current()->fees().base;
594 env.
fund(
XRP(5000),
"alice",
"bob");
595 auto const seq = env.
seq(
"alice");
636 Env env(*
this, features);
637 auto const baseFee = env.
current()->fees().base;
639 env.
fund(
XRP(5000),
"alice",
"bob");
640 auto const seq = env.
seq(
"alice");
675 Env env(*
this, features);
676 auto const baseFee = env.
current()->fees().base;
678 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
679 auto const seq = env.
seq(
"alice");
724 testcase(
"Escrow with CryptoConditions");
730 Env env(*
this, features);
731 auto const baseFee = env.
current()->fees().base;
732 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
733 auto const seq = env.
seq(
"alice");
734 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
738 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
742 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
747 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
755 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
761 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
767 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
776 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
782 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
788 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
798 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
801 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
805 Env env(*
this, features);
806 auto const baseFee = env.
current()->fees().base;
807 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
808 auto const seq = env.
seq(
"alice");
809 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
822 Env env(*
this, features);
823 auto const baseFee = env.
current()->fees().base;
824 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
826 auto const seq = env.
seq(
"alice");
830 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
833 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
841 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
845 Env env(*
this, features);
846 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
852 auto const p = v.
data();
853 auto const s = v.
size();
855 auto const ts = env.
now() + 1s;
888 auto const seq = env.
seq(
"alice");
889 auto const baseFee = env.
current()->fees().base;
903 Env env(*
this, features);
904 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
910 auto const cp = cv.
data();
911 auto const cs = cv.
size();
917 auto const fp = fv.
data();
918 auto const fs = fv.
size();
920 auto const ts = env.
now() + 1s;
953 auto const seq = env.
seq(
"alice");
954 auto const baseFee = env.
current()->fees().base;
1044 fee(150 * baseFee));
1050 Env env(*
this, features);
1051 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
1058 auto const seq = env.
seq(
"alice");
1059 auto const baseFee = env.
current()->fees().base;
1093 fee(150 * baseFee));
1099 Env env(*
this, features);
1100 env.
fund(
XRP(5000),
"alice",
"bob");
1103 {0xA2, 0x2B, 0x80, 0x20, 0x42, 0x4A, 0x70, 0x49, 0x49,
1104 0x52, 0x92, 0x67, 0xB6, 0x21, 0xB3, 0xD7, 0x91, 0x19,
1105 0xD7, 0x29, 0xB2, 0x38, 0x2C, 0xED, 0x8B, 0x29, 0x6C,
1106 0x3C, 0x02, 0x8F, 0xA9, 0x7D, 0x35, 0x0F, 0x6D, 0x07,
1107 0x81, 0x03, 0x06, 0x34, 0xD2, 0x82, 0x02, 0x03, 0xC8}};
1121 using namespace jtx;
1124 auto const alice =
Account(
"alice");
1125 auto const bruce =
Account(
"bruce");
1126 auto const carol =
Account(
"carol");
1131 Env env(*
this, features);
1132 env.
fund(
XRP(5000), alice, bruce, carol);
1133 auto const aseq = env.
seq(alice);
1134 auto const bseq = env.
seq(bruce);
1140 (*env.
meta())[sfTransactionResult] ==
1157 (*env.
meta())[sfTransactionResult] ==
1175 (*env.
meta())[sfTransactionResult] ==
1194 (*env.
meta())[sfTransactionResult] ==
1206 Env env(*
this, features);
1207 env.
fund(
XRP(5000), alice, bruce, carol);
1208 auto const aseq = env.
seq(alice);
1209 auto const bseq = env.
seq(bruce);
1214 (*env.
meta())[sfTransactionResult] ==
1221 (*env.
meta())[sfTransactionResult] ==
1301 using namespace jtx;
1303 Env env(*
this, features);
1304 auto const baseFee = env.
current()->fees().base;
1311 auto const jtx = env.
jt(
1323 BEAST_EXPECT(!pf.consequences.isBlocker());
1324 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1325 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(1000));
1338 BEAST_EXPECT(!pf.consequences.isBlocker());
1339 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1340 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1353 BEAST_EXPECT(!pf.consequences.isBlocker());
1354 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1355 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1364 using namespace jtx;
1371 Env env(*
this, features);
1372 auto const baseFee = env.
current()->fees().base;
1373 env.
fund(
XRP(5000), alice, bob);
1396 auto const ts = env.
now() + 97s;
1402 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1408 for (; env.
now() < ts; env.
close())
1414 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1428 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1432 Env env(*
this, features);
1433 auto const baseFee = env.
current()->fees().base;
1434 env.
fund(
XRP(5000), alice, bob);
1456 auto const ts = env.
now() + 117s;
1463 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1469 for (; env.
now() < ts; env.
close())
1475 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1485 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1492 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1504 using namespace jtx;
1510 Account const dillon{
"dillon "};
1513 char const credType[] =
"abcde";
1517 Env env(*
this, features - featureCredentials);
1518 env.
fund(
XRP(5000), alice, bob);
1521 auto const seq = env.
seq(alice);
1532 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1540 Env env(*
this, features);
1542 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1549 std::string const credIdx = jv[jss::result][jss::index].asString();
1551 auto const seq = env.
seq(alice);
1590 testcase(
"Escrow with credentials without depositPreauth");
1593 Env env(*
this, features);
1595 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1604 std::string const credIdx = jv[jss::result][jss::index].asString();
1606 auto const seq = env.
seq(alice);
1622 char const credType2[] =
"fghijk";
1628 auto const credIdxBob =
1630 env, bob, zelda, credType2)[jss::result][jss::index]
1633 auto const seq = env.
seq(alice);
1673 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.