3#include <xrpl/protocol/TxFlags.h>
4#include <xrpl/protocol/jss.h>
16 testcase(
"Test deletion of trust lines: revert trust line limit to zero");
24 env.
fund(
XRP(10000), becky, alice);
30 env(
trust(becky, alice[
"USD"](50)));
42 jv[
"account"] = becky.
human();
43 auto beckyLines = env.
rpc(
"json",
"account_lines",
to_string(jv));
45 jv[
"account"] = alice.
human();
46 auto aliceLines = env.
rpc(
"json",
"account_lines",
to_string(jv));
48 BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 1);
49 BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 1);
52 env(
trust(becky, alice[
"USD"](0)));
62 jv[
"account"] = becky.
human();
63 beckyLines = env.
rpc(
"json",
"account_lines",
to_string(jv));
65 jv[
"account"] = alice.
human();
66 aliceLines = env.
rpc(
"json",
"account_lines",
to_string(jv));
68 BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 0);
69 BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 0);
72 jv[
"account"] = becky.
human();
73 auto const beckyObj = env.
rpc(
"json",
"account_objects",
to_string(jv));
74 BEAST_EXPECT(beckyObj[jss::result][jss::account_objects].size() == 0);
76 jv[
"account"] = alice.
human();
77 auto const aliceObj = env.
rpc(
"json",
"account_objects",
to_string(jv));
78 BEAST_EXPECT(aliceObj[jss::result][jss::account_objects].size() == 0);
85 "Reset trust line limit with Authorised Lines: Verify "
86 "deletion of trust lines");
94 env.
fund(
XRP(10000), becky, alice);
98 env(
fset(alice, asfRequireAuth));
104 env(
trust(becky, alice[
"USD"](50)));
108 env(
trust(alice, alice[
"USD"](0), becky, tfSetfAuth));
120 jv[
"account"] = becky.
human();
121 auto beckyLines = env.
rpc(
"json",
"account_lines",
to_string(jv));
123 jv[
"account"] = alice.
human();
124 auto aliceLines = env.
rpc(
"json",
"account_lines",
to_string(jv));
126 BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 1);
127 BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 1);
130 env(
trust(becky, alice[
"USD"](0)));
140 jv[
"account"] = becky.
human();
141 beckyLines = env.
rpc(
"json",
"account_lines",
to_string(jv));
143 jv[
"account"] = alice.
human();
144 aliceLines = env.
rpc(
"json",
"account_lines",
to_string(jv));
146 BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 0);
147 BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 0);
153 if (thirdLineCreatesLE)
155 testcase(
"Allow two free trustlines");
159 testcase(
"Dynamic reserve for trustline");
163 Env env(*
this, features);
165 auto const gwA =
Account{
"gwA"};
166 auto const gwB =
Account{
"gwB"};
167 auto const acctC =
Account{
"acctC"};
168 auto const acctD =
Account{
"acctD"};
170 auto const& creator = createOnHighAcct ? acctD : acctC;
171 auto const& assistor = createOnHighAcct ? acctC : acctD;
173 auto const txFee = env.
current()->fees().base;
174 auto const baseReserve = env.
current()->fees().reserve;
175 auto const threelineReserve = env.
current()->fees().accountReserve(3);
177 env.
fund(
XRP(10000), gwA, gwB, assistor);
188 if (thirdLineCreatesLE)
191 env(
trust(creator, assistor[
"USD"](100)),
208 if (thirdLineCreatesLE)
217 jv[
"account"] = creator.human();
220 BEAST_EXPECT(
lines[jss::result][jss::lines].isArray());
221 BEAST_EXPECT(
lines[jss::result][jss::lines].size() == 3);
222 for (
auto const& line :
lines[jss::result][jss::lines])
224 BEAST_EXPECT(line[jss::limit] ==
"100");
232 testcase(
"TrustSet using a ticket");
237 Env env{*
this, features};
238 auto const gw =
Account{
"gateway"};
239 auto const alice =
Account{
"alice"};
240 auto const USD = gw[
"USD"];
242 env.fund(
XRP(10000), gw, alice);
259 env(
pay(gw, alice, USD(200)));
267 jv[jss::Account] = a.
human();
269 jv[jss::TransactionType] = jss::TrustSet;
277 testcase(
"TrustSet checks for malformed transactions");
280 Env env{*
this, features};
282 auto const gw =
Account{
"gateway"};
283 auto const alice =
Account{
"alice"};
284 env.fund(
XRP(10000), gw, alice);
287 for (
std::uint64_t badFlag = 1u; badFlag <= std::numeric_limits<std::uint32_t>::max();
290 if ((badFlag & tfTrustSetMask) != 0u)
321 "Ensure that trust line limits are respected in payment "
327 auto const gw =
Account{
"gateway"};
328 auto const alice =
Account{
"alice"};
329 env.fund(
XRP(10000), gw, alice);
332 env(
trust(alice, gw[
"USD"](100)));
340 env(
pay(gw, alice, gw[
"USD"](20)));
348 "Ensure that authorised trust lines do not allow payments "
349 "from unauthorised counter-parties");
354 auto const bob =
Account{
"bob"};
355 auto const alice =
Account{
"alice"};
356 env.fund(
XRP(10000), bob, alice);
359 env(
fset(alice, asfRequireAuth));
365 env(
trust(bob, alice[
"USD"](100)));
377 "Check that trust line limits are respected in conjunction "
378 "with rippling feature");
383 auto const bob =
Account{
"bob"};
384 auto const alice =
Account{
"alice"};
385 env.fund(
XRP(10000), bob, alice);
389 env(
trust(bob, alice[
"USD"](100)));
414 testcase <<
"TrustSet " << (createQuality ?
"creates" :
"removes")
415 <<
" quality of trustline for " << (createOnHighAcct ?
"high" :
"low")
419 Env env{*
this, features};
421 auto const alice =
Account{
"alice"};
422 auto const bob =
Account{
"bob"};
424 auto const& fromAcct = createOnHighAcct ? alice : bob;
425 auto const& toAcct = createOnHighAcct ? bob : alice;
427 env.fund(
XRP(10000), fromAcct, toAcct);
429 auto txWithoutQuality =
trust(toAcct, fromAcct[
"USD"](100));
430 txWithoutQuality[
"QualityIn"] =
"0";
431 txWithoutQuality[
"QualityOut"] =
"0";
433 auto txWithQuality = txWithoutQuality;
434 txWithQuality[
"QualityIn"] =
"1000";
435 txWithQuality[
"QualityOut"] =
"1000";
437 auto& tx1 = createQuality ? txWithQuality : txWithoutQuality;
438 auto& tx2 = createQuality ? txWithoutQuality : txWithQuality;
440 auto check_quality = [&](
bool const exists) {
442 jv[
"account"] = toAcct.human();
443 auto const lines = env.rpc(
"json",
"account_lines",
to_string(jv));
444 auto quality = exists ? 1000 : 0;
445 BEAST_EXPECT(
lines[jss::result][jss::lines].isArray());
446 BEAST_EXPECT(
lines[jss::result][jss::lines].size() == 1);
447 BEAST_EXPECT(
lines[jss::result][jss::lines][0u][jss::quality_in] == quality);
448 BEAST_EXPECT(
lines[jss::result][jss::lines][0u][jss::quality_out] == quality);
452 check_quality(createQuality);
455 check_quality(!createQuality);
461 testcase(
"Create trustline with disallow incoming");
463 using namespace test::jtx;
467 for (
bool const withFix : {
true,
false})
469 auto const amend = withFix ? features : features - fixDisallowIncomingV1;
471 Env env{*
this, amend};
472 auto const dist =
Account(
"dist");
474 auto const USD = gw[
"USD"];
475 auto const distUSD = dist[
"USD"];
477 env.fund(
XRP(1000), gw, dist);
480 env(
fset(gw, asfRequireAuth));
483 env(
fset(dist, asfDisallowIncomingTrustline));
486 env(
trust(dist, USD(10000)));
492 env(
trust(gw, distUSD(10000)),
txflags(tfSetfAuth), trustResult);
496 env(
pay(gw, dist, USD(1000)), txResult);
501 Env env{*
this, features};
503 auto const gw =
Account{
"gateway"};
504 auto const alice =
Account{
"alice"};
505 auto const bob =
Account{
"bob"};
506 auto const USD = gw[
"USD"];
508 env.fund(
XRP(10000), gw, alice, bob);
512 env(
fset(gw, asfDisallowIncomingTrustline));
520 env(
fclear(gw, asfDisallowIncomingTrustline));
524 env(
trust(alice, USD(1000)));
528 env(
pay(gw, alice, USD(200)));
532 env(
fset(gw, asfDisallowIncomingTrustline));
536 env(
pay(gw, alice, USD(200)));
541 env(
pay(gw, alice, USD(200)));
545 env(
fset(bob, asfDisallowIncomingTrustline));
558 env(
fclear(gw, asfDisallowIncomingTrustline));
562 env(
trust(bob, USD(1000)));
566 env(
pay(gw, bob, USD(200)));
597 using namespace test::jtx;
testcase_t testcase
Memberspace for declaring test cases.
A currency issued by an account.
Json::Value getJson(JsonOptions=JsonOptions::none) const override
void run() override
Runs the suite.
void testMalformedTransaction(FeatureBitset features)
void testTrustLineLimitsWithRippling()
void testExceedTrustLineLimit()
void testTrustLineResetWithAuthFlag()
void testTicketTrustSet(FeatureBitset features)
void testDisallowIncoming(FeatureBitset features)
void testFreeTrustlines(FeatureBitset features, bool thirdLineCreatesLE, bool createOnHighAcct)
static Json::Value trust_explicit_amt(jtx::Account const &a, STAmount const &amt)
void testTrustLineDelete()
void testModifyQualityOfTrustline(FeatureBitset features, bool createQuality, bool createOnHighAcct)
void testWithFeats(FeatureBitset features)
void testAuthFlagTrustLines()
Immutable cryptographic account descriptor.
std::string const & human() const
Returns the human readable public key.
A transaction testing environment.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
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 require(Args const &... args)
Check a set of requirements.
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Check a set of conditions.
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.
Json::Value create(Account const &account, std::uint32_t count)
Create one of more tickets.
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
XRP_t const XRP
Converts to XRP Issue or STAmount.
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
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< ltRIPPLE_STATE > lines
Match the number of trust lines in the account's owner directory.
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.
std::string to_string(base_uint< Bits, Tag > const &a)
AccountID const & noAccount()
A placeholder for empty accounts.
@ tecNO_LINE_INSUF_RESERVE
bool to_currency(Currency &, std::string const &)
Tries to convert a string to a Currency, returns true on success.
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...