21#include <test/jtx/AMM.h>
23#include <xrpl/protocol/AccountID.h>
24#include <xrpl/protocol/Feature.h>
25#include <xrpl/protocol/SField.h>
26#include <xrpl/protocol/TxFlags.h>
27#include <xrpl/protocol/jss.h>
38 using namespace test::jtx;
39 Env env(*
this, features);
45 env.
fund(
XRP(1000), G1, alice, bob);
48 env.
trust(G1[
"USD"](100), bob);
49 env.
trust(G1[
"USD"](100), alice);
52 env(
pay(G1, bob, G1[
"USD"](10)));
53 env(
pay(G1, alice, G1[
"USD"](100)));
56 env(
offer(alice,
XRP(500), G1[
"USD"](100)));
63 BEAST_EXPECT(
lines[jss::lines][0u][jss::account] == G1.human());
64 BEAST_EXPECT(
lines[jss::lines][0u][jss::limit] ==
"100");
65 BEAST_EXPECT(
lines[jss::lines][0u][jss::balance] ==
"10");
72 BEAST_EXPECT(
lines[jss::lines][0u][jss::account] == G1.human());
73 BEAST_EXPECT(
lines[jss::lines][0u][jss::limit] ==
"100");
74 BEAST_EXPECT(
lines[jss::lines][0u][jss::balance] ==
"100");
80 env(
pay(alice, bob, G1[
"USD"](1)));
83 env(
pay(bob, alice, G1[
"USD"](1)));
91 auto affected = env.
meta()->getJson(
96 affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
98 ff[sfLowLimit.fieldName] ==
108 env(
offer(bob, G1[
"USD"](5),
XRP(25)));
109 auto affected = env.
meta()->getJson(
114 affected[3u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
116 ff[sfHighLimit.fieldName] ==
121 BEAST_EXPECT(ff[sfBalance.fieldName] == amt);
130 env(
pay(alice, bob, G1[
"USD"](1)));
141 for (
auto const& it :
lines[jss::lines])
143 if (it[jss::account] == bob.human())
149 if (!BEAST_EXPECT(bobLine))
151 BEAST_EXPECT(bobLine[jss::freeze] ==
true);
152 BEAST_EXPECT(bobLine[jss::balance] ==
"-16");
159 for (
auto const& it :
lines[jss::lines])
161 if (it[jss::account] == G1.human())
167 if (!BEAST_EXPECT(g1Line))
169 BEAST_EXPECT(g1Line[jss::freeze_peer] ==
true);
170 BEAST_EXPECT(g1Line[jss::balance] ==
"16");
177 auto affected = env.
meta()->getJson(
182 affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
184 ff[sfLowLimit.fieldName] ==
186 BEAST_EXPECT(!(ff[jss::Flags].asUInt() &
lsfLowFreeze));
197 using namespace test::jtx;
198 Env env(*
this, features);
206 env.
trust(G1[
"USD"](1000), A1);
209 if (features[featureDeepFreeze])
288 testcase(
"Create Frozen Trustline");
290 using namespace test::jtx;
291 Env env(*
this, features);
315 if (features[featureDeepFreeze])
324 if (features[featureDeepFreeze])
340 using namespace test::jtx;
341 Env env(*
this, features);
349 env.
trust(G1[
"USD"](1000), A1);
352 if (features[featureDeepFreeze])
371 auto affected = env.
meta()->getJson(
384 using namespace test::jtx;
385 Env env(*
this, features);
395 env.
fund(
XRP(20000), A2, A3, A4);
398 env.
trust(G1[
"USD"](1200), A1);
399 env.
trust(G1[
"USD"](200), A2);
400 env.
trust(G1[
"BTC"](100), A3);
401 env.
trust(G1[
"BTC"](100), A4);
404 env(
pay(G1, A1, G1[
"USD"](1000)));
405 env(
pay(G1, A2, G1[
"USD"](100)));
406 env(
pay(G1, A3, G1[
"BTC"](100)));
407 env(
pay(G1, A4, G1[
"BTC"](100)));
436 "XRP")[jss::result][jss::offers];
444 BEAST_EXPECT(accounts.
find(A2.human()) !=
std::end(accounts));
445 BEAST_EXPECT(accounts.
find(G1.human()) !=
std::end(accounts));
451 std::string(
"USD/") + G1.human())[jss::result][jss::offers];
459 BEAST_EXPECT(accounts.
find(A1.human()) !=
std::end(accounts));
460 BEAST_EXPECT(accounts.
find(G1.human()) !=
std::end(accounts));
466 env(
offer(A3, G1[
"BTC"](1),
XRP(1)));
469 env(
offer(A4,
XRP(1), G1[
"BTC"](1)));
472 env(
pay(G1, A2, G1[
"USD"](1)));
475 env(
pay(A2, G1, G1[
"USD"](1)));
478 env(
pay(A2, A1, G1[
"USD"](1)));
481 env(
pay(A1, A2, G1[
"USD"](1)));
512 std::string(
"USD/") + G1.human())[jss::result][jss::offers];
519 "XRP")[jss::result][jss::offers];
527 env(
pay(G1, A2, G1[
"USD"](1)));
530 env(
pay(A2, G1, G1[
"USD"](1)));
542 using namespace test::jtx;
543 Env env(*
this, features);
552 env.
fund(
XRP(1000), frozenAcc);
553 env.
fund(
XRP(1000), deepFrozenAcc);
556 env.
trust(G1[
"USD"](1000), A1);
557 env.
trust(G1[
"USD"](1000), frozenAcc);
558 env.
trust(G1[
"USD"](1000), deepFrozenAcc);
561 env(
pay(G1, A1, G1[
"USD"](1000)));
562 env(
pay(G1, frozenAcc, G1[
"USD"](1000)));
563 env(
pay(G1, deepFrozenAcc, G1[
"USD"](1000)));
573 if (features[featureDeepFreeze])
609 if (features[featureDeepFreeze])
623 auto affected = env.
meta()->getJson(
628 auto let = affected[0u][sfModifiedNode.fieldName]
629 [sfLedgerEntryType.fieldName];
630 BEAST_EXPECT(let == jss::AccountRoot);
640 if (features[featureDeepFreeze])
655 testcase(
"Offers for Frozen Trust Lines");
657 using namespace test::jtx;
658 Env env(*
this, features);
665 env.
fund(
XRP(1000), G1, A3, A4);
669 env.
trust(G1[
"USD"](1000), A2);
670 env.
trust(G1[
"USD"](2000), A3);
671 env.
trust(G1[
"USD"](2000), A4);
674 env(
pay(G1, A3, G1[
"USD"](2000)));
675 env(
pay(G1, A4, G1[
"USD"](2000)));
691 offers[0u][jss::taker_gets] ==
695 env(
offer(A4,
XRP(999), G1[
"USD"](999)));
705 affected[1u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
707 ff[sfHighLimit.fieldName] ==
709 BEAST_EXPECT(!(ff[jss::Flags].asUInt() &
lsfLowFreeze));
734 ff = affected[0u][sfModifiedNode.fieldName][sfFinalFields.fieldName];
736 ff[sfLowLimit.fieldName] ==
743 env(
offer(A2, G1[
"USD"](999),
XRP(999)));
748 auto created = affected[0u][sfCreatedNode.fieldName];
750 created[sfNewFields.fieldName][jss::Account] == A2.human());
762 testcase(
"Offers on frozen trust lines");
764 using namespace test::jtx;
765 Env env(*
this, features);
771 auto const USD{G1[
"USD"]};
773 env.
fund(
XRP(10000), G1, A1, A2, A3);
776 auto const limit = USD(10000);
777 env.
trust(limit, A1, A2, A3);
780 env(
pay(G1, A1, USD(1000)));
781 env(
pay(G1, A2, USD(1000)));
845 if (features[featureDeepFreeze])
914 if (features[featureDeepFreeze])
964 if (features[featureFlowCross])
1003 if (features[featureDeepFreeze])
1040 testcase(
"Longer paths payment on frozen trust lines");
1041 using namespace test::jtx;
1044 Env env(*
this, features);
1048 auto const USD{G1[
"USD"]};
1050 env.
fund(
XRP(10000), G1, A1, A2);
1053 auto const limit = USD(10000);
1054 env.
trust(limit, A1, A2);
1057 env(
pay(G1, A1, USD(1000)));
1058 env(
pay(G1, A2, USD(1000)));
1070 env(
pay(A1, G1, USD(10)),
1078 env(
pay(G1, A1, USD(10)),
1090 if (features[featureDeepFreeze])
1096 env(
pay(A1, G1, USD(10)),
1104 env(
pay(G1, A1, USD(10)),
1122 env(
pay(A1, G1, USD(10)),
1129 env(
pay(G1, A1, USD(10)),
1141 if (features[featureDeepFreeze])
1147 env(
pay(A1, G1, USD(10)),
1155 env(
pay(G1, A1, USD(10)),
1180 env(
pay(A1, G1,
XRP(10)),
1187 env(
pay(G1, A1,
XRP(10)),
1199 if (features[featureDeepFreeze])
1205 env(
pay(A1, G1,
XRP(10)),
1213 env(
pay(G1, A1,
XRP(10)),
1231 env(
pay(A1, G1,
XRP(10)),
1238 env(
pay(G1, A1,
XRP(10)),
1250 if (features[featureDeepFreeze])
1256 env(
pay(A1, G1,
XRP(10)),
1264 env(
pay(G1, A1,
XRP(10)),
1284 testcase(
"Direct payments on frozen trust lines");
1286 using namespace test::jtx;
1287 Env env(*
this, features);
1292 auto const USD{G1[
"USD"]};
1294 env.
fund(
XRP(10000), G1, A1, A2);
1297 auto const limit = USD(10000);
1298 env.
trust(limit, A1, A2);
1301 env(
pay(G1, A1, USD(1000)));
1302 env(
pay(G1, A2, USD(1000)));
1307 env(
pay(A1, G1, USD(1)));
1308 env(
pay(A2, G1, USD(1)));
1312 env(
pay(A1, A2, USD(1)));
1313 env(
pay(A2, A1, USD(1)));
1321 env(
pay(A1, G1, USD(1)));
1322 env(
pay(G1, A1, USD(1)));
1329 env(
pay(A2, A1, USD(1)));
1332 if (features[featureDeepFreeze])
1339 env(
pay(A1, G1, USD(1)));
1340 env(
pay(G1, A1, USD(1)));
1363 env(
pay(A2, G1, USD(1)));
1364 env(
pay(G1, A2, USD(1)));
1368 env(
pay(A1, G1, USD(1)));
1371 env(
pay(A1, A2, USD(1)));
1375 env(
pay(G1, A1, USD(1)));
1379 if (features[featureDeepFreeze])
1386 env(
pay(A2, G1, USD(1)));
1387 env(
pay(G1, A2, USD(1)));
1391 env(
pay(A1, G1, USD(1)));
1395 env(
pay(G1, A1, USD(1)));
1406 testcase(
"Checks on frozen trust lines");
1408 using namespace test::jtx;
1409 Env env(*
this, features);
1414 auto const USD{G1[
"USD"]};
1416 env.
fund(
XRP(10000), G1, A1, A2);
1419 auto const limit = USD(10000);
1420 env.
trust(limit, A1, A2);
1423 env(
pay(G1, A1, USD(1000)));
1424 env(
pay(G1, A2, USD(1000)));
1547 if (features[featureDeepFreeze])
1658 if (features[featureDeepFreeze])
1701 testcase(
"AMM payments on frozen trust lines");
1702 using namespace test::jtx;
1705 Env env(*
this, features);
1709 auto const USD{G1[
"USD"]};
1711 env.
fund(
XRP(10000), G1, A1, A2);
1714 env.
trust(G1[
"USD"](10000), A1, A2);
1717 env(
pay(G1, A1, USD(1000)));
1718 env(
pay(G1, A2, USD(1000)));
1721 AMM ammG1(env, G1,
XRP(1'000), USD(1'000));
1730 env(
pay(A1, A2, USD(10)),
1737 env(
pay(A1, A2,
XRP(10)),
1745 env(
pay(A2, A1, USD(10)),
1752 env(
pay(A2, A1,
XRP(10)),
1764 if (features[featureDeepFreeze])
1770 env(
pay(A1, A2, USD(10)),
1777 env(
pay(A1, A2,
XRP(10)),
1785 env(
pay(A2, A1, USD(10)),
1793 env(
pay(A2, A1,
XRP(10)),
1807 testcase(
"NFT offers on frozen trust lines");
1808 using namespace test::jtx;
1810 Env env(*
this, features);
1814 auto const USD{G1[
"USD"]};
1816 env.
fund(
XRP(10000), G1, A1, A2);
1819 auto const limit = USD(10000);
1820 env.
trust(limit, A1, A2);
1823 env(
pay(G1, A1, USD(1000)));
1824 env(
pay(G1, A2, USD(1000)));
1842 if (features[featureDeepFreeze])
1873 if (features[featureDeepFreeze])
1903 if (features[featureDeepFreeze])
1933 if (features[featureDeepFreeze])
1953 size_t expectedArraySize,
1954 size_t expectedArrayIndex,
1955 bool modified =
true)
1957 using namespace test::jtx;
1958 auto const affected =
1965 return affected[expectedArrayIndex][sfModifiedNode.fieldName]
1966 [sfFinalFields.fieldName][jss::Flags]
1970 return affected[expectedArrayIndex][sfCreatedNode.fieldName]
1971 [sfNewFields.fieldName][jss::Flags]
1988 using namespace test::jtx;
1993 uint256 const sellOfferIndex =
1999 return sellOfferIndex;
2021 using namespace test::jtx;
2023 testAll(sa - featureFlowCross - featureDeepFreeze);
2024 testAll(sa - featureFlowCross);
2025 testAll(sa - featureDeepFreeze);
testcase_t testcase
Memberspace for declaring test cases.
void testOffersWhenDeepFrozen(FeatureBitset features)
uint256 createNFTSellOffer(test::jtx::Env &env, test::jtx::Account const &account, test::jtx::PrettyAmount const ¤cy)
uint32_t getTrustlineFlags(test::jtx::Env &env, size_t expectedArraySize, size_t expectedArrayIndex, bool modified=true)
void testGlobalFreeze(FeatureBitset features)
void testDeepFreeze(FeatureBitset features)
void testPaymentsWhenDeepFrozen(FeatureBitset features)
void testNoFreeze(FeatureBitset features)
void testNFTOffersWhenFreeze(FeatureBitset features)
void testAMMWhenFreeze(FeatureBitset features)
void testPathsWhenFrozen(FeatureBitset features)
void run() override
Runs the suite.
uint256 getCheckIndex(AccountID const &account, std::uint32_t uSequence)
void testCreateFrozenTrustline(FeatureBitset features)
void testRippleState(FeatureBitset features)
void testSetAndClear(FeatureBitset features)
void testOffersWhenFrozen(FeatureBitset features)
void testChecksWhenFrozen(FeatureBitset features)
A currency issued by an account.
Convenience class to test AMM functionality.
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.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
Json::Value rpc(unsigned apiVersion, std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::shared_ptr< STObject const > meta()
Return metadata for the last JTx.
Match clear account flags.
Set Paths, SendMax on a JTx.
Sets the SendMax on a JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
Keylet nftoffer(AccountID const &owner, std::uint32_t seq)
An offer from an account to buy or sell an NFT.
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Json::Value create(A const &account, A const &dest, STAmount const &sendMax)
Create a check.
Json::Value cash(jtx::Account const &dest, uint256 const &checkId, STAmount const &amount)
Cash a check requiring that a specific amount be delivered.
uint256 getNextID(jtx::Env const &env, jtx::Account const &issuer, std::uint32_t nfTokenTaxon, std::uint16_t flags, std::uint16_t xferFee)
Get the next NFTokenID that will be issued.
Json::Value createOffer(jtx::Account const &account, uint256 const &nftokenID, STAmount const &amount)
Create an NFTokenOffer.
Json::Value acceptSellOffer(jtx::Account const &account, uint256 const &offerIndex)
Accept an NFToken sell offer.
Json::Value mint(jtx::Account const &account, std::uint32_t nfTokenTaxon)
Mint an NFToken.
owner_count< ltRIPPLE_STATE > lines
Match the number of trust lines in the account's owner directory.
bool checkArraySize(Json::Value const &val, unsigned int size)
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
owner_count< ltOFFER > offers
Match the number of offers in the account's owner directory.
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Json::Value getAccountLines(Env &env, AccountID const &acctId)
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
XRP_t const XRP
Converts to XRP Issue or STAmount.
FeatureBitset supported_amendments()
Json::Value offer_cancel(Account const &account, std::uint32_t offerSeq)
Cancel an offer.
Json::Value getAccountOffers(Env &env, AccountID const &acct, bool current)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
AccountID const & noAccount()
A placeholder for empty accounts.
constexpr std::uint32_t asfGlobalFreeze
constexpr std::uint32_t tfSetDeepFreeze
constexpr std::uint32_t const tfSellNFToken
constexpr std::uint32_t asfNoFreeze
constexpr std::uint32_t tfFillOrKill
constexpr std::uint32_t tfPassive
constexpr std::uint32_t tfClearFreeze
constexpr std::uint32_t tfNoRippleDirect
constexpr std::uint32_t tfClearDeepFreeze
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
constexpr std::uint32_t tfSetFreeze
constexpr std::uint32_t const tfTransferable
bool to_currency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
Represents an XRP or IOU quantity This customizes the string conversion and supports XRP conversions ...