41 auto const info = env.
rpc(
"json",
"account_info",
"{ }");
43 info[jss::result][jss::error_message] ==
44 "Missing field 'account'.");
48 auto const info = env.
rpc(
52 "\"n94JNrQYkDrpt62bbSR7nVEhdyAvcJXRAsjEkFYyqRkh9SUTYEqV\"}");
56 info[jss::result][jss::error_message] ==
"Account malformed.");
61 auto const info = env.
rpc(
64 R
"({ "account": ")" + bogie.human() + R"("})");
68 info[jss::result][jss::error_message] == "Account not found.");
73 env.
rpc(
"json",
"account_info", R
"({"account": "foo"})");
77 info[jss::result][jss::error_message] == "Account malformed.");
82 auto testInvalidAccountParam = [&](
auto const& param) {
84 params[jss::account] = param;
86 "json",
"account_info",
to_string(params))[jss::result];
87 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
89 jrr[jss::error_message] ==
"Invalid field 'account'.");
92 testInvalidAccountParam(1);
93 testInvalidAccountParam(1.1);
94 testInvalidAccountParam(
true);
102 auto testInvalidIdentParam = [&](
auto const& param) {
104 params[jss::ident] = param;
106 "json",
"account_info",
to_string(params))[jss::result];
107 BEAST_EXPECT(jrr[jss::error] ==
"invalidParams");
109 jrr[jss::error_message] ==
"Invalid field 'ident'.");
112 testInvalidIdentParam(1);
113 testInvalidIdentParam(1.1);
114 testInvalidIdentParam(
true);
129 env.fund(
XRP(1000), alice);
131 auto const withoutSigners =
132 std::string(
"{ ") +
"\"account\": \"" + alice.human() +
"\"}";
134 auto const withSigners =
std::string(
"{ ") +
"\"account\": \"" +
135 alice.human() +
"\", " +
"\"signer_lists\": true }";
140 auto const info = env.rpc(
"json",
"account_info", withoutSigners);
142 info.isMember(jss::result) &&
143 info[jss::result].isMember(jss::account_data));
144 BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
149 auto const info = env.rpc(
"json",
"account_info", withSigners);
151 info.isMember(jss::result) &&
152 info[jss::result].isMember(jss::account_data));
153 auto const&
data = info[jss::result][jss::account_data];
154 BEAST_EXPECT(
data.isMember(jss::signer_lists));
155 auto const& signerLists =
data[jss::signer_lists];
156 BEAST_EXPECT(signerLists.isArray());
157 BEAST_EXPECT(signerLists.size() == 0);
161 Account
const bogie{
"bogie"};
167 auto const info = env.rpc(
"json",
"account_info", withoutSigners);
169 info.isMember(jss::result) &&
170 info[jss::result].isMember(jss::account_data));
171 BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
176 auto const info = env.rpc(
"json",
"account_info", withSigners);
178 info.isMember(jss::result) &&
179 info[jss::result].isMember(jss::account_data));
180 auto const&
data = info[jss::result][jss::account_data];
181 BEAST_EXPECT(
data.isMember(jss::signer_lists));
182 auto const& signerLists =
data[jss::signer_lists];
183 BEAST_EXPECT(signerLists.isArray());
184 BEAST_EXPECT(signerLists.size() == 1);
185 auto const&
signers = signerLists[0u];
187 BEAST_EXPECT(
signers[sfSignerQuorum.jsonName] == 2);
188 auto const& signerEntries =
signers[sfSignerEntries.jsonName];
189 BEAST_EXPECT(signerEntries.size() == 1);
190 auto const& entry0 = signerEntries[0u][sfSignerEntry.jsonName];
191 BEAST_EXPECT(entry0[sfSignerWeight.jsonName] == 3);
195 Account
const demon{
"demon"};
196 Account
const ghost{
"ghost"};
197 Account
const haunt{
"haunt"};
198 Account
const jinni{
"jinni"};
199 Account
const phase{
"phase"};
200 Account
const shade{
"shade"};
201 Account
const spook{
"spook"};
219 auto const info = env.rpc(
"json",
"account_info", withSigners);
221 info.isMember(jss::result) &&
222 info[jss::result].isMember(jss::account_data));
223 auto const&
data = info[jss::result][jss::account_data];
224 BEAST_EXPECT(
data.isMember(jss::signer_lists));
225 auto const& signerLists =
data[jss::signer_lists];
226 BEAST_EXPECT(signerLists.isArray());
227 BEAST_EXPECT(signerLists.size() == 1);
228 auto const&
signers = signerLists[0u];
230 BEAST_EXPECT(
signers[sfSignerQuorum.jsonName] == 4);
231 auto const& signerEntries =
signers[sfSignerEntries.jsonName];
232 BEAST_EXPECT(signerEntries.size() == 8);
233 for (
unsigned i = 0u; i < 8; ++i)
235 auto const&
entry = signerEntries[i][sfSignerEntry.jsonName];
238 BEAST_EXPECT(entry[sfSignerWeight.jsonName] == 1);
245 testSignerListsApiVersion2()
250 Account
const alice{
"alice"};
251 env.fund(
XRP(1000), alice);
254 "\"api_version\": 2, \"account\": \"" + alice.human() +
"\"}";
257 "\"api_version\": 2, \"account\": \"" + alice.human() +
"\", " +
258 "\"signer_lists\": true }";
260 auto const withSignersAsString =
std::string(
"{ ") +
261 "\"api_version\": 2, \"account\": \"" + alice.human() +
"\", " +
262 "\"signer_lists\": asdfggh }";
267 auto const info = env.rpc(
"json",
"account_info", withoutSigners);
268 BEAST_EXPECT(info.isMember(jss::result));
269 BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
273 auto const info = env.rpc(
"json",
"account_info", withSigners);
274 BEAST_EXPECT(info.isMember(jss::result));
275 auto const&
data = info[jss::result];
276 BEAST_EXPECT(
data.isMember(jss::signer_lists));
277 auto const& signerLists =
data[jss::signer_lists];
278 BEAST_EXPECT(signerLists.isArray());
279 BEAST_EXPECT(signerLists.size() == 0);
283 Account
const bogie{
"bogie"};
289 auto const info = env.rpc(
"json",
"account_info", withoutSigners);
290 BEAST_EXPECT(info.isMember(jss::result));
291 BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
295 auto const info = env.rpc(
"json",
"account_info", withSigners);
296 BEAST_EXPECT(info.isMember(jss::result));
297 auto const&
data = info[jss::result];
298 BEAST_EXPECT(
data.isMember(jss::signer_lists));
299 auto const& signerLists =
data[jss::signer_lists];
300 BEAST_EXPECT(signerLists.isArray());
301 BEAST_EXPECT(signerLists.size() == 1);
302 auto const&
signers = signerLists[0u];
304 BEAST_EXPECT(
signers[sfSignerQuorum.jsonName] == 2);
305 auto const& signerEntries =
signers[sfSignerEntries.jsonName];
306 BEAST_EXPECT(signerEntries.size() == 1);
307 auto const& entry0 = signerEntries[0u][sfSignerEntry.jsonName];
308 BEAST_EXPECT(entry0[sfSignerWeight.jsonName] == 3);
313 env.rpc(
"json",
"account_info", withSignersAsString);
314 BEAST_EXPECT(info[jss::status] ==
"error");
315 BEAST_EXPECT(info[jss::error] ==
"invalidParams");
319 Account
const demon{
"demon"};
320 Account
const ghost{
"ghost"};
321 Account
const haunt{
"haunt"};
322 Account
const jinni{
"jinni"};
323 Account
const phase{
"phase"};
324 Account
const shade{
"shade"};
325 Account
const spook{
"spook"};
343 auto const info = env.rpc(
"json",
"account_info", withSigners);
344 BEAST_EXPECT(info.isMember(jss::result));
345 auto const&
data = info[jss::result];
346 BEAST_EXPECT(
data.isMember(jss::signer_lists));
347 auto const& signerLists =
data[jss::signer_lists];
348 BEAST_EXPECT(signerLists.isArray());
349 BEAST_EXPECT(signerLists.size() == 1);
350 auto const&
signers = signerLists[0u];
352 BEAST_EXPECT(
signers[sfSignerQuorum.jsonName] == 4);
353 auto const& signerEntries =
signers[sfSignerEntries.jsonName];
354 BEAST_EXPECT(signerEntries.size() == 8);
355 for (
unsigned i = 0u; i < 8; ++i)
357 auto const&
entry = signerEntries[i][sfSignerEntry.jsonName];
360 BEAST_EXPECT(entry[sfSignerWeight.jsonName] == 1);
372 Account
const alice{
"alice"};
373 env.fund(
XRP(1000), alice);
376 "\"jsonrpc\": \"2.0\", "
377 "\"ripplerpc\": \"2.0\", "
379 "\"method\": \"account_info\", "
382 alice.human() +
"\"}}";
385 "\"jsonrpc\": \"2.0\", "
386 "\"ripplerpc\": \"2.0\", "
388 "\"method\": \"account_info\", "
391 alice.human() +
"\", " +
"\"signer_lists\": true }}";
395 auto const info = env.rpc(
"json2", withoutSigners);
397 info.isMember(jss::result) &&
398 info[jss::result].isMember(jss::account_data));
399 BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
402 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
404 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
405 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 5);
409 auto const info = env.rpc(
"json2", withSigners);
411 info.isMember(jss::result) &&
412 info[jss::result].isMember(jss::account_data));
413 auto const&
data = info[jss::result][jss::account_data];
414 BEAST_EXPECT(
data.isMember(jss::signer_lists));
415 auto const& signerLists =
data[jss::signer_lists];
416 BEAST_EXPECT(signerLists.isArray());
417 BEAST_EXPECT(signerLists.size() == 0);
419 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
421 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
422 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
426 auto const info = env.rpc(
427 "json2",
'[' + withoutSigners +
", " + withSigners +
']');
429 info[0u].isMember(jss::result) &&
430 info[0u][jss::result].isMember(jss::account_data));
431 BEAST_EXPECT(!info[0u][jss::result][jss::account_data].isMember(
434 info[0u].isMember(jss::jsonrpc) &&
435 info[0u][jss::jsonrpc] ==
"2.0");
437 info[0u].isMember(jss::ripplerpc) &&
438 info[0u][jss::ripplerpc] ==
"2.0");
439 BEAST_EXPECT(info[0u].isMember(jss::id) && info[0u][jss::id] == 5);
442 info[1u].isMember(jss::result) &&
443 info[1u][jss::result].isMember(jss::account_data));
444 auto const&
data = info[1u][jss::result][jss::account_data];
445 BEAST_EXPECT(
data.isMember(jss::signer_lists));
446 auto const& signerLists =
data[jss::signer_lists];
447 BEAST_EXPECT(signerLists.isArray());
448 BEAST_EXPECT(signerLists.size() == 0);
450 info[1u].isMember(jss::jsonrpc) &&
451 info[1u][jss::jsonrpc] ==
"2.0");
453 info[1u].isMember(jss::ripplerpc) &&
454 info[1u][jss::ripplerpc] ==
"2.0");
455 BEAST_EXPECT(info[1u].isMember(jss::id) && info[1u][jss::id] == 6);
459 Account
const bogie{
"bogie"};
465 auto const info = env.rpc(
"json2", withoutSigners);
467 info.isMember(jss::result) &&
468 info[jss::result].isMember(jss::account_data));
469 BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
472 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
474 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
475 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 5);
479 auto const info = env.rpc(
"json2", withSigners);
481 info.isMember(jss::result) &&
482 info[jss::result].isMember(jss::account_data));
483 auto const&
data = info[jss::result][jss::account_data];
484 BEAST_EXPECT(
data.isMember(jss::signer_lists));
485 auto const& signerLists =
data[jss::signer_lists];
486 BEAST_EXPECT(signerLists.isArray());
487 BEAST_EXPECT(signerLists.size() == 1);
488 auto const&
signers = signerLists[0u];
490 BEAST_EXPECT(
signers[sfSignerQuorum.jsonName] == 2);
491 auto const& signerEntries =
signers[sfSignerEntries.jsonName];
492 BEAST_EXPECT(signerEntries.size() == 1);
493 auto const& entry0 = signerEntries[0u][sfSignerEntry.jsonName];
494 BEAST_EXPECT(entry0[sfSignerWeight.jsonName] == 3);
496 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
498 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
499 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
503 Account
const demon{
"demon"};
504 Account
const ghost{
"ghost"};
505 Account
const haunt{
"haunt"};
506 Account
const jinni{
"jinni"};
507 Account
const phase{
"phase"};
508 Account
const shade{
"shade"};
509 Account
const spook{
"spook"};
527 auto const info = env.rpc(
"json2", withSigners);
529 info.isMember(jss::result) &&
530 info[jss::result].isMember(jss::account_data));
531 auto const&
data = info[jss::result][jss::account_data];
532 BEAST_EXPECT(
data.isMember(jss::signer_lists));
533 auto const& signerLists =
data[jss::signer_lists];
534 BEAST_EXPECT(signerLists.isArray());
535 BEAST_EXPECT(signerLists.size() == 1);
536 auto const&
signers = signerLists[0u];
538 BEAST_EXPECT(
signers[sfSignerQuorum.jsonName] == 4);
539 auto const& signerEntries =
signers[sfSignerEntries.jsonName];
540 BEAST_EXPECT(signerEntries.size() == 8);
541 for (
unsigned i = 0u; i < 8; ++i)
543 auto const&
entry = signerEntries[i][sfSignerEntry.jsonName];
546 BEAST_EXPECT(entry[sfSignerWeight.jsonName] == 1);
549 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
551 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
552 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
557 testAccountFlags(FeatureBitset
const& features)
562 Env env(*
this, features);
563 Account
const alice{
"alice"};
564 Account
const bob{
"bob"};
565 env.fund(
XRP(1000), alice, bob);
567 auto getAccountFlag = [&env](
569 Account
const& account) {
570 auto const info = env.rpc(
573 R
"({"account" : ")" + account.human() + R"("})");
576 if (info[jss::result][jss::status] ==
"success" &&
577 info[jss::result][jss::account_flags].isMember(fName.
data()))
578 res.
emplace(info[jss::result][jss::account_flags][fName.
data()]
584 static constexpr std::
595 for (
auto& asf : asFlags)
599 env(
fclear(alice, asf.second));
601 auto const f1 = getAccountFlag(asf.first, alice);
602 BEAST_EXPECT(f1.has_value());
603 BEAST_EXPECT(!f1.value());
607 env(
fset(alice, asf.second));
609 auto const f2 = getAccountFlag(asf.first, alice);
610 BEAST_EXPECT(f2.has_value());
611 BEAST_EXPECT(f2.value());
614 static constexpr std::
616 disallowIncomingFlags{
618 {
"disallowIncomingNFTokenOffer",
621 {
"disallowIncomingTrustline",
624 if (features[featureDisallowIncoming])
626 for (
auto& asf : disallowIncomingFlags)
630 env(
fclear(alice, asf.second));
632 auto const f1 = getAccountFlag(asf.first, alice);
633 BEAST_EXPECT(f1.has_value());
634 BEAST_EXPECT(!f1.value());
638 env(
fset(alice, asf.second));
640 auto const f2 = getAccountFlag(asf.first, alice);
641 BEAST_EXPECT(f2.has_value());
642 BEAST_EXPECT(f2.value());
647 for (
auto& asf : disallowIncomingFlags)
649 BEAST_EXPECT(!getAccountFlag(asf.first, alice));
654 allowTrustLineClawbackFlag{
657 if (features[featureClawback])
661 getAccountFlag(allowTrustLineClawbackFlag.first, bob);
662 BEAST_EXPECT(f1.has_value());
663 BEAST_EXPECT(!f1.value());
666 env(
fset(bob, allowTrustLineClawbackFlag.second));
669 getAccountFlag(allowTrustLineClawbackFlag.first, bob);
670 BEAST_EXPECT(f2.has_value());
671 BEAST_EXPECT(f2.value());
676 !getAccountFlag(allowTrustLineClawbackFlag.first, bob));
680 allowTrustLineLockingFlag{
683 if (features[featureTokenEscrow])
686 getAccountFlag(allowTrustLineLockingFlag.first, bob);
687 BEAST_EXPECT(f1.has_value());
688 BEAST_EXPECT(!f1.value());
691 env(
fset(bob, allowTrustLineLockingFlag.second));
694 getAccountFlag(allowTrustLineLockingFlag.first, bob);
695 BEAST_EXPECT(f2.has_value());
696 BEAST_EXPECT(f2.value());
700 BEAST_EXPECT(!getAccountFlag(allowTrustLineLockingFlag.first, bob));
709 testSignerListsApiVersion2();
712 FeatureBitset
const allFeatures{
714 testAccountFlags(allFeatures);
715 testAccountFlags(allFeatures - featureDisallowIncoming);
717 allFeatures - featureDisallowIncoming - featureClawback);
719 allFeatures - featureDisallowIncoming - featureClawback -