21#include <test/jtx/envconfig.h>
22#include <xrpld/app/misc/TxQ.h>
23#include <xrpld/rpc/detail/Tuning.h>
24#include <xrpl/beast/utility/temp_dir.h>
25#include <xrpl/protocol/Feature.h>
26#include <xrpl/protocol/jss.h>
27#include <xrpl/resource/ResourceManager.h>
28#include <xrpl/resource/detail/Entry.h>
29#include <xrpl/resource/detail/Tuning.h>
30#include <boost/algorithm/string/predicate.hpp>
39 testcase(
"Bad input to noripple_check");
41 using namespace test::jtx;
44 auto const alice = Account{
"alice"};
45 env.fund(XRP(10000), alice);
50 env.rpc(
"json",
"noripple_check",
"{}")[jss::result];
51 BEAST_EXPECT(result[jss::error] ==
"invalidParams");
53 result[jss::error_message] ==
"Missing field 'account'.");
58 params[jss::account] = alice.human();
59 auto const result = env.rpc(
62 boost::lexical_cast<std::string>(params))[jss::result];
63 BEAST_EXPECT(result[jss::error] ==
"invalidParams");
64 BEAST_EXPECT(result[jss::error_message] ==
"Missing field 'role'.");
69 auto testInvalidAccountParam = [&](
auto const& param) {
71 params[jss::account] = param;
72 params[jss::role] =
"user";
74 "json",
"noripple_check",
to_string(params))[jss::result];
75 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
77 jrr[jss::error_message] ==
"Invalid field 'account'.");
80 testInvalidAccountParam(1);
81 testInvalidAccountParam(1.1);
82 testInvalidAccountParam(
true);
90 params[jss::account] = alice.human();
91 params[jss::role] =
"not_a_role";
92 auto const result = env.rpc(
95 boost::lexical_cast<std::string>(params))[jss::result];
96 BEAST_EXPECT(result[jss::error] ==
"invalidParams");
97 BEAST_EXPECT(result[jss::error_message] ==
"Invalid field 'role'.");
102 params[jss::account] = alice.human();
103 params[jss::role] =
"user";
104 params[jss::limit] = -1;
105 auto const result = env.rpc(
108 boost::lexical_cast<std::string>(params))[jss::result];
109 BEAST_EXPECT(result[jss::error] ==
"invalidParams");
111 result[jss::error_message] ==
112 "Invalid field 'limit', not unsigned integer.");
117 params[jss::account] = alice.human();
118 params[jss::role] =
"user";
119 params[jss::ledger_hash] = 1;
120 auto const result = env.rpc(
123 boost::lexical_cast<std::string>(params))[jss::result];
124 BEAST_EXPECT(result[jss::error] ==
"invalidParams");
125 BEAST_EXPECT(result[jss::error_message] ==
"ledgerHashNotString");
130 params[jss::account] = Account{
"nobody"}.human();
131 params[jss::role] =
"user";
132 params[jss::ledger] =
"current";
133 auto const result = env.rpc(
136 boost::lexical_cast<std::string>(params))[jss::result];
137 BEAST_EXPECT(result[jss::error] ==
"actNotFound");
138 BEAST_EXPECT(result[jss::error_message] ==
"Account not found.");
145 params[jss::role] =
"user";
146 params[jss::ledger] =
"current";
147 auto const result = env.rpc(
150 boost::lexical_cast<std::string>(params))[jss::result];
151 BEAST_EXPECT(result[jss::error] ==
"actMalformed");
152 BEAST_EXPECT(result[jss::error_message] ==
"Account malformed.");
159 testcase <<
"Request noripple_check for " << (user ?
"user" :
"gateway")
160 <<
" role, expect" << (problems ?
"" :
" no") <<
" problems";
162 using namespace test::jtx;
165 auto const gw = Account{
"gw"};
166 auto const alice = Account{
"alice"};
168 env.fund(XRP(10000), gw, alice);
169 if ((user && problems) || (!user && !problems))
172 env(trust(alice, gw[
"USD"](100)));
182 params[jss::account] = alice.human();
183 params[jss::role] = (user ?
"user" :
"gateway");
184 params[jss::ledger] =
"current";
185 auto result = env.rpc(
188 boost::lexical_cast<std::string>(params))[jss::result];
190 auto const pa = result[
"problems"];
191 if (!BEAST_EXPECT(pa.isArray()))
196 if (!BEAST_EXPECT(pa.size() == 2))
201 BEAST_EXPECT(boost::starts_with(
202 pa[0u].asString(),
"You appear to have set"));
203 BEAST_EXPECT(boost::starts_with(
204 pa[1u].asString(),
"You should probably set"));
208 BEAST_EXPECT(boost::starts_with(
209 pa[0u].asString(),
"You should immediately set"));
211 boost::starts_with(pa[1u].asString(),
"You should clear"));
216 BEAST_EXPECT(pa.size() == 0);
221 params[jss::transactions] =
true;
225 boost::lexical_cast<std::string>(params))[jss::result];
226 if (!BEAST_EXPECT(result[jss::transactions].isArray()))
229 auto const txs = result[jss::transactions];
232 if (!BEAST_EXPECT(txs.size() == (user ? 1 : 2)))
237 BEAST_EXPECT(txs[0u][jss::Account] == alice.human());
238 BEAST_EXPECT(txs[0u][jss::TransactionType] == jss::AccountSet);
242 result[jss::transactions][txs.size() - 1][jss::Account] ==
245 result[jss::transactions][txs.size() - 1]
246 [jss::TransactionType] == jss::TrustSet);
248 result[jss::transactions][txs.size() - 1][jss::LimitAmount] ==
253 BEAST_EXPECT(txs.size() == 0);
262 for (
auto user : {
true,
false})
263 for (
auto problem : {
true,
false})
273 testcase <<
"Check limits in returned data, "
274 << (admin ?
"admin" :
"non-admin");
276 using namespace test::jtx;
278 Env env{*
this, admin ? envconfig() : envconfig(no_admin)};
280 auto const alice = Account{
"alice"};
281 env.fund(XRP(100000), alice);
285 auto checkBalance = [&env]() {
296 auto c = env.app().getResourceManager().newInboundEndpoint(
300 if (c.balance() > warningThreshold)
303 c.entry().local_balance =
313 auto& txq = env.app().getTxQ();
316 auto const baseFee = env.current()->fees().base;
317 env(pay(env.master, gw, XRP(1000)),
320 txq.getMetrics(*env.current()).openLedgerFeeLevel,
327 txq.getMetrics(*env.current()).openLedgerFeeLevel,
331 env(trust(alice, gw[
"USD"](10)),
333 txq.getMetrics(*env.current()).openLedgerFeeLevel,
341 params[jss::account] = alice.human();
342 params[jss::role] =
"user";
343 params[jss::ledger] =
"current";
344 auto result = env.rpc(
347 boost::lexical_cast<std::string>(params))[jss::result];
349 BEAST_EXPECT(result[
"problems"].size() == 301);
352 params[jss::limit] = 9;
356 boost::lexical_cast<std::string>(params))[jss::result];
357 BEAST_EXPECT(result[
"problems"].size() == (admin ? 10 : 11));
360 params[jss::limit] = 10;
364 boost::lexical_cast<std::string>(params))[jss::result];
365 BEAST_EXPECT(result[
"problems"].size() == 11);
368 params[jss::limit] = 400;
372 boost::lexical_cast<std::string>(params))[jss::result];
373 BEAST_EXPECT(result[
"problems"].size() == 401);
376 params[jss::limit] = 401;
380 boost::lexical_cast<std::string>(params))[jss::result];
381 BEAST_EXPECT(result[
"problems"].size() == (admin ? 402 : 401));
388 for (
auto admin : {
true,
false})
393BEAST_DEFINE_TESTSUITE(NoRippleCheck, rpc,
ripple);
399BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(NoRippleCheckLimits, rpc,
ripple, 1);
Abstract interface to a clock.
testcase_t testcase
Memberspace for declaring test cases.
Sampling function using exponential decay to provide a continuous value.
void testLimits(bool admin)
void run() override
Runs the suite.
void run() override
Runs the suite.
void testBasic(bool user, bool problems)
@ arrayValue
array value (ordered list)
@ objectValue
object value (collection of name/value pairs).
static LimitRange constexpr noRippleCheck
Limits for the no_ripple_check command.
const char * getEnvLocalhostAddr()
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
constexpr std::uint32_t asfDefaultRipple
std::string to_string(base_uint< Bits, Tag > const &a)
XRPAmount toDrops(FeeLevel< T > const &level, XRPAmount baseFee)
constexpr std::uint32_t tfSetNoRipple