2#include <test/jtx/Env.h>
3#include <test/jtx/amount.h>
4#include <test/jtx/balance.h>
5#include <test/jtx/credentials.h>
6#include <test/jtx/deposit.h>
7#include <test/jtx/escrow.h>
8#include <test/jtx/fee.h>
9#include <test/jtx/flags.h>
10#include <test/jtx/seq.h>
11#include <test/jtx/tag.h>
12#include <test/jtx/ter.h>
13#include <test/jtx/ticket.h>
14#include <test/jtx/txflags.h>
16#include <xrpl/basics/Slice.h>
17#include <xrpl/beast/unit_test/suite.h>
18#include <xrpl/ledger/ApplyView.h>
19#include <xrpl/ledger/Dir.h>
20#include <xrpl/protocol/Feature.h>
21#include <xrpl/protocol/Indexes.h>
22#include <xrpl/protocol/SField.h>
23#include <xrpl/protocol/TER.h>
24#include <xrpl/protocol/TxFlags.h>
25#include <xrpl/protocol/jss.h>
26#include <xrpl/tx/applySteps.h>
47 Env env(*
this, features);
48 auto const baseFee = env.
current()->fees().base;
49 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");
105 Env env(*
this, features);
106 auto const baseFee = env.
current()->fees().base;
107 env.
fund(
XRP(5000),
"alice",
"bob");
111 auto const ts = env.
now() + 117s;
113 auto const seq = env.
seq(
"alice");
135 testcase(
"Timing: Finish and Cancel -> Finish");
136 Env env(*
this, features);
137 auto const baseFee = env.
current()->fees().base;
138 env.
fund(
XRP(5000),
"alice",
"bob");
142 auto const fts = env.
now() + 117s;
143 auto const cts = env.
now() + 192s;
145 auto const seq = env.
seq(
"alice");
152 for (; env.
now() < fts; env.
close())
166 testcase(
"Timing: Finish and Cancel -> Cancel");
167 Env env(*
this, features);
168 auto const baseFee = env.
current()->fees().base;
169 env.
fund(
XRP(5000),
"alice",
"bob");
173 auto const fts = env.
now() + 109s;
174 auto const cts = env.
now() + 184s;
176 auto const seq = env.
seq(
"alice");
183 for (; env.
now() < fts; env.
close())
191 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);
220 env(
fset(bob, asfRequireDest));
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");
261 env(
fset(
"george", asfDisallowXRP));
272 testcase(
"RequiresConditionOrFinishAfter");
274 Env env(*
this, features);
275 auto const baseFee = env.
current()->fees().base;
276 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
287 auto const seq = env.
seq(
"alice");
297 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5100));
301 auto const seqFt = env.
seq(
"alice");
309 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5200));
320 Env env(*
this, features);
321 auto const baseFee = env.
current()->fees().base;
322 env.
fund(
XRP(5000),
"alice",
"bob",
"gw");
350 bool const withTokenEscrow = env.
current()->rules().enabled(featureTokenEscrow);
396 env(
fset(
"carol", asfRequireDest));
411 auto const accountReserve =
drops(env.
current()->fees().reserve);
412 auto const accountIncrement =
drops(env.
current()->fees().increment);
414 env.
fund(accountReserve + accountIncrement +
XRP(50),
"daniel");
419 env.
fund(accountReserve + accountIncrement +
XRP(50),
"evan");
424 env.
fund(accountReserve,
"frank");
432 auto const seq = env.
seq(
"hannah");
442 auto const seq = env.
seq(
"ivan");
464 Env env(*
this, features);
465 auto const baseFee = env.
current()->fees().base;
466 env.
fund(
XRP(5000),
"alice",
"bob");
467 auto const seq = env.
seq(
"alice");
488 Env env(*
this, features);
489 auto const baseFee = env.
current()->fees().base;
490 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
491 auto const seq = env.
seq(
"alice");
514 Env env(*
this, features);
515 auto const baseFee = env.
current()->fees().base;
517 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
518 env(
fset(
"bob", asfDepositAuth));
521 auto const seq = env.
seq(
"alice");
552 Env env(*
this, features);
553 auto const baseFee = env.
current()->fees().base;
555 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
556 env(
fset(
"bob", asfDepositAuth));
561 auto const seq = env.
seq(
"alice");
579 Env env(*
this, features);
580 auto const baseFee = env.
current()->fees().base;
581 env.
fund(
XRP(5000),
"alice",
"bob");
582 auto const seq = env.
seq(
"alice");
621 Env env(*
this, features);
622 auto const baseFee = env.
current()->fees().base;
624 env.
fund(
XRP(5000),
"alice",
"bob");
625 auto const seq = env.
seq(
"alice");
638 env(
fset(
"alice", asfDepositAuth));
658 Env env(*
this, features);
659 auto const baseFee = env.
current()->fees().base;
661 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
662 auto const seq = env.
seq(
"alice");
681 env(
fset(
"alice", asfDepositAuth));
704 testcase(
"Escrow with CryptoConditions");
710 Env env(*
this, features);
711 auto const baseFee = env.
current()->fees().base;
712 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
713 auto const seq = env.
seq(
"alice");
714 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
718 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
722 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
726 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
734 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
740 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
746 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);
777 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
780 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
784 Env env(*
this, features);
785 auto const baseFee = env.
current()->fees().base;
786 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
787 auto const seq = env.
seq(
"alice");
788 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
801 Env env(*
this, features);
802 auto const baseFee = env.
current()->fees().base;
803 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
805 auto const seq = env.
seq(
"alice");
809 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
812 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
820 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
824 Env env(*
this, features);
825 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
831 auto const p = v.
data();
832 auto const s = v.
size();
834 auto const ts = env.
now() + 1s;
867 auto const seq = env.
seq(
"alice");
868 auto const baseFee = env.
current()->fees().base;
882 Env env(*
this, features);
883 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
889 auto const cp = cv.
data();
890 auto const cs = cv.
size();
896 auto const fp = fv.
data();
897 auto const fs = fv.
size();
899 auto const ts = env.
now() + 1s;
932 auto const seq = env.
seq(
"alice");
933 auto const baseFee = env.
current()->fees().base;
1023 Fee(150 * baseFee));
1029 Env env(*
this, features);
1030 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
1037 auto const seq = env.
seq(
"alice");
1038 auto const baseFee = env.
current()->fees().base;
1072 Fee(150 * baseFee));
1078 Env env(*
this, features);
1079 env.
fund(
XRP(5000),
"alice",
"bob");
1082 {0xA2, 0x2B, 0x80, 0x20, 0x42, 0x4A, 0x70, 0x49, 0x49, 0x52, 0x92, 0x67,
1083 0xB6, 0x21, 0xB3, 0xD7, 0x91, 0x19, 0xD7, 0x29, 0xB2, 0x38, 0x2C, 0xED,
1084 0x8B, 0x29, 0x6C, 0x3C, 0x02, 0x8F, 0xA9, 0x7D, 0x35, 0x0F, 0x6D, 0x07,
1085 0x81, 0x03, 0x06, 0x34, 0xD2, 0x82, 0x02, 0x03, 0xC8}};
1099 using namespace jtx;
1102 auto const alice =
Account(
"alice");
1103 auto const bruce =
Account(
"bruce");
1104 auto const carol =
Account(
"carol");
1109 Env env(*
this, features);
1110 env.
fund(
XRP(5000), alice, bruce, carol);
1111 auto const aseq = env.
seq(alice);
1112 auto const bseq = env.
seq(bruce);
1185 Env env(*
this, features);
1186 env.
fund(
XRP(5000), alice, bruce, carol);
1187 auto const aseq = env.
seq(alice);
1188 auto const bseq = env.
seq(bruce);
1287 using namespace jtx;
1289 Env env(*
this, features);
1290 auto const baseFee = env.
current()->fees().base;
1297 auto const jtx = env.
jt(
1305 BEAST_EXPECT(!pf.consequences.isBlocker());
1306 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1307 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(1000));
1315 BEAST_EXPECT(!pf.consequences.isBlocker());
1316 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1317 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1325 BEAST_EXPECT(!pf.consequences.isBlocker());
1326 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1327 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1336 using namespace jtx;
1343 Env env(*
this, features);
1344 auto const baseFee = env.
current()->fees().base;
1345 env.
fund(
XRP(5000), alice, bob);
1368 auto const ts = env.
now() + 97s;
1374 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1380 for (; env.
now() < ts; env.
close())
1386 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1400 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1404 Env env(*
this, features);
1405 auto const baseFee = env.
current()->fees().base;
1406 env.
fund(
XRP(5000), alice, bob);
1428 auto const ts = env.
now() + 117s;
1435 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1441 for (; env.
now() < ts; env.
close())
1447 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1457 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1464 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1476 using namespace jtx;
1482 Account const dillon{
"dillon "};
1485 char const credType[] =
"abcde";
1489 Env env(*
this, features - featureCredentials);
1490 env.
fund(
XRP(5000), alice, bob);
1493 auto const seq = env.
seq(alice);
1497 env(
fset(bob, asfDepositAuth));
1503 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1509 Env env(*
this, features);
1511 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1517 std::string const credIdx = jv[jss::result][jss::index].asString();
1519 auto const seq = env.
seq(alice);
1524 env(
fset(bob, asfDepositAuth));
1557 testcase(
"Escrow with credentials without depositPreauth");
1560 Env env(*
this, features);
1562 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1570 std::string const credIdx = jv[jss::result][jss::index].asString();
1572 auto const seq = env.
seq(alice);
1587 char const credType2[] =
"random";
1593 auto const credIdxBob =
1597 auto const seq = env.
seq(alice);
1602 env(
fset(bob, asfDepositAuth));
1639 testTags(all - fixIncludeKeyletFields);
TestcaseT testcase
Memberspace for declaring test cases.
std::string asString() const
Returns the unquoted string value.
A class that simplifies iterating ledger directory pages.
ConstIterator begin() const
ConstIterator end() const
An immutable linear range of bytes.
Immutable cryptographic account descriptor.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
SLE::const_pointer le(Account const &account) const
Return an account root.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
JTx jt(JsonValue &&jv, FN const &... fN)
Create a JTx from parameters.
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
void memoize(Account const &account)
Associate AccountID with account.
beast::Journal const journal
void require(Args const &... args)
Check a set of requirements.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
NetClock::time_point now()
Returns the current network time.
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 accept(jtx::Account const &subject, jtx::Account const &issuer, std::string_view credType)
json::Value create(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 authCredentials(jtx::Account const &account, std::vector< AuthorizeCredentials > const &auth)
json::Value auth(Account const &account, Account const &auth)
Preauthorize for deposit.
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)
auto const kCancelTime
Set the "CancelAfter" time tag on a JTx.
auto const kFinishTime
Set the "FinishAfter" time tag on a JTx.
std::array< std::uint8_t, 8 > const kFb3
std::array< std::uint8_t, 7 > const kFb2
std::array< std::uint8_t, 39 > const kCb2
json::Value finish(AccountID const &account, AccountID const &from, std::uint32_t seq)
std::array< std::uint8_t, 4 > const kFb1
std::array< std::uint8_t, 39 > const kCb1
std::array< std::uint8_t, 39 > const kCb3
json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
XrpT const XRP
Converts to XRP Issue or STAmount.
FeatureBitset testableAmendments()
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
OwnerCount< ltTICKET > tickets
Match the number of tickets on the account.
json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
PreflightResult preflight(ServiceRegistry ®istry, Rules const &rules, STTx const &tx, ApplyFlags flags, beast::Journal j)
Gate a transaction based on static information.
bool isTesSuccess(TER x) noexcept
@ tecCRYPTOCONDITION_ERROR
@ tecINSUFFICIENT_RESERVE
void testEscrowConditions(FeatureBitset features)
void testEnablement(FeatureBitset features)
void testFails(FeatureBitset features)
void testTags(FeatureBitset features)
void testMetaAndOwnership(FeatureBitset features)
void testWithFeats(FeatureBitset features)
void run() override
Runs the suite.
void testConsequences(FeatureBitset features)
void testEscrowWithTickets(FeatureBitset features)
void testDisallowXRP(FeatureBitset features)
void testCredentials(FeatureBitset features)
void testTiming(FeatureBitset features)
void testRequiresConditionOrFinishAfter(FeatureBitset features)
void testLockup(FeatureBitset features)
Set the destination tag on a JTx.
Set the sequence number on a JTx.
Set the source tag on a JTx.