3#include <xrpl/ledger/Dir.h>
4#include <xrpl/protocol/Feature.h>
5#include <xrpl/protocol/Indexes.h>
6#include <xrpl/protocol/TxFlags.h>
7#include <xrpl/protocol/jss.h>
8#include <xrpl/tx/applySteps.h>
26 Env env(*
this, features);
27 auto const baseFee = env.
current()->fees().base;
28 env.
fund(
XRP(5000),
"alice",
"bob");
32 auto const seq1 = env.
seq(
"alice");
44 auto const seq2 = env.
seq(
"alice");
63 Env env(*
this, features);
64 auto const baseFee = env.
current()->fees().base;
65 env.
fund(
XRP(5000),
"alice",
"bob");
69 auto const ts = env.
now() + 97s;
71 auto const seq = 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() + 117s;
92 auto const seq = env.
seq(
"alice");
114 testcase(
"Timing: Finish and Cancel -> Finish");
115 Env env(*
this, features);
116 auto const baseFee = env.
current()->fees().base;
117 env.
fund(
XRP(5000),
"alice",
"bob");
121 auto const fts = env.
now() + 117s;
122 auto const cts = env.
now() + 192s;
124 auto const seq = env.
seq(
"alice");
131 for (; env.
now() < fts; env.
close())
145 testcase(
"Timing: Finish and Cancel -> Cancel");
146 Env env(*
this, features);
147 auto const baseFee = env.
current()->fees().base;
148 env.
fund(
XRP(5000),
"alice",
"bob");
152 auto const fts = env.
now() + 109s;
153 auto const cts = env.
now() + 184s;
155 auto const seq = env.
seq(
"alice");
162 for (; env.
now() < fts; env.
close())
170 for (; env.
now() < cts; env.
close())
190 Env env(*
this, features);
192 auto const alice =
Account(
"alice");
193 auto const bob =
Account(
"bob");
195 env.
fund(
XRP(5000), alice, bob);
199 env(
fset(bob, asfRequireDest));
205 auto const seq = env.
seq(alice);
214 BEAST_EXPECT((*sle)[sfSourceTag] == 1);
215 BEAST_EXPECT((*sle)[sfDestinationTag] == 2);
216 if (features[fixIncludeKeyletFields])
218 BEAST_EXPECT((*sle)[sfSequence] ==
seq);
222 BEAST_EXPECT(!sle->isFieldPresent(sfSequence));
237 Env env(*
this, features);
239 env.
fund(
XRP(5000),
"bob",
"george");
240 env(
fset(
"george", asfDisallowXRP));
251 testcase(
"RequiresConditionOrFinishAfter");
253 Env env(*
this, features);
254 auto const baseFee = env.
current()->fees().base;
255 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
266 auto const seq = env.
seq(
"alice");
276 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5100));
280 auto const seqFt = env.
seq(
"alice");
288 BEAST_EXPECT(env.
balance(
"bob") ==
XRP(5200));
299 Env env(*
this, features);
300 auto const baseFee = env.
current()->fees().base;
301 env.
fund(
XRP(5000),
"alice",
"bob",
"gw");
329 bool const withTokenEscrow = env.
current()->rules().enabled(featureTokenEscrow);
375 env(
fset(
"carol", asfRequireDest));
390 auto const accountReserve =
drops(env.
current()->fees().reserve);
391 auto const accountIncrement =
drops(env.
current()->fees().increment);
393 env.
fund(accountReserve + accountIncrement +
XRP(50),
"daniel");
398 env.
fund(accountReserve + accountIncrement +
XRP(50),
"evan");
403 env.
fund(accountReserve,
"frank");
411 auto const seq = env.
seq(
"hannah");
421 auto const seq = env.
seq(
"ivan");
443 Env env(*
this, features);
444 auto const baseFee = env.
current()->fees().base;
445 env.
fund(
XRP(5000),
"alice",
"bob");
446 auto const seq = env.
seq(
"alice");
467 Env env(*
this, features);
468 auto const baseFee = env.
current()->fees().base;
469 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
470 auto const seq = env.
seq(
"alice");
493 Env env(*
this, features);
494 auto const baseFee = env.
current()->fees().base;
496 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
497 env(
fset(
"bob", asfDepositAuth));
500 auto const seq = env.
seq(
"alice");
531 Env env(*
this, features);
532 auto const baseFee = env.
current()->fees().base;
534 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
535 env(
fset(
"bob", asfDepositAuth));
540 auto const seq = env.
seq(
"alice");
558 Env env(*
this, features);
559 auto const baseFee = env.
current()->fees().base;
560 env.
fund(
XRP(5000),
"alice",
"bob");
561 auto const seq = env.
seq(
"alice");
600 Env env(*
this, features);
601 auto const baseFee = env.
current()->fees().base;
603 env.
fund(
XRP(5000),
"alice",
"bob");
604 auto const seq = env.
seq(
"alice");
617 env(
fset(
"alice", asfDepositAuth));
637 Env env(*
this, features);
638 auto const baseFee = env.
current()->fees().base;
640 env.
fund(
XRP(5000),
"alice",
"bob",
"zelda");
641 auto const seq = env.
seq(
"alice");
660 env(
fset(
"alice", asfDepositAuth));
683 testcase(
"Escrow with CryptoConditions");
689 Env env(*
this, features);
690 auto const baseFee = env.
current()->fees().base;
691 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
692 auto const seq = env.
seq(
"alice");
693 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
697 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
701 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
705 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
713 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
719 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
725 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);
756 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
759 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
763 Env env(*
this, features);
764 auto const baseFee = env.
current()->fees().base;
765 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
766 auto const seq = env.
seq(
"alice");
767 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 0);
780 Env env(*
this, features);
781 auto const baseFee = env.
current()->fees().base;
782 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
784 auto const seq = env.
seq(
"alice");
788 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
791 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
799 BEAST_EXPECT((*env.
le(
"alice"))[sfOwnerCount] == 1);
803 Env env(*
this, features);
804 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
810 auto const p = v.
data();
811 auto const s = v.
size();
813 auto const ts = env.
now() + 1s;
846 auto const seq = env.
seq(
"alice");
847 auto const baseFee = env.
current()->fees().base;
861 Env env(*
this, features);
862 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
868 auto const cp = cv.
data();
869 auto const cs = cv.
size();
875 auto const fp = fv.
data();
876 auto const fs = fv.
size();
878 auto const ts = env.
now() + 1s;
911 auto const seq = env.
seq(
"alice");
912 auto const baseFee = env.
current()->fees().base;
1002 fee(150 * baseFee));
1008 Env env(*
this, features);
1009 env.
fund(
XRP(5000),
"alice",
"bob",
"carol");
1016 auto const seq = env.
seq(
"alice");
1017 auto const baseFee = env.
current()->fees().base;
1051 fee(150 * baseFee));
1057 Env env(*
this, features);
1058 env.
fund(
XRP(5000),
"alice",
"bob");
1061 {0xA2, 0x2B, 0x80, 0x20, 0x42, 0x4A, 0x70, 0x49, 0x49, 0x52, 0x92, 0x67,
1062 0xB6, 0x21, 0xB3, 0xD7, 0x91, 0x19, 0xD7, 0x29, 0xB2, 0x38, 0x2C, 0xED,
1063 0x8B, 0x29, 0x6C, 0x3C, 0x02, 0x8F, 0xA9, 0x7D, 0x35, 0x0F, 0x6D, 0x07,
1064 0x81, 0x03, 0x06, 0x34, 0xD2, 0x82, 0x02, 0x03, 0xC8}};
1078 using namespace jtx;
1081 auto const alice =
Account(
"alice");
1082 auto const bruce =
Account(
"bruce");
1083 auto const carol =
Account(
"carol");
1088 Env env(*
this, features);
1089 env.
fund(
XRP(5000), alice, bruce, carol);
1090 auto const aseq = env.
seq(alice);
1091 auto const bseq = env.
seq(bruce);
1154 Env env(*
this, features);
1155 env.
fund(
XRP(5000), alice, bruce, carol);
1156 auto const aseq = env.
seq(alice);
1157 auto const bseq = env.
seq(bruce);
1236 using namespace jtx;
1238 Env env(*
this, features);
1239 auto const baseFee = env.
current()->fees().base;
1246 auto const jtx = env.
jt(
1254 BEAST_EXPECT(!pf.consequences.isBlocker());
1255 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1256 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(1000));
1264 BEAST_EXPECT(!pf.consequences.isBlocker());
1265 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1266 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1274 BEAST_EXPECT(!pf.consequences.isBlocker());
1275 BEAST_EXPECT(pf.consequences.fee() ==
drops(baseFee));
1276 BEAST_EXPECT(pf.consequences.potentialSpend() ==
XRP(0));
1285 using namespace jtx;
1292 Env env(*
this, features);
1293 auto const baseFee = env.
current()->fees().base;
1294 env.
fund(
XRP(5000), alice, bob);
1317 auto const ts = env.
now() + 97s;
1323 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1329 for (; env.
now() < ts; env.
close())
1335 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1349 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1353 Env env(*
this, features);
1354 auto const baseFee = env.
current()->fees().base;
1355 env.
fund(
XRP(5000), alice, bob);
1377 auto const ts = env.
now() + 117s;
1384 BEAST_EXPECT(env.
seq(alice) == aliceRootSeq);
1390 for (; env.
now() < ts; env.
close())
1396 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1406 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1413 BEAST_EXPECT(env.
seq(bob) == bobRootSeq);
1425 using namespace jtx;
1431 Account const dillon{
"dillon "};
1434 char const credType[] =
"abcde";
1438 Env env(*
this, features - featureCredentials);
1439 env.
fund(
XRP(5000), alice, bob);
1442 auto const seq = env.
seq(alice);
1446 env(
fset(bob, asfDepositAuth));
1452 "48004829F915654A81B11C4AB8218D96FED67F209B58328A72314FB6EA288B"
1458 Env env(*
this, features);
1460 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1466 std::string const credIdx = jv[jss::result][jss::index].asString();
1468 auto const seq = env.
seq(alice);
1473 env(
fset(bob, asfDepositAuth));
1506 testcase(
"Escrow with credentials without depositPreauth");
1509 Env env(*
this, features);
1511 env.
fund(
XRP(5000), alice, bob, carol, dillon, zelda);
1519 std::string const credIdx = jv[jss::result][jss::index].asString();
1521 auto const seq = env.
seq(alice);
1536 char const credType2[] =
"random";
1542 auto const credIdxBob =
1546 auto const seq = env.
seq(alice);
1551 env(
fset(bob, asfDepositAuth));
1584 using namespace test::jtx;
1588 testTags(all - fixIncludeKeyletFields);
1592BEAST_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.
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.