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");
33 auto const seq1 = env.
seq(
"alice");
45 auto const seq2 = env.
seq(
"alice");
64 Env env(*
this, features);
65 auto const baseFee = env.
current()->fees().base;
66 env.
fund(
XRP(5000),
"alice",
"bob");
70 auto const ts = env.
now() + 97s;
72 auto const seq = 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() + 117s;
93 auto const seq = env.
seq(
"alice");
113 testcase(
"Timing: Finish and Cancel -> Finish");
114 Env env(*
this, features);
115 auto const baseFee = env.
current()->fees().base;
116 env.
fund(
XRP(5000),
"alice",
"bob");
120 auto const fts = env.
now() + 117s;
121 auto const cts = env.
now() + 192s;
123 auto const seq = env.
seq(
"alice");
128 for (; env.
now() < fts; env.
close())
142 testcase(
"Timing: Finish and Cancel -> Cancel");
143 Env env(*
this, features);
144 auto const baseFee = env.
current()->fees().base;
145 env.
fund(
XRP(5000),
"alice",
"bob");
149 auto const fts = env.
now() + 109s;
150 auto const cts = env.
now() + 184s;
152 auto const seq = env.
seq(
"alice");
157 for (; env.
now() < fts; env.
close())
165 for (; env.
now() < cts; env.
close())
185 Env env(*
this, features);
187 auto const alice =
Account(
"alice");
188 auto const bob =
Account(
"bob");
190 env.
fund(
XRP(5000), alice, bob);
198 auto const seq = env.
seq(alice);
204 BEAST_EXPECT((*sle)[sfSourceTag] == 1);
205 BEAST_EXPECT((*sle)[sfDestinationTag] == 2);
206 if (features[fixIncludeKeyletFields])
208 BEAST_EXPECT((*sle)[sfSequence] ==
seq);
212 BEAST_EXPECT(!sle->isFieldPresent(sfSequence));
227 Env env(*
this, features);
229 env.
fund(
XRP(5000),
"bob",
"george");
241 testcase(
"RequiresConditionOrFinishAfter");
243 Env env(*
this, features);
244 auto const baseFee = env.
current()->fees().base;
245 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
256 auto const seq = env.
seq(
"alice");
266 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5100));
270 auto const seqFt = env.
seq(
"alice");
278 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5200));
289 Env env(*
this, features);
290 auto const baseFee = env.
current()->fees().base;
291 env.
fund(
XRP(5000),
"alice",
"bob",
"gw");
315 bool const withTokenEscrow = env.
current()->rules().enabled(featureTokenEscrow);
368 auto const accountReserve =
drops(env.
current()->fees().reserve);
369 auto const accountIncrement =
drops(env.
current()->fees().increment);
371 env.
fund(accountReserve + accountIncrement +
XRP(50),
"daniel");
374 env.
fund(accountReserve + accountIncrement +
XRP(50),
"evan");
377 env.
fund(accountReserve,
"frank");
385 auto const seq = env.
seq(
"hannah");
393 auto const seq = env.
seq(
"ivan");
415 Env env(*
this, features);
416 auto const baseFee = env.
current()->fees().base;
417 env.
fund(
XRP(5000),
"alice",
"bob");
418 auto const seq = env.
seq(
"alice");
439 Env env(*
this, features);
440 auto const baseFee = env.
current()->fees().base;
441 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
442 auto const seq = env.
seq(
"alice");
465 Env env(*
this, features);
466 auto const baseFee = env.
current()->fees().base;
468 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
472 auto const seq = env.
seq(
"alice");
503 Env env(*
this, features);
504 auto const baseFee = env.
current()->fees().base;
506 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
512 auto const seq = env.
seq(
"alice");
530 Env env(*
this, features);
531 auto const baseFee = env.
current()->fees().base;
532 env.
fund(
XRP(5000),
"alice",
"bob");
533 auto const seq = env.
seq(
"alice");
572 Env env(*
this, features);
573 auto const baseFee = env.
current()->fees().base;
575 env.
fund(
XRP(5000),
"alice",
"bob");
576 auto const seq = env.
seq(
"alice");
609 Env env(*
this, features);
610 auto const baseFee = env.
current()->fees().base;
612 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
613 auto const seq = env.
seq(
"alice");
655 testcase(
"Escrow with CryptoConditions");
661 Env env(*
this, features);
662 auto const baseFee = env.
current()->fees().base;
663 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
664 auto const seq = env.
seq(
"alice");
665 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
669 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
673 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
677 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
685 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
691 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
697 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
706 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
712 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
718 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
728 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
731 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
735 Env env(*
this, features);
736 auto const baseFee = env.
current()->fees().base;
737 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
738 auto const seq = env.
seq(
"alice");
739 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
752 Env env(*
this, features);
753 auto const baseFee = env.
current()->fees().base;
754 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
756 auto const seq = env.
seq(
"alice");
760 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
763 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
771 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
775 Env env(*
this, features);
776 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
782 auto const p = v.
data();
783 auto const s = v.
size();
785 auto const ts = env.
now() + 1s;
818 auto const seq = env.
seq(
"alice");
819 auto const baseFee = env.
current()->fees().base;
833 Env env(*
this, features);
834 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
840 auto const cp = cv.
data();
841 auto const cs = cv.
size();
847 auto const fp = fv.
data();
848 auto const fs = fv.
size();
850 auto const ts = env.
now() + 1s;
883 auto const seq = env.
seq(
"alice");
884 auto const baseFee = env.
current()->fees().base;
980 Env env(*
this, features);
981 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
988 auto const seq = env.
seq(
"alice");
989 auto const baseFee = env.
current()->fees().base;
1019 fee(150 * baseFee));
1025 Env env(*
this, features);
1026 env.
fund(
XRP(5000),
"alice",
"bob");
1028 std::array<std::uint8_t, 45> cb = {{0xA2, 0x2B, 0x80, 0x20, 0x42, 0x4A, 0x70, 0x49, 0x49, 0x52, 0x92, 0x67,
1029 0xB6, 0x21, 0xB3, 0xD7, 0x91, 0x19, 0xD7, 0x29, 0xB2, 0x38, 0x2C, 0xED,
1030 0x8B, 0x29, 0x6C, 0x3C, 0x02, 0x8F, 0xA9, 0x7D, 0x35, 0x0F, 0x6D, 0x07,
1031 0x81, 0x03, 0x06, 0x34, 0xD2, 0x82, 0x02, 0x03, 0xC8}};
1045 using namespace jtx;
1048 auto const alice =
Account(
"alice");
1049 auto const bruce =
Account(
"bruce");
1050 auto const carol =
Account(
"carol");
1055 Env env(*
this, features);
1056 env.
fund(
XRP(5000), alice, bruce, carol);
1057 auto const aseq = env.
seq(alice);
1058 auto const bseq = env.
seq(bruce);
1117 Env env(*
this, features);
1118 env.
fund(
XRP(5000), alice, bruce, carol);
1119 auto const aseq = env.
seq(alice);
1120 auto const bseq = env.
seq(bruce);
1197 using namespace jtx;
1199 Env env(*
this, features);
1200 auto const baseFee = env.
current()->fees().base;
1207 auto const jtx = env.
jt(
1211 BEAST_EXPECT(!pf.consequences.isBlocker());
1212 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1213 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(1000));
1220 BEAST_EXPECT(!pf.consequences.isBlocker());
1221 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1222 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1229 BEAST_EXPECT(!pf.consequences.isBlocker());
1230 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1231 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1240 using namespace jtx;
1247 Env env(*
this, features);
1248 auto const baseFee = env.
current()->fees().base;
1249 env.
fund(
XRP(5000), alice, bob);
1272 auto const ts = env.
now() + 97s;
1276 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1282 for (; env.
now() < ts; env.
close())
1288 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1297 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1301 Env env(*
this, features);
1302 auto const baseFee = env.
current()->fees().base;
1303 env.
fund(
XRP(5000), alice, bob);
1325 auto const ts = env.
now() + 117s;
1332 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1338 for (; env.
now() < ts; env.
close())
1344 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1354 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1359 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1371 using namespace jtx;
1377 Account const dillon{
"dillon "};
1380 char const credType[] =
"abcde";
1384 Env env(*
this, features - featureCredentials);
1385 env.
fund(
XRP(5000), alice, bob);
1388 auto const seq = env.
seq(alice);
1398 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1404 Env env(*
this, features);
1406 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1412 std::string const credIdx = jv[jss::result][jss::index].asString();
1414 auto const seq = env.
seq(alice);
1446 testcase(
"Escrow with credentials without depositPreauth");
1449 Env env(*
this, features);
1451 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1459 std::string const credIdx = jv[jss::result][jss::index].asString();
1461 auto const seq = env.
seq(alice);
1476 char const credType2[] =
"random";
1482 auto const credIdxBob =
1485 auto const seq = env.
seq(alice);
1523 using namespace test::jtx;
1531BEAST_DEFINE_TESTSUITE(Escrow, app,
xrpl);
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 begin() const
const_iterator 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.
std::shared_ptr< SLE const > 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 ledgerEntry(jtx::Env &env, 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 authCredentials(jtx::Account const &account, std::vector< AuthorizeCredentials > const &auth)
Json::Value auth(Account const &account, Account const &auth)
Preauthorize for deposit.
auto const finish_time
Set the "FinishAfter" time tag on a JTx.
Json::Value create(AccountID const &account, AccountID const &to, STAmount const &amount)
std::array< std::uint8_t, 39 > const cb3
std::array< std::uint8_t, 7 > const fb2
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, 39 > const cb1
auto const cancel_time
Set the "CancelAfter" time tag on a JTx.
Json::Value finish(AccountID const &account, AccountID const &from, std::uint32_t seq)
std::array< std::uint8_t, 8 > const fb3
std::array< std::uint8_t, 4 > const fb1
Json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
XRP_t const XRP
Converts to XRP Issue or STAmount.
FeatureBitset testable_amendments()
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.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint32_t asfRequireDest
constexpr std::uint32_t tfPassive
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 asfDepositAuth
constexpr std::uint32_t asfDisallowXRP
@ 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.