20 #include <ripple/protocol/Feature.h>
21 #include <ripple/protocol/jss.h>
24 #include <ripple/resource/Charge.h>
25 #include <ripple/resource/Fees.h>
26 #include <ripple/rpc/GRPCHandlers.h>
27 #include <test/jtx/WSClient.h>
28 #include <test/rpc/GRPCTestClientBase.h>
43 auto const info = env.
rpc(
"json",
"account_info",
"{ }");
45 info[jss::result][jss::error_message] ==
46 "Missing field 'account'.");
50 auto const info = env.
rpc(
54 "\"n94JNrQYkDrpt62bbSR7nVEhdyAvcJXRAsjEkFYyqRkh9SUTYEqV\"}");
58 info[jss::result][jss::error_message] ==
"Account malformed.");
63 auto const info = env.
rpc(
66 R
"({ "account": ")" + bogie.human() + R"("})");
70 info[jss::result][jss::error_message] == "Account not found.");
75 env.
rpc(
"json",
"account_info", R
"({"account": "foo"})");
79 info[jss::result][jss::error_message] == "Account malformed.");
90 env.fund(XRP(1000), alice);
92 auto const withoutSigners =
93 std::string(
"{ ") +
"\"account\": \"" + alice.human() +
"\"}";
95 auto const withSigners =
std::string(
"{ ") +
"\"account\": \"" +
96 alice.human() +
"\", " +
"\"signer_lists\": true }";
101 auto const info = env.rpc(
"json",
"account_info", withoutSigners);
103 info.isMember(jss::result) &&
104 info[jss::result].isMember(jss::account_data));
105 BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
110 auto const info = env.rpc(
"json",
"account_info", withSigners);
112 info.isMember(jss::result) &&
113 info[jss::result].isMember(jss::account_data));
114 auto const& data = info[jss::result][jss::account_data];
115 BEAST_EXPECT(data.isMember(jss::signer_lists));
116 auto const& signerLists = data[jss::signer_lists];
117 BEAST_EXPECT(signerLists.isArray());
118 BEAST_EXPECT(signerLists.size() == 0);
122 Account
const bogie{
"bogie"};
128 auto const info = env.rpc(
"json",
"account_info", withoutSigners);
130 info.isMember(jss::result) &&
131 info[jss::result].isMember(jss::account_data));
132 BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
137 auto const info = env.rpc(
"json",
"account_info", withSigners);
139 info.isMember(jss::result) &&
140 info[jss::result].isMember(jss::account_data));
141 auto const&
data = info[jss::result][jss::account_data];
142 BEAST_EXPECT(
data.isMember(jss::signer_lists));
143 auto const& signerLists =
data[jss::signer_lists];
144 BEAST_EXPECT(signerLists.isArray());
145 BEAST_EXPECT(signerLists.size() == 1);
146 auto const&
signers = signerLists[0u];
147 BEAST_EXPECT(
signers.isObject());
150 BEAST_EXPECT(signerEntries.size() == 1);
156 Account
const demon{
"demon"};
157 Account
const ghost{
"ghost"};
158 Account
const haunt{
"haunt"};
159 Account
const jinni{
"jinni"};
160 Account
const phase{
"phase"};
161 Account
const shade{
"shade"};
162 Account
const spook{
"spook"};
180 auto const info = env.rpc(
"json",
"account_info", withSigners);
182 info.isMember(jss::result) &&
183 info[jss::result].isMember(jss::account_data));
184 auto const&
data = info[jss::result][jss::account_data];
185 BEAST_EXPECT(
data.isMember(jss::signer_lists));
186 auto const& signerLists =
data[jss::signer_lists];
187 BEAST_EXPECT(signerLists.isArray());
188 BEAST_EXPECT(signerLists.size() == 1);
189 auto const&
signers = signerLists[0u];
190 BEAST_EXPECT(
signers.isObject());
193 BEAST_EXPECT(signerEntries.size() == 8);
194 for (
unsigned i = 0u; i < 8; ++i)
197 BEAST_EXPECT(entry.size() == 2);
206 testSignerListsApiVersion2()
210 Account
const alice{
"alice"};
211 env.fund(
XRP(1000), alice);
214 "\"api_version\": 2, \"account\": \"" + alice.human() +
"\"}";
217 "\"api_version\": 2, \"account\": \"" + alice.human() +
"\", " +
218 "\"signer_lists\": true }";
220 auto const withSignersAsString =
std::string(
"{ ") +
221 "\"api_version\": 2, \"account\": \"" + alice.human() +
"\", " +
222 "\"signer_lists\": asdfggh }";
227 auto const info = env.rpc(
"json",
"account_info", withoutSigners);
228 BEAST_EXPECT(info.isMember(jss::result));
229 BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
233 auto const info = env.rpc(
"json",
"account_info", withSigners);
234 BEAST_EXPECT(info.isMember(jss::result));
235 auto const&
data = info[jss::result];
236 BEAST_EXPECT(
data.isMember(jss::signer_lists));
237 auto const& signerLists =
data[jss::signer_lists];
238 BEAST_EXPECT(signerLists.isArray());
239 BEAST_EXPECT(signerLists.size() == 0);
243 Account
const bogie{
"bogie"};
249 auto const info = env.rpc(
"json",
"account_info", withoutSigners);
250 BEAST_EXPECT(info.isMember(jss::result));
251 BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
255 auto const info = env.rpc(
"json",
"account_info", withSigners);
256 BEAST_EXPECT(info.isMember(jss::result));
257 auto const&
data = info[jss::result];
258 BEAST_EXPECT(
data.isMember(jss::signer_lists));
259 auto const& signerLists =
data[jss::signer_lists];
260 BEAST_EXPECT(signerLists.isArray());
261 BEAST_EXPECT(signerLists.size() == 1);
262 auto const&
signers = signerLists[0u];
263 BEAST_EXPECT(
signers.isObject());
266 BEAST_EXPECT(signerEntries.size() == 1);
273 env.rpc(
"json",
"account_info", withSignersAsString);
274 BEAST_EXPECT(info[jss::status] ==
"error");
275 BEAST_EXPECT(info[jss::error] ==
"invalidParams");
279 Account
const demon{
"demon"};
280 Account
const ghost{
"ghost"};
281 Account
const haunt{
"haunt"};
282 Account
const jinni{
"jinni"};
283 Account
const phase{
"phase"};
284 Account
const shade{
"shade"};
285 Account
const spook{
"spook"};
303 auto const info = env.rpc(
"json",
"account_info", withSigners);
304 BEAST_EXPECT(info.isMember(jss::result));
305 auto const&
data = info[jss::result];
306 BEAST_EXPECT(
data.isMember(jss::signer_lists));
307 auto const& signerLists =
data[jss::signer_lists];
308 BEAST_EXPECT(signerLists.isArray());
309 BEAST_EXPECT(signerLists.size() == 1);
310 auto const&
signers = signerLists[0u];
311 BEAST_EXPECT(
signers.isObject());
314 BEAST_EXPECT(signerEntries.size() == 8);
315 for (
unsigned i = 0u; i < 8; ++i)
318 BEAST_EXPECT(entry.size() == 2);
331 Account
const alice{
"alice"};
332 env.fund(
XRP(1000), alice);
335 "\"jsonrpc\": \"2.0\", "
336 "\"ripplerpc\": \"2.0\", "
338 "\"method\": \"account_info\", "
341 alice.human() +
"\"}}";
344 "\"jsonrpc\": \"2.0\", "
345 "\"ripplerpc\": \"2.0\", "
347 "\"method\": \"account_info\", "
350 alice.human() +
"\", " +
"\"signer_lists\": true }}";
354 auto const info = env.rpc(
"json2", withoutSigners);
356 info.isMember(jss::result) &&
357 info[jss::result].isMember(jss::account_data));
358 BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
361 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
363 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
364 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 5);
368 auto const info = env.rpc(
"json2", withSigners);
370 info.isMember(jss::result) &&
371 info[jss::result].isMember(jss::account_data));
372 auto const&
data = info[jss::result][jss::account_data];
373 BEAST_EXPECT(
data.isMember(jss::signer_lists));
374 auto const& signerLists =
data[jss::signer_lists];
375 BEAST_EXPECT(signerLists.isArray());
376 BEAST_EXPECT(signerLists.size() == 0);
378 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
380 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
381 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
385 auto const info = env.rpc(
386 "json2",
'[' + withoutSigners +
", " + withSigners +
']');
388 info[0u].isMember(jss::result) &&
389 info[0u][jss::result].isMember(jss::account_data));
390 BEAST_EXPECT(!info[0u][jss::result][jss::account_data].isMember(
393 info[0u].isMember(jss::jsonrpc) &&
394 info[0u][jss::jsonrpc] ==
"2.0");
396 info[0u].isMember(jss::ripplerpc) &&
397 info[0u][jss::ripplerpc] ==
"2.0");
398 BEAST_EXPECT(info[0u].isMember(jss::id) && info[0u][jss::id] == 5);
401 info[1u].isMember(jss::result) &&
402 info[1u][jss::result].isMember(jss::account_data));
403 auto const&
data = info[1u][jss::result][jss::account_data];
404 BEAST_EXPECT(
data.isMember(jss::signer_lists));
405 auto const& signerLists =
data[jss::signer_lists];
406 BEAST_EXPECT(signerLists.isArray());
407 BEAST_EXPECT(signerLists.size() == 0);
409 info[1u].isMember(jss::jsonrpc) &&
410 info[1u][jss::jsonrpc] ==
"2.0");
412 info[1u].isMember(jss::ripplerpc) &&
413 info[1u][jss::ripplerpc] ==
"2.0");
414 BEAST_EXPECT(info[1u].isMember(jss::id) && info[1u][jss::id] == 6);
418 Account
const bogie{
"bogie"};
424 auto const info = env.rpc(
"json2", withoutSigners);
426 info.isMember(jss::result) &&
427 info[jss::result].isMember(jss::account_data));
428 BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
431 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
433 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
434 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 5);
438 auto const info = env.rpc(
"json2", withSigners);
440 info.isMember(jss::result) &&
441 info[jss::result].isMember(jss::account_data));
442 auto const&
data = info[jss::result][jss::account_data];
443 BEAST_EXPECT(
data.isMember(jss::signer_lists));
444 auto const& signerLists =
data[jss::signer_lists];
445 BEAST_EXPECT(signerLists.isArray());
446 BEAST_EXPECT(signerLists.size() == 1);
447 auto const&
signers = signerLists[0u];
448 BEAST_EXPECT(
signers.isObject());
451 BEAST_EXPECT(signerEntries.size() == 1);
455 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
457 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
458 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
462 Account
const demon{
"demon"};
463 Account
const ghost{
"ghost"};
464 Account
const haunt{
"haunt"};
465 Account
const jinni{
"jinni"};
466 Account
const phase{
"phase"};
467 Account
const shade{
"shade"};
468 Account
const spook{
"spook"};
486 auto const info = env.rpc(
"json2", withSigners);
488 info.isMember(jss::result) &&
489 info[jss::result].isMember(jss::account_data));
490 auto const&
data = info[jss::result][jss::account_data];
491 BEAST_EXPECT(
data.isMember(jss::signer_lists));
492 auto const& signerLists =
data[jss::signer_lists];
493 BEAST_EXPECT(signerLists.isArray());
494 BEAST_EXPECT(signerLists.size() == 1);
495 auto const&
signers = signerLists[0u];
496 BEAST_EXPECT(
signers.isObject());
499 BEAST_EXPECT(signerEntries.size() == 8);
500 for (
unsigned i = 0u; i < 8; ++i)
503 BEAST_EXPECT(entry.size() == 2);
508 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
510 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
511 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
516 testAccountFlags(FeatureBitset
const& features)
520 Env env(*
this, features);
521 Account
const alice{
"alice"};
522 Account
const bob{
"bob"};
523 env.fund(
XRP(1000), alice, bob);
525 auto getAccountFlag = [&env](
527 Account
const& account) {
528 auto const info = env.rpc(
531 R
"({"account" : ")" + account.human() + R"("})");
534 if (info[jss::result][jss::status] ==
"success" &&
535 info[jss::result][jss::account_flags].isMember(fName.
data()))
536 res.
emplace(info[jss::result][jss::account_flags][fName.
data()]
542 static constexpr std::
543 array<std::pair<std::string_view, std::uint32_t>, 7>
553 for (
auto& asf : asFlags)
557 env(
fclear(alice, asf.second));
559 auto const f1 = getAccountFlag(asf.first, alice);
560 BEAST_EXPECT(f1.has_value());
561 BEAST_EXPECT(!f1.value());
565 env(
fset(alice, asf.second));
567 auto const f2 = getAccountFlag(asf.first, alice);
568 BEAST_EXPECT(f2.has_value());
569 BEAST_EXPECT(f2.value());
572 static constexpr std::
573 array<std::pair<std::string_view, std::uint32_t>, 4>
574 disallowIncomingFlags{
576 {
"disallowIncomingNFTokenOffer",
579 {
"disallowIncomingTrustline",
584 for (
auto& asf : disallowIncomingFlags)
588 env(
fclear(alice, asf.second));
590 auto const f1 = getAccountFlag(asf.first, alice);
591 BEAST_EXPECT(f1.has_value());
592 BEAST_EXPECT(!f1.value());
596 env(
fset(alice, asf.second));
598 auto const f2 = getAccountFlag(asf.first, alice);
599 BEAST_EXPECT(f2.has_value());
600 BEAST_EXPECT(f2.value());
605 for (
auto& asf : disallowIncomingFlags)
607 BEAST_EXPECT(!getAccountFlag(asf.first, alice));
612 allowTrustLineClawbackFlag{
619 getAccountFlag(allowTrustLineClawbackFlag.first, bob);
620 BEAST_EXPECT(f1.has_value());
621 BEAST_EXPECT(!f1.value());
624 env(
fset(bob, allowTrustLineClawbackFlag.second));
627 getAccountFlag(allowTrustLineClawbackFlag.first, bob);
628 BEAST_EXPECT(f2.has_value());
629 BEAST_EXPECT(f2.value());
634 !getAccountFlag(allowTrustLineClawbackFlag.first, bob));
643 testSignerListsApiVersion2();
646 FeatureBitset
const allFeatures{
648 testAccountFlags(allFeatures);