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 }";
223 auto const info = env.rpc(
"json",
"account_info", withoutSigners);
224 BEAST_EXPECT(info.isMember(jss::result));
225 BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
229 auto const info = env.rpc(
"json",
"account_info", withSigners);
230 BEAST_EXPECT(info.isMember(jss::result));
231 auto const&
data = info[jss::result];
232 BEAST_EXPECT(
data.isMember(jss::signer_lists));
233 auto const& signerLists =
data[jss::signer_lists];
234 BEAST_EXPECT(signerLists.isArray());
235 BEAST_EXPECT(signerLists.size() == 0);
239 Account
const bogie{
"bogie"};
245 auto const info = env.rpc(
"json",
"account_info", withoutSigners);
246 BEAST_EXPECT(info.isMember(jss::result));
247 BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
251 auto const info = env.rpc(
"json",
"account_info", withSigners);
252 BEAST_EXPECT(info.isMember(jss::result));
253 auto const&
data = info[jss::result];
254 BEAST_EXPECT(
data.isMember(jss::signer_lists));
255 auto const& signerLists =
data[jss::signer_lists];
256 BEAST_EXPECT(signerLists.isArray());
257 BEAST_EXPECT(signerLists.size() == 1);
258 auto const&
signers = signerLists[0u];
259 BEAST_EXPECT(
signers.isObject());
262 BEAST_EXPECT(signerEntries.size() == 1);
268 Account
const demon{
"demon"};
269 Account
const ghost{
"ghost"};
270 Account
const haunt{
"haunt"};
271 Account
const jinni{
"jinni"};
272 Account
const phase{
"phase"};
273 Account
const shade{
"shade"};
274 Account
const spook{
"spook"};
292 auto const info = env.rpc(
"json",
"account_info", withSigners);
293 BEAST_EXPECT(info.isMember(jss::result));
294 auto const&
data = info[jss::result];
295 BEAST_EXPECT(
data.isMember(jss::signer_lists));
296 auto const& signerLists =
data[jss::signer_lists];
297 BEAST_EXPECT(signerLists.isArray());
298 BEAST_EXPECT(signerLists.size() == 1);
299 auto const&
signers = signerLists[0u];
300 BEAST_EXPECT(
signers.isObject());
303 BEAST_EXPECT(signerEntries.size() == 8);
304 for (
unsigned i = 0u; i < 8; ++i)
307 BEAST_EXPECT(entry.size() == 2);
320 Account
const alice{
"alice"};
321 env.fund(
XRP(1000), alice);
324 "\"jsonrpc\": \"2.0\", "
325 "\"ripplerpc\": \"2.0\", "
327 "\"method\": \"account_info\", "
330 alice.human() +
"\"}}";
333 "\"jsonrpc\": \"2.0\", "
334 "\"ripplerpc\": \"2.0\", "
336 "\"method\": \"account_info\", "
339 alice.human() +
"\", " +
"\"signer_lists\": true }}";
343 auto const info = env.rpc(
"json2", withoutSigners);
345 info.isMember(jss::result) &&
346 info[jss::result].isMember(jss::account_data));
347 BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
350 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
352 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
353 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 5);
357 auto const info = env.rpc(
"json2", withSigners);
359 info.isMember(jss::result) &&
360 info[jss::result].isMember(jss::account_data));
361 auto const&
data = info[jss::result][jss::account_data];
362 BEAST_EXPECT(
data.isMember(jss::signer_lists));
363 auto const& signerLists =
data[jss::signer_lists];
364 BEAST_EXPECT(signerLists.isArray());
365 BEAST_EXPECT(signerLists.size() == 0);
367 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
369 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
370 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
374 auto const info = env.rpc(
375 "json2",
'[' + withoutSigners +
", " + withSigners +
']');
377 info[0u].isMember(jss::result) &&
378 info[0u][jss::result].isMember(jss::account_data));
379 BEAST_EXPECT(!info[0u][jss::result][jss::account_data].isMember(
382 info[0u].isMember(jss::jsonrpc) &&
383 info[0u][jss::jsonrpc] ==
"2.0");
385 info[0u].isMember(jss::ripplerpc) &&
386 info[0u][jss::ripplerpc] ==
"2.0");
387 BEAST_EXPECT(info[0u].isMember(jss::id) && info[0u][jss::id] == 5);
390 info[1u].isMember(jss::result) &&
391 info[1u][jss::result].isMember(jss::account_data));
392 auto const&
data = info[1u][jss::result][jss::account_data];
393 BEAST_EXPECT(
data.isMember(jss::signer_lists));
394 auto const& signerLists =
data[jss::signer_lists];
395 BEAST_EXPECT(signerLists.isArray());
396 BEAST_EXPECT(signerLists.size() == 0);
398 info[1u].isMember(jss::jsonrpc) &&
399 info[1u][jss::jsonrpc] ==
"2.0");
401 info[1u].isMember(jss::ripplerpc) &&
402 info[1u][jss::ripplerpc] ==
"2.0");
403 BEAST_EXPECT(info[1u].isMember(jss::id) && info[1u][jss::id] == 6);
407 Account
const bogie{
"bogie"};
413 auto const info = env.rpc(
"json2", withoutSigners);
415 info.isMember(jss::result) &&
416 info[jss::result].isMember(jss::account_data));
417 BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
420 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
422 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
423 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 5);
427 auto const info = env.rpc(
"json2", withSigners);
429 info.isMember(jss::result) &&
430 info[jss::result].isMember(jss::account_data));
431 auto const&
data = info[jss::result][jss::account_data];
432 BEAST_EXPECT(
data.isMember(jss::signer_lists));
433 auto const& signerLists =
data[jss::signer_lists];
434 BEAST_EXPECT(signerLists.isArray());
435 BEAST_EXPECT(signerLists.size() == 1);
436 auto const&
signers = signerLists[0u];
437 BEAST_EXPECT(
signers.isObject());
440 BEAST_EXPECT(signerEntries.size() == 1);
444 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
446 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
447 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
451 Account
const demon{
"demon"};
452 Account
const ghost{
"ghost"};
453 Account
const haunt{
"haunt"};
454 Account
const jinni{
"jinni"};
455 Account
const phase{
"phase"};
456 Account
const shade{
"shade"};
457 Account
const spook{
"spook"};
475 auto const info = env.rpc(
"json2", withSigners);
477 info.isMember(jss::result) &&
478 info[jss::result].isMember(jss::account_data));
479 auto const&
data = info[jss::result][jss::account_data];
480 BEAST_EXPECT(
data.isMember(jss::signer_lists));
481 auto const& signerLists =
data[jss::signer_lists];
482 BEAST_EXPECT(signerLists.isArray());
483 BEAST_EXPECT(signerLists.size() == 1);
484 auto const&
signers = signerLists[0u];
485 BEAST_EXPECT(
signers.isObject());
488 BEAST_EXPECT(signerEntries.size() == 8);
489 for (
unsigned i = 0u; i < 8; ++i)
492 BEAST_EXPECT(entry.size() == 2);
497 info.isMember(jss::jsonrpc) && info[jss::jsonrpc] ==
"2.0");
499 info.isMember(jss::ripplerpc) && info[jss::ripplerpc] ==
"2.0");
500 BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
505 testAccountFlags(FeatureBitset
const& features)
509 Env env(*
this, features);
510 Account
const alice{
"alice"};
511 env.fund(
XRP(1000), alice);
514 auto const info = env.rpc(
517 R
"({"account" : ")" + alice.human() + R"("})");
520 if (info[jss::result][jss::status] ==
"success" &&
521 info[jss::result][jss::account_flags].isMember(fName.data()))
522 res.
emplace(info[jss::result][jss::account_flags][fName.data()]
528 static constexpr std::
529 array<std::pair<std::string_view, std::uint32_t>, 7>
539 for (
auto& asf : asFlags)
543 env(
fclear(alice, asf.second));
545 auto const f1 = getAccountFlag(asf.first);
546 BEAST_EXPECT(f1.has_value());
547 BEAST_EXPECT(!f1.value());
551 env(
fset(alice, asf.second));
553 auto const f2 = getAccountFlag(asf.first);
554 BEAST_EXPECT(f2.has_value());
555 BEAST_EXPECT(f2.value());
558 static constexpr std::
559 array<std::pair<std::string_view, std::uint32_t>, 4>
560 disallowIncomingFlags{
562 {
"disallowIncomingNFTokenOffer",
565 {
"disallowIncomingTrustline",
570 for (
auto& asf : disallowIncomingFlags)
574 env(
fclear(alice, asf.second));
576 auto const f1 = getAccountFlag(asf.first);
577 BEAST_EXPECT(f1.has_value());
578 BEAST_EXPECT(!f1.value());
582 env(
fset(alice, asf.second));
584 auto const f2 = getAccountFlag(asf.first);
585 BEAST_EXPECT(f2.has_value());
586 BEAST_EXPECT(f2.value());
591 for (
auto& asf : disallowIncomingFlags)
593 BEAST_EXPECT(!getAccountFlag(asf.first));
603 testSignerListsApiVersion2();
606 FeatureBitset
const allFeatures{
608 testAccountFlags(allFeatures);