2#include <test/jtx/Account.h>
3#include <test/jtx/Env.h>
4#include <test/jtx/TestHelpers.h>
5#include <test/jtx/amount.h>
6#include <test/jtx/balance.h>
7#include <test/jtx/flags.h>
8#include <test/jtx/paths.h>
9#include <test/jtx/pay.h>
10#include <test/jtx/ter.h>
11#include <test/jtx/trust.h>
13#include <xrpl/beast/unit_test/suite.h>
14#include <xrpl/json/json_value.h>
15#include <xrpl/json/to_string.h>
16#include <xrpl/protocol/ApiVersion.h>
17#include <xrpl/protocol/Feature.h>
18#include <xrpl/protocol/TER.h>
19#include <xrpl/protocol/TxFlags.h>
20#include <xrpl/protocol/jss.h>
37 auto const gw =
Account(
"gateway");
38 auto const alice =
Account(
"alice");
40 env.
fund(
XRP(10000), gw, alice);
42 auto const usd = gw[
"USD"];
45 accountGw[jss::account] = gw.human();
47 accountAlice[jss::account] = alice.human();
49 for (
auto setOrClear : {
true,
false})
52 env(
trust(gw, usd(100), alice, setOrClear ? tfSetNoRipple : tfClearNoRipple));
57 auto const& gwLine0 =
lines[jss::result][jss::lines][0u];
58 BEAST_EXPECT(gwLine0[jss::no_ripple].asBool() == setOrClear);
62 auto const& aline0 =
lines[jss::result][jss::lines][0u];
63 BEAST_EXPECT(aline0[jss::no_ripple_peer].asBool() == setOrClear);
70 testcase(
"Set noripple on a line with negative balance");
73 auto const gw =
Account(
"gateway");
74 auto const alice =
Account(
"alice");
75 auto const bob =
Account(
"bob");
76 auto const carol =
Account(
"carol");
78 Env env(*
this, features);
80 env.
fund(
XRP(10000), gw, alice, bob, carol);
83 env.
trust(alice[
"USD"](100), bob);
84 env.
trust(bob[
"USD"](100), carol);
90 env(
pay(alice, carol, carol[
"USD"](50)),
Path(bob));
95 env(
trust(alice, bob[
"USD"](100), bob, tfSetNoRipple),
Ter(terNeg));
96 env(
trust(bob, carol[
"USD"](100), carol, tfSetNoRipple),
Ter(terNeg));
100 params[jss::source_account] = alice.human();
101 params[jss::destination_account] = carol.human();
102 params[jss::destination_amount] = [] {
104 destAmt[jss::currency] =
"USD";
105 destAmt[jss::value] =
"1";
106 destAmt[jss::issuer] =
Account(
"carol").human();
110 auto const resp = env.
rpc(
"json",
"ripple_path_find",
to_string(params));
111 BEAST_EXPECT(resp[jss::result][jss::alternatives].size() == 1);
115 return r[jss::lines];
119 BEAST_EXPECT(aliceLines.size() == 1);
120 BEAST_EXPECT(aliceLines[0u][jss::no_ripple].asBool() ==
false);
123 BEAST_EXPECT(bobLines.size() == 2);
124 BEAST_EXPECT(bobLines[0u][jss::no_ripple].asBool() ==
false);
125 BEAST_EXPECT(bobLines[1u][jss::no_ripple].asBool() ==
false);
130 env(
pay(carol, alice, alice[
"USD"](50)),
Path(bob));
133 env(
trust(alice, bob[
"USD"](100), bob, tfSetNoRipple));
134 env(
trust(bob, carol[
"USD"](100), carol, tfSetNoRipple));
138 BEAST_EXPECT(aliceLines.size() == 1);
139 BEAST_EXPECT(aliceLines[0u].isMember(jss::no_ripple));
142 BEAST_EXPECT(bobLines.size() == 2);
143 BEAST_EXPECT(bobLines[0u].isMember(jss::no_ripple_peer));
144 BEAST_EXPECT(bobLines[1u].isMember(jss::no_ripple));
154 Env env(*
this, features);
156 auto const alice =
Account(
"alice");
157 auto const bob =
Account(
"bob");
158 auto const carol =
Account(
"carol");
160 env.
fund(
XRP(10000), alice, bob, carol);
162 env(
trust(bob, alice[
"USD"](100)));
163 env(
trust(carol, bob[
"USD"](100)));
165 env(
trust(bob, alice[
"USD"](100), alice, tfSetNoRipple));
166 env(
trust(bob, carol[
"USD"](100), carol, tfSetNoRipple));
170 params[jss::source_account] = alice.human();
171 params[jss::destination_account] = carol.human();
172 params[jss::destination_amount] = [] {
174 destAmt[jss::currency] =
"USD";
175 destAmt[jss::value] =
"1";
176 destAmt[jss::issuer] =
Account(
"carol").human();
181 BEAST_EXPECT(resp[jss::result][jss::alternatives].size() == 0);
190 "Set default ripple on an account and check new trustlines "
195 Env env(*
this, features);
197 auto const gw =
Account(
"gateway");
198 auto const alice =
Account(
"alice");
199 auto const bob =
Account(
"bob");
203 env(
fset(bob, asfDefaultRipple));
205 auto const usd = gw[
"USD"];
207 env(
trust(gw, usd(100), alice, 0));
208 env(
trust(gw, usd(100), bob, 0));
210 params[jss::api_version] = apiVersion;
213 params[jss::account] = gw.human();
214 params[jss::peer] = alice.human();
217 auto const& line0 =
lines[jss::result][jss::lines][0u];
218 BEAST_EXPECT(line0[jss::no_ripple_peer].asBool() ==
true);
221 params[jss::account] = alice.human();
222 params[jss::peer] = gw.human();
225 auto const& line0 =
lines[jss::result][jss::lines][0u];
226 BEAST_EXPECT(line0[jss::no_ripple].asBool() ==
true);
229 params[jss::account] = gw.human();
230 params[jss::peer] = bob.human();
233 auto const& line0 =
lines[jss::result][jss::lines][0u];
234 BEAST_EXPECT(line0[jss::no_ripple].asBool() ==
false);
237 params[jss::account] = bob.human();
238 params[jss::peer] = gw.human();
241 auto const& line0 =
lines[jss::result][jss::lines][0u];
242 BEAST_EXPECT(line0[jss::no_ripple_peer].asBool() ==
false);
247 params[jss::account] = bob.human();
248 params[jss::role] =
"gateway";
249 params[jss::transactions] =
"asdf";
254 BEAST_EXPECT(
lines[jss::result][jss::status] ==
"success");
258 BEAST_EXPECT(
lines[jss::result][jss::error] ==
"invalidParams");
277 withFeatsTests(sa - featurePermissionedDEX);
TestcaseT testcase
Memberspace for declaring test cases.
void testPairwise(FeatureBitset features)
void run() override
Runs the suite.
void testDefaultRipple(FeatureBitset features, unsigned int apiVersion)
void testNegativeBalance(FeatureBitset features)
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.
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 trust(STAmount const &amount, Account const &account)
Establish trust lines.
Set the expected result code for a JTx The test will fail if the code doesn't match.
json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
XrpT const XRP
Converts to XRP Issue or STAmount.
OwnerCount< ltRIPPLE_STATE > lines
Match the number of trust lines in the account's owner directory.
FeatureBitset testableAmendments()
std::array< Account, 1+sizeof...(Args)> noripple(Account const &account, Args const &... args)
Designate accounts as no-ripple in Env::fund.
json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
json::Value getAccountLines(Env &env, AccountID const &acctId)
json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
BEAST_DEFINE_TESTSUITE(AMMClawback, app, xrpl)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string to_string(BaseUInt< Bits, Tag > const &a)
void forAllApiVersions(Fn const &fn, Args &&... args)
TERSubset< CanCvtToTER > TER