mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Additional unit tests for testing deletion of trust lines (#4886)
This commit is contained in:
committed by
GitHub
parent
58f3abe3c6
commit
263e984bf4
@@ -29,6 +29,144 @@ class SetTrust_test : public beast::unit_test::suite
|
||||
FeatureBitset const disallowIncoming{featureDisallowIncoming};
|
||||
|
||||
public:
|
||||
void
|
||||
testTrustLineDelete()
|
||||
{
|
||||
testcase(
|
||||
"Test deletion of trust lines: revert trust line limit to zero");
|
||||
|
||||
using namespace jtx;
|
||||
Env env(*this);
|
||||
|
||||
Account const alice = Account{"alice"};
|
||||
Account const becky = Account{"becky"};
|
||||
|
||||
env.fund(XRP(10000), becky, alice);
|
||||
env.close();
|
||||
|
||||
// becky wants to hold at most 50 tokens of alice["USD"]
|
||||
// becky is the customer, alice is the issuer
|
||||
// becky can be sent at most 50 tokens of alice's USD
|
||||
env(trust(becky, alice["USD"](50)));
|
||||
env.close();
|
||||
|
||||
// Since the settings of the trust lines are non-default for both
|
||||
// alice and becky, both of them will be charged an owner reserve
|
||||
// Irrespective of whether the issuer or the customer initiated
|
||||
// the trust-line creation, both will be charged
|
||||
env.require(lines(alice, 1));
|
||||
env.require(lines(becky, 1));
|
||||
|
||||
// Fetch the trust-lines via RPC for verification
|
||||
Json::Value jv;
|
||||
jv["account"] = becky.human();
|
||||
auto beckyLines = env.rpc("json", "account_lines", to_string(jv));
|
||||
|
||||
jv["account"] = alice.human();
|
||||
auto aliceLines = env.rpc("json", "account_lines", to_string(jv));
|
||||
|
||||
BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 1);
|
||||
BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 1);
|
||||
|
||||
// reset the trust line limits to zero
|
||||
env(trust(becky, alice["USD"](0)));
|
||||
env.close();
|
||||
|
||||
// the reset of the trust line limits deletes the trust-line
|
||||
// this occurs despite the authorization of the trust-line by the
|
||||
// issuer(alice, in this unit test)
|
||||
env.require(lines(becky, 0));
|
||||
env.require(lines(alice, 0));
|
||||
|
||||
// second verification check via RPC calls
|
||||
jv["account"] = becky.human();
|
||||
beckyLines = env.rpc("json", "account_lines", to_string(jv));
|
||||
|
||||
jv["account"] = alice.human();
|
||||
aliceLines = env.rpc("json", "account_lines", to_string(jv));
|
||||
|
||||
BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 0);
|
||||
BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 0);
|
||||
|
||||
// additionally, verify that account_objects is an empty array
|
||||
jv["account"] = becky.human();
|
||||
auto const beckyObj = env.rpc("json", "account_objects", to_string(jv));
|
||||
BEAST_EXPECT(beckyObj[jss::result][jss::account_objects].size() == 0);
|
||||
|
||||
jv["account"] = alice.human();
|
||||
auto const aliceObj = env.rpc("json", "account_objects", to_string(jv));
|
||||
BEAST_EXPECT(aliceObj[jss::result][jss::account_objects].size() == 0);
|
||||
}
|
||||
|
||||
void
|
||||
testTrustLineResetWithAuthFlag()
|
||||
{
|
||||
testcase(
|
||||
"Reset trust line limit with Authorised Lines: Verify "
|
||||
"deletion of trust lines");
|
||||
|
||||
using namespace jtx;
|
||||
Env env(*this);
|
||||
|
||||
Account const alice = Account{"alice"};
|
||||
Account const becky = Account{"becky"};
|
||||
|
||||
env.fund(XRP(10000), becky, alice);
|
||||
env.close();
|
||||
|
||||
// alice wants to ensure that all holders of her tokens are authorised
|
||||
env(fset(alice, asfRequireAuth));
|
||||
env.close();
|
||||
|
||||
// becky wants to hold at most 50 tokens of alice["USD"]
|
||||
// becky is the customer, alice is the issuer
|
||||
// becky can be sent at most 50 tokens of alice's USD
|
||||
env(trust(becky, alice["USD"](50)));
|
||||
env.close();
|
||||
|
||||
// alice authorizes becky to hold alice["USD"] tokens
|
||||
env(trust(alice, alice["USD"](0), becky, tfSetfAuth));
|
||||
env.close();
|
||||
|
||||
// Since the settings of the trust lines are non-default for both
|
||||
// alice and becky, both of them will be charged an owner reserve
|
||||
// Irrespective of whether the issuer or the customer initiated
|
||||
// the trust-line creation, both will be charged
|
||||
env.require(lines(alice, 1));
|
||||
env.require(lines(becky, 1));
|
||||
|
||||
// Fetch the trust-lines via RPC for verification
|
||||
Json::Value jv;
|
||||
jv["account"] = becky.human();
|
||||
auto beckyLines = env.rpc("json", "account_lines", to_string(jv));
|
||||
|
||||
jv["account"] = alice.human();
|
||||
auto aliceLines = env.rpc("json", "account_lines", to_string(jv));
|
||||
|
||||
BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 1);
|
||||
BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 1);
|
||||
|
||||
// reset the trust line limits to zero
|
||||
env(trust(becky, alice["USD"](0)));
|
||||
env.close();
|
||||
|
||||
// the reset of the trust line limits deletes the trust-line
|
||||
// this occurs despite the authorization of the trust-line by the
|
||||
// issuer(alice, in this unit test)
|
||||
env.require(lines(becky, 0));
|
||||
env.require(lines(alice, 0));
|
||||
|
||||
// second verification check via RPC calls
|
||||
jv["account"] = becky.human();
|
||||
beckyLines = env.rpc("json", "account_lines", to_string(jv));
|
||||
|
||||
jv["account"] = alice.human();
|
||||
aliceLines = env.rpc("json", "account_lines", to_string(jv));
|
||||
|
||||
BEAST_EXPECT(aliceLines[jss::result][jss::lines].size() == 0);
|
||||
BEAST_EXPECT(beckyLines[jss::result][jss::lines].size() == 0);
|
||||
}
|
||||
|
||||
void
|
||||
testFreeTrustlines(
|
||||
FeatureBitset features,
|
||||
@@ -203,6 +341,100 @@ public:
|
||||
env(trust(alice, gw["USD"](100), tfSetfAuth), ter(tefNO_AUTH_REQUIRED));
|
||||
}
|
||||
|
||||
void
|
||||
testExceedTrustLineLimit()
|
||||
{
|
||||
testcase(
|
||||
"Ensure that trust line limits are respected in payment "
|
||||
"transactions");
|
||||
|
||||
using namespace jtx;
|
||||
Env env{*this};
|
||||
|
||||
auto const gw = Account{"gateway"};
|
||||
auto const alice = Account{"alice"};
|
||||
env.fund(XRP(10000), gw, alice);
|
||||
|
||||
// alice wants to hold at most 100 of gw's USD tokens
|
||||
env(trust(alice, gw["USD"](100)));
|
||||
env.close();
|
||||
|
||||
// send a payment for a large quantity through the trust line
|
||||
env(pay(gw, alice, gw["USD"](200)), ter(tecPATH_PARTIAL));
|
||||
env.close();
|
||||
|
||||
// on the other hand, smaller payments should succeed
|
||||
env(pay(gw, alice, gw["USD"](20)));
|
||||
env.close();
|
||||
}
|
||||
|
||||
void
|
||||
testAuthFlagTrustLines()
|
||||
{
|
||||
testcase(
|
||||
"Ensure that authorised trust lines do not allow payments "
|
||||
"from unauthorised counter-parties");
|
||||
|
||||
using namespace jtx;
|
||||
Env env{*this};
|
||||
|
||||
auto const bob = Account{"bob"};
|
||||
auto const alice = Account{"alice"};
|
||||
env.fund(XRP(10000), bob, alice);
|
||||
|
||||
// alice wants to ensure that all holders of her tokens are authorised
|
||||
env(fset(alice, asfRequireAuth));
|
||||
env.close();
|
||||
|
||||
// create a trust line from bob to alice. bob wants to hold at most
|
||||
// 100 of alice's USD tokens. Note: alice hasn't authorised this
|
||||
// trust line yet.
|
||||
env(trust(bob, alice["USD"](100)));
|
||||
env.close();
|
||||
|
||||
// send a payment from alice to bob, validate that the payment fails
|
||||
env(pay(alice, bob, alice["USD"](10)), ter(tecPATH_DRY));
|
||||
env.close();
|
||||
}
|
||||
|
||||
void
|
||||
testTrustLineLimitsWithRippling()
|
||||
{
|
||||
testcase(
|
||||
"Check that trust line limits are respected in conjunction "
|
||||
"with rippling feature");
|
||||
|
||||
using namespace jtx;
|
||||
Env env{*this};
|
||||
|
||||
auto const bob = Account{"bob"};
|
||||
auto const alice = Account{"alice"};
|
||||
env.fund(XRP(10000), bob, alice);
|
||||
|
||||
// create a trust line from bob to alice. bob wants to hold at most
|
||||
// 100 of alice's USD tokens.
|
||||
env(trust(bob, alice["USD"](100)));
|
||||
env.close();
|
||||
|
||||
// archetypical payment transaction from alice to bob must succeed
|
||||
env(pay(alice, bob, alice["USD"](20)), ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
// Issued tokens are fungible. i.e. alice's USD is identical to bob's
|
||||
// USD
|
||||
env(pay(bob, alice, bob["USD"](10)), ter(tesSUCCESS));
|
||||
env.close();
|
||||
|
||||
// bob cannot place alice in his debt i.e. alice's balance of the USD
|
||||
// tokens cannot go below zero.
|
||||
env(pay(bob, alice, bob["USD"](11)), ter(tecPATH_PARTIAL));
|
||||
env.close();
|
||||
|
||||
// payments that respect the trust line limits of alice should succeed
|
||||
env(pay(bob, alice, bob["USD"](10)), ter(tesSUCCESS));
|
||||
env.close();
|
||||
}
|
||||
|
||||
void
|
||||
testModifyQualityOfTrustline(
|
||||
FeatureBitset features,
|
||||
@@ -402,6 +634,11 @@ public:
|
||||
testModifyQualityOfTrustline(features, true, false);
|
||||
testModifyQualityOfTrustline(features, true, true);
|
||||
testDisallowIncoming(features);
|
||||
testTrustLineResetWithAuthFlag();
|
||||
testTrustLineDelete();
|
||||
testExceedTrustLineLimit();
|
||||
testAuthFlagTrustLines();
|
||||
testTrustLineLimitsWithRippling();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -39,6 +39,10 @@ trust(Account const& account, STAmount const& amount, std::uint32_t flags)
|
||||
return jv;
|
||||
}
|
||||
|
||||
// This function overload is especially useful for modelling Authorised trust
|
||||
// lines. account (first function parameter) is the issuing authority, it
|
||||
// authorises peer (third function parameter) to hold a certain currency
|
||||
// (amount, the second function parameter)
|
||||
Json::Value
|
||||
trust(
|
||||
Account const& account,
|
||||
|
||||
Reference in New Issue
Block a user