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/SeqProxy.h>
24#include <xrpl/protocol/TER.h>
25#include <xrpl/protocol/TxFlags.h>
26#include <xrpl/protocol/jss.h>
27#include <xrpl/tx/applySteps.h>
48 Env env(*
this, features);
49 auto const baseFee = env.
current()->fees().base;
50 env.
fund(
XRP(5000),
"alice",
"bob");
54 auto const seq1 = env.
seq(
"alice");
66 auto const seq2 = env.
seq(
"alice");
85 Env env(*
this, features);
86 auto const baseFee = env.
current()->fees().base;
87 env.
fund(
XRP(5000),
"alice",
"bob");
91 auto const ts = env.
now() + 97s;
93 auto const seq = env.
seq(
"alice");
106 Env env(*
this, features);
107 auto const baseFee = env.
current()->fees().base;
108 env.
fund(
XRP(5000),
"alice",
"bob");
112 auto const ts = env.
now() + 117s;
114 auto const seq = env.
seq(
"alice");
136 testcase(
"Timing: Finish and Cancel -> Finish");
137 Env env(*
this, features);
138 auto const baseFee = env.
current()->fees().base;
139 env.
fund(
XRP(5000),
"alice",
"bob");
143 auto const fts = env.
now() + 117s;
144 auto const cts = env.
now() + 192s;
146 auto const seq = env.
seq(
"alice");
153 for (; env.
now() < fts; env.
close())
167 testcase(
"Timing: Finish and Cancel -> Cancel");
168 Env env(*
this, features);
169 auto const baseFee = env.
current()->fees().base;
170 env.
fund(
XRP(5000),
"alice",
"bob");
174 auto const fts = env.
now() + 109s;
175 auto const cts = env.
now() + 184s;
177 auto const seq = env.
seq(
"alice");
184 for (; env.
now() < fts; env.
close())
192 for (; env.
now() < cts; env.
close())
212 Env env(*
this, features);
214 auto const alice =
Account(
"alice");
215 auto const bob =
Account(
"bob");
217 env.
fund(
XRP(5000), alice, bob);
221 env(
fset(bob, asfRequireDest));
227 auto const seq = env.
seq(alice);
236 BEAST_EXPECT((*sle)[sfSourceTag] == 1);
237 BEAST_EXPECT((*sle)[sfDestinationTag] == 2);
238 if (features[fixIncludeKeyletFields])
240 BEAST_EXPECT((*sle)[sfSequence] == seq);
244 BEAST_EXPECT(!sle->isFieldPresent(sfSequence));
259 Env env(*
this, features);
261 env.
fund(
XRP(5000),
"bob",
"george");
262 env(
fset(
"george", asfDisallowXRP));
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");
310 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5200));
321 Env env(*
this, features);
322 auto const baseFee = env.
current()->fees().base;
323 env.
fund(
XRP(5000),
"alice",
"bob",
"gw");
351 bool const withTokenEscrow = env.
current()->rules().enabled(featureTokenEscrow);
397 env(
fset(
"carol", asfRequireDest));
413 auto const accountIncrement =
drops(env.
current()->fees().increment);
433 auto const seq = env.
seq(
"hannah");
443 auto const seq = env.
seq(
"ivan");
465 Env env(*
this, features);
466 auto const baseFee = env.
current()->fees().base;
467 env.
fund(
XRP(5000),
"alice",
"bob");
468 auto const seq = env.
seq(
"alice");
489 Env env(*
this, features);
490 auto const baseFee = env.
current()->fees().base;
491 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
492 auto const seq = env.
seq(
"alice");
515 Env env(*
this, features);
516 auto const baseFee = env.
current()->fees().base;
518 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
519 env(
fset(
"bob", asfDepositAuth));
522 auto const seq = env.
seq(
"alice");
553 Env env(*
this, features);
554 auto const baseFee = env.
current()->fees().base;
556 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
557 env(
fset(
"bob", asfDepositAuth));
562 auto const seq = env.
seq(
"alice");
580 Env env(*
this, features);
581 auto const baseFee = env.
current()->fees().base;
582 env.
fund(
XRP(5000),
"alice",
"bob");
583 auto const seq = env.
seq(
"alice");
622 Env env(*
this, features);
623 auto const baseFee = env.
current()->fees().base;
625 env.
fund(
XRP(5000),
"alice",
"bob");
626 auto const seq = env.
seq(
"alice");
639 env(
fset(
"alice", asfDepositAuth));
659 Env env(*
this, features);
660 auto const baseFee = env.
current()->fees().base;
662 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
663 auto const seq = env.
seq(
"alice");
682 env(
fset(
"alice", asfDepositAuth));
705 testcase(
"Escrow with CryptoConditions");
711 Env env(*
this, features);
712 auto const baseFee = env.
current()->fees().base;
713 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
714 auto const seq = env.
seq(
"alice");
715 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
719 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
723 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
727 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
735 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
741 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
747 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
756 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
762 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
768 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
779 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
782 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
786 Env env(*
this, features);
787 auto const baseFee = env.
current()->fees().base;
788 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
789 auto const seq = env.
seq(
"alice");
790 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
804 Env env(*
this, features);
805 auto const baseFee = env.
current()->fees().base;
806 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
808 auto const seq = env.
seq(
"alice");
812 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
815 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
823 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
827 Env env(*
this, features);
828 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
834 auto const p = v.
data();
835 auto const s = v.
size();
837 auto const ts = env.
now() + 1s;
870 auto const seq = env.
seq(
"alice");
871 auto const baseFee = env.
current()->fees().base;
885 Env env(*
this, features);
886 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
892 auto const cp = cv.
data();
893 auto const cs = cv.
size();
899 auto const fp = fv.
data();
900 auto const fs = fv.
size();
902 auto const ts = env.
now() + 1s;
935 auto const seq = env.
seq(
"alice");
936 auto const baseFee = env.
current()->fees().base;
1026 Fee(150 * baseFee));
1032 Env env(*
this, features);
1033 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
1040 auto const seq = env.
seq(
"alice");
1041 auto const baseFee = env.
current()->fees().base;
1075 Fee(150 * baseFee));
1081 Env env(*
this, features);
1082 env.
fund(
XRP(5000),
"alice",
"bob");
1085 {0xA2, 0x2B, 0x80, 0x20, 0x42, 0x4A, 0x70, 0x49, 0x49, 0x52, 0x92, 0x67,
1086 0xB6, 0x21, 0xB3, 0xD7, 0x91, 0x19, 0xD7, 0x29, 0xB2, 0x38, 0x2C, 0xED,
1087 0x8B, 0x29, 0x6C, 0x3C, 0x02, 0x8F, 0xA9, 0x7D, 0x35, 0x0F, 0x6D, 0x07,
1088 0x81, 0x03, 0x06, 0x34, 0xD2, 0x82, 0x02, 0x03, 0xC8}};
1102 using namespace jtx;
1105 auto const alice =
Account(
"alice");
1106 auto const bruce =
Account(
"bruce");
1107 auto const carol =
Account(
"carol");
1112 Env env(*
this, features);
1113 env.
fund(
XRP(5000), alice, bruce, carol);
1114 auto const aseq = env.
seq(alice);
1115 auto const bseq = env.
seq(bruce);
1188 Env env(*
this, features);
1189 env.
fund(
XRP(5000), alice, bruce, carol);
1190 auto const aseq = env.
seq(alice);
1191 auto const bseq = env.
seq(bruce);
1290 using namespace jtx;
1292 Env env(*
this, features);
1293 auto const baseFee = env.
current()->fees().base;
1300 auto const jtx = env.
jt(
1308 BEAST_EXPECT(!pf.consequences.isBlocker());
1309 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1310 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(1000));
1318 BEAST_EXPECT(!pf.consequences.isBlocker());
1319 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1320 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1328 BEAST_EXPECT(!pf.consequences.isBlocker());
1329 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1330 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1339 using namespace jtx;
1346 Env env(*
this, features);
1347 auto const baseFee = env.
current()->fees().base;
1348 env.
fund(
XRP(5000), alice, bob);
1371 auto const ts = env.
now() + 97s;
1377 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1383 for (; env.
now() < ts; env.
close())
1389 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1403 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1407 Env env(*
this, features);
1408 auto const baseFee = env.
current()->fees().base;
1409 env.
fund(
XRP(5000), alice, bob);
1431 auto const ts = env.
now() + 117s;
1438 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1444 for (; env.
now() < ts; env.
close())
1450 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1460 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1467 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1479 using namespace jtx;
1485 Account const dillon{
"dillon "};
1488 char const credType[] =
"abcde";
1492 Env env(*
this, features - featureCredentials);
1493 env.
fund(
XRP(5000), alice, bob);
1496 auto const seq = env.
seq(alice);
1500 env(
fset(bob, asfDepositAuth));
1506 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1512 Env env(*
this, features);
1514 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1520 std::string const credIdx = jv[jss::result][jss::index].asString();
1522 auto const seq = env.
seq(alice);
1527 env(
fset(bob, asfDepositAuth));
1560 testcase(
"Escrow with credentials without depositPreauth");
1563 Env env(*
this, features);
1565 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1573 std::string const credIdx = jv[jss::result][jss::index].asString();
1575 auto const seq = env.
seq(alice);
1590 char const credType2[] =
"random";
1596 auto const credIdxBob =
1600 auto const seq = env.
seq(alice);
1605 env(
fset(bob, asfDepositAuth));
1642 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
static constexpr SeqProxy rawSequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
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, SeqProxy const &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.
static STAmount accountReserve(jtx::Env &env, std::uint32_t count=1)
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.