rippled
AccountInfo_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2016 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/protocol/Feature.h>
21 #include <ripple/protocol/jss.h>
22 #include <test/jtx.h>
23 
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>
29 
30 namespace ripple {
31 namespace test {
32 
33 class AccountInfo_test : public beast::unit_test::suite
34 {
35 public:
36  void
38  {
39  using namespace jtx;
40  Env env(*this);
41  {
42  // account_info with no account.
43  auto const info = env.rpc("json", "account_info", "{ }");
44  BEAST_EXPECT(
45  info[jss::result][jss::error_message] ==
46  "Missing field 'account'.");
47  }
48  {
49  // account_info with a malformed account string.
50  auto const info = env.rpc(
51  "json",
52  "account_info",
53  "{\"account\": "
54  "\"n94JNrQYkDrpt62bbSR7nVEhdyAvcJXRAsjEkFYyqRkh9SUTYEqV\"}");
55  BEAST_EXPECT(
56  info[jss::result][jss::error_code] == rpcACT_MALFORMED);
57  BEAST_EXPECT(
58  info[jss::result][jss::error_message] == "Account malformed.");
59  }
60  {
61  // account_info with an account that's not in the ledger.
62  Account const bogie{"bogie"};
63  auto const info = env.rpc(
64  "json",
65  "account_info",
66  R"({ "account": ")" + bogie.human() + R"("})");
67  BEAST_EXPECT(
68  info[jss::result][jss::error_code] == rpcACT_NOT_FOUND);
69  BEAST_EXPECT(
70  info[jss::result][jss::error_message] == "Account not found.");
71  }
72  {
73  // Cannot use a seed as account
74  auto const info =
75  env.rpc("json", "account_info", R"({"account": "foo"})");
76  BEAST_EXPECT(
77  info[jss::result][jss::error_code] == rpcACT_MALFORMED);
78  BEAST_EXPECT(
79  info[jss::result][jss::error_message] == "Account malformed.");
80  }
81  }
82 
83  // Test the "signer_lists" argument in account_info.
84  void
85  testSignerLists()
86  {
87  using namespace jtx;
88  Env env(*this);
89  Account const alice{"alice"};
90  env.fund(XRP(1000), alice);
91 
92  auto const withoutSigners =
93  std::string("{ ") + "\"account\": \"" + alice.human() + "\"}";
94 
95  auto const withSigners = std::string("{ ") + "\"account\": \"" +
96  alice.human() + "\", " + "\"signer_lists\": true }";
97 
98  // Alice has no SignerList yet.
99  {
100  // account_info without the "signer_lists" argument.
101  auto const info = env.rpc("json", "account_info", withoutSigners);
102  BEAST_EXPECT(
103  info.isMember(jss::result) &&
104  info[jss::result].isMember(jss::account_data));
105  BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
106  jss::signer_lists));
107  }
108  {
109  // account_info with the "signer_lists" argument.
110  auto const info = env.rpc("json", "account_info", withSigners);
111  BEAST_EXPECT(
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);
119  }
120 
121  // Give alice a SignerList.
122  Account const bogie{"bogie"};
123 
124  Json::Value const smallSigners = signers(alice, 2, {{bogie, 3}});
125  env(smallSigners);
126  {
127  // account_info without the "signer_lists" argument.
128  auto const info = env.rpc("json", "account_info", withoutSigners);
129  BEAST_EXPECT(
130  info.isMember(jss::result) &&
131  info[jss::result].isMember(jss::account_data));
132  BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
133  jss::signer_lists));
134  }
135  {
136  // account_info with the "signer_lists" argument.
137  auto const info = env.rpc("json", "account_info", withSigners);
138  BEAST_EXPECT(
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());
148  BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 2);
149  auto const& signerEntries = signers[sfSignerEntries.jsonName];
150  BEAST_EXPECT(signerEntries.size() == 1);
151  auto const& entry0 = signerEntries[0u][sfSignerEntry.jsonName];
152  BEAST_EXPECT(entry0[sfSignerWeight.jsonName] == 3);
153  }
154 
155  // Give alice a big signer list
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"};
163 
164  Json::Value const bigSigners = signers(
165  alice,
166  4,
167  {
168  {bogie, 1},
169  {demon, 1},
170  {ghost, 1},
171  {haunt, 1},
172  {jinni, 1},
173  {phase, 1},
174  {shade, 1},
175  {spook, 1},
176  });
177  env(bigSigners);
178  {
179  // account_info with the "signer_lists" argument.
180  auto const info = env.rpc("json", "account_info", withSigners);
181  BEAST_EXPECT(
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());
191  BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 4);
192  auto const& signerEntries = signers[sfSignerEntries.jsonName];
193  BEAST_EXPECT(signerEntries.size() == 8);
194  for (unsigned i = 0u; i < 8; ++i)
195  {
196  auto const& entry = signerEntries[i][sfSignerEntry.jsonName];
197  BEAST_EXPECT(entry.size() == 2);
198  BEAST_EXPECT(entry.isMember(sfAccount.jsonName));
199  BEAST_EXPECT(entry[sfSignerWeight.jsonName] == 1);
200  }
201  }
202  }
203 
204  // Test the "signer_lists" argument in account_info, with api_version 2.
205  void
206  testSignerListsApiVersion2()
207  {
208  using namespace jtx;
209  Env env{*this, envconfig([](std::unique_ptr<Config> c) {
210  c->loadFromString("\n[beta_rpc_api]\n1\n");
211  return c;
212  })};
213  Account const alice{"alice"};
214  env.fund(XRP(1000), alice);
215 
216  auto const withoutSigners = std::string("{ ") +
217  "\"api_version\": 2, \"account\": \"" + alice.human() + "\"}";
218 
219  auto const withSigners = std::string("{ ") +
220  "\"api_version\": 2, \"account\": \"" + alice.human() + "\", " +
221  "\"signer_lists\": true }";
222 
223  // Alice has no SignerList yet.
224  {
225  // account_info without the "signer_lists" argument.
226  auto const info = env.rpc("json", "account_info", withoutSigners);
227  BEAST_EXPECT(info.isMember(jss::result));
228  BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
229  }
230  {
231  // account_info with the "signer_lists" argument.
232  auto const info = env.rpc("json", "account_info", withSigners);
233  BEAST_EXPECT(info.isMember(jss::result));
234  auto const& data = info[jss::result];
235  BEAST_EXPECT(data.isMember(jss::signer_lists));
236  auto const& signerLists = data[jss::signer_lists];
237  BEAST_EXPECT(signerLists.isArray());
238  BEAST_EXPECT(signerLists.size() == 0);
239  }
240 
241  // Give alice a SignerList.
242  Account const bogie{"bogie"};
243 
244  Json::Value const smallSigners = signers(alice, 2, {{bogie, 3}});
245  env(smallSigners);
246  {
247  // account_info without the "signer_lists" argument.
248  auto const info = env.rpc("json", "account_info", withoutSigners);
249  BEAST_EXPECT(info.isMember(jss::result));
250  BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
251  }
252  {
253  // account_info with the "signer_lists" argument.
254  auto const info = env.rpc("json", "account_info", withSigners);
255  BEAST_EXPECT(info.isMember(jss::result));
256  auto const& data = info[jss::result];
257  BEAST_EXPECT(data.isMember(jss::signer_lists));
258  auto const& signerLists = data[jss::signer_lists];
259  BEAST_EXPECT(signerLists.isArray());
260  BEAST_EXPECT(signerLists.size() == 1);
261  auto const& signers = signerLists[0u];
262  BEAST_EXPECT(signers.isObject());
263  BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 2);
264  auto const& signerEntries = signers[sfSignerEntries.jsonName];
265  BEAST_EXPECT(signerEntries.size() == 1);
266  auto const& entry0 = signerEntries[0u][sfSignerEntry.jsonName];
267  BEAST_EXPECT(entry0[sfSignerWeight.jsonName] == 3);
268  }
269 
270  // Give alice a big signer list
271  Account const demon{"demon"};
272  Account const ghost{"ghost"};
273  Account const haunt{"haunt"};
274  Account const jinni{"jinni"};
275  Account const phase{"phase"};
276  Account const shade{"shade"};
277  Account const spook{"spook"};
278 
279  Json::Value const bigSigners = signers(
280  alice,
281  4,
282  {
283  {bogie, 1},
284  {demon, 1},
285  {ghost, 1},
286  {haunt, 1},
287  {jinni, 1},
288  {phase, 1},
289  {shade, 1},
290  {spook, 1},
291  });
292  env(bigSigners);
293  {
294  // account_info with the "signer_lists" argument.
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];
303  BEAST_EXPECT(signers.isObject());
304  BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 4);
305  auto const& signerEntries = signers[sfSignerEntries.jsonName];
306  BEAST_EXPECT(signerEntries.size() == 8);
307  for (unsigned i = 0u; i < 8; ++i)
308  {
309  auto const& entry = signerEntries[i][sfSignerEntry.jsonName];
310  BEAST_EXPECT(entry.size() == 2);
311  BEAST_EXPECT(entry.isMember(sfAccount.jsonName));
312  BEAST_EXPECT(entry[sfSignerWeight.jsonName] == 1);
313  }
314  }
315  }
316 
317  // Test the "signer_lists" argument in account_info, version 2 API.
318  void
319  testSignerListsV2()
320  {
321  using namespace jtx;
322  Env env(*this);
323  Account const alice{"alice"};
324  env.fund(XRP(1000), alice);
325 
326  auto const withoutSigners = std::string("{ ") +
327  "\"jsonrpc\": \"2.0\", "
328  "\"ripplerpc\": \"2.0\", "
329  "\"id\": 5, "
330  "\"method\": \"account_info\", "
331  "\"params\": { "
332  "\"account\": \"" +
333  alice.human() + "\"}}";
334 
335  auto const withSigners = std::string("{ ") +
336  "\"jsonrpc\": \"2.0\", "
337  "\"ripplerpc\": \"2.0\", "
338  "\"id\": 6, "
339  "\"method\": \"account_info\", "
340  "\"params\": { "
341  "\"account\": \"" +
342  alice.human() + "\", " + "\"signer_lists\": true }}";
343  // Alice has no SignerList yet.
344  {
345  // account_info without the "signer_lists" argument.
346  auto const info = env.rpc("json2", withoutSigners);
347  BEAST_EXPECT(
348  info.isMember(jss::result) &&
349  info[jss::result].isMember(jss::account_data));
350  BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
351  jss::signer_lists));
352  BEAST_EXPECT(
353  info.isMember(jss::jsonrpc) && info[jss::jsonrpc] == "2.0");
354  BEAST_EXPECT(
355  info.isMember(jss::ripplerpc) && info[jss::ripplerpc] == "2.0");
356  BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 5);
357  }
358  {
359  // account_info with the "signer_lists" argument.
360  auto const info = env.rpc("json2", withSigners);
361  BEAST_EXPECT(
362  info.isMember(jss::result) &&
363  info[jss::result].isMember(jss::account_data));
364  auto const& data = info[jss::result][jss::account_data];
365  BEAST_EXPECT(data.isMember(jss::signer_lists));
366  auto const& signerLists = data[jss::signer_lists];
367  BEAST_EXPECT(signerLists.isArray());
368  BEAST_EXPECT(signerLists.size() == 0);
369  BEAST_EXPECT(
370  info.isMember(jss::jsonrpc) && info[jss::jsonrpc] == "2.0");
371  BEAST_EXPECT(
372  info.isMember(jss::ripplerpc) && info[jss::ripplerpc] == "2.0");
373  BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
374  }
375  {
376  // Do both of the above as a batch job
377  auto const info = env.rpc(
378  "json2", '[' + withoutSigners + ", " + withSigners + ']');
379  BEAST_EXPECT(
380  info[0u].isMember(jss::result) &&
381  info[0u][jss::result].isMember(jss::account_data));
382  BEAST_EXPECT(!info[0u][jss::result][jss::account_data].isMember(
383  jss::signer_lists));
384  BEAST_EXPECT(
385  info[0u].isMember(jss::jsonrpc) &&
386  info[0u][jss::jsonrpc] == "2.0");
387  BEAST_EXPECT(
388  info[0u].isMember(jss::ripplerpc) &&
389  info[0u][jss::ripplerpc] == "2.0");
390  BEAST_EXPECT(info[0u].isMember(jss::id) && info[0u][jss::id] == 5);
391 
392  BEAST_EXPECT(
393  info[1u].isMember(jss::result) &&
394  info[1u][jss::result].isMember(jss::account_data));
395  auto const& data = info[1u][jss::result][jss::account_data];
396  BEAST_EXPECT(data.isMember(jss::signer_lists));
397  auto const& signerLists = data[jss::signer_lists];
398  BEAST_EXPECT(signerLists.isArray());
399  BEAST_EXPECT(signerLists.size() == 0);
400  BEAST_EXPECT(
401  info[1u].isMember(jss::jsonrpc) &&
402  info[1u][jss::jsonrpc] == "2.0");
403  BEAST_EXPECT(
404  info[1u].isMember(jss::ripplerpc) &&
405  info[1u][jss::ripplerpc] == "2.0");
406  BEAST_EXPECT(info[1u].isMember(jss::id) && info[1u][jss::id] == 6);
407  }
408 
409  // Give alice a SignerList.
410  Account const bogie{"bogie"};
411 
412  Json::Value const smallSigners = signers(alice, 2, {{bogie, 3}});
413  env(smallSigners);
414  {
415  // account_info without the "signer_lists" argument.
416  auto const info = env.rpc("json2", withoutSigners);
417  BEAST_EXPECT(
418  info.isMember(jss::result) &&
419  info[jss::result].isMember(jss::account_data));
420  BEAST_EXPECT(!info[jss::result][jss::account_data].isMember(
421  jss::signer_lists));
422  BEAST_EXPECT(
423  info.isMember(jss::jsonrpc) && info[jss::jsonrpc] == "2.0");
424  BEAST_EXPECT(
425  info.isMember(jss::ripplerpc) && info[jss::ripplerpc] == "2.0");
426  BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 5);
427  }
428  {
429  // account_info with the "signer_lists" argument.
430  auto const info = env.rpc("json2", withSigners);
431  BEAST_EXPECT(
432  info.isMember(jss::result) &&
433  info[jss::result].isMember(jss::account_data));
434  auto const& data = info[jss::result][jss::account_data];
435  BEAST_EXPECT(data.isMember(jss::signer_lists));
436  auto const& signerLists = data[jss::signer_lists];
437  BEAST_EXPECT(signerLists.isArray());
438  BEAST_EXPECT(signerLists.size() == 1);
439  auto const& signers = signerLists[0u];
440  BEAST_EXPECT(signers.isObject());
441  BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 2);
442  auto const& signerEntries = signers[sfSignerEntries.jsonName];
443  BEAST_EXPECT(signerEntries.size() == 1);
444  auto const& entry0 = signerEntries[0u][sfSignerEntry.jsonName];
445  BEAST_EXPECT(entry0[sfSignerWeight.jsonName] == 3);
446  BEAST_EXPECT(
447  info.isMember(jss::jsonrpc) && info[jss::jsonrpc] == "2.0");
448  BEAST_EXPECT(
449  info.isMember(jss::ripplerpc) && info[jss::ripplerpc] == "2.0");
450  BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
451  }
452 
453  // Give alice a big signer list
454  Account const demon{"demon"};
455  Account const ghost{"ghost"};
456  Account const haunt{"haunt"};
457  Account const jinni{"jinni"};
458  Account const phase{"phase"};
459  Account const shade{"shade"};
460  Account const spook{"spook"};
461 
462  Json::Value const bigSigners = signers(
463  alice,
464  4,
465  {
466  {bogie, 1},
467  {demon, 1},
468  {ghost, 1},
469  {haunt, 1},
470  {jinni, 1},
471  {phase, 1},
472  {shade, 1},
473  {spook, 1},
474  });
475  env(bigSigners);
476  {
477  // account_info with the "signer_lists" argument.
478  auto const info = env.rpc("json2", withSigners);
479  BEAST_EXPECT(
480  info.isMember(jss::result) &&
481  info[jss::result].isMember(jss::account_data));
482  auto const& data = info[jss::result][jss::account_data];
483  BEAST_EXPECT(data.isMember(jss::signer_lists));
484  auto const& signerLists = data[jss::signer_lists];
485  BEAST_EXPECT(signerLists.isArray());
486  BEAST_EXPECT(signerLists.size() == 1);
487  auto const& signers = signerLists[0u];
488  BEAST_EXPECT(signers.isObject());
489  BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 4);
490  auto const& signerEntries = signers[sfSignerEntries.jsonName];
491  BEAST_EXPECT(signerEntries.size() == 8);
492  for (unsigned i = 0u; i < 8; ++i)
493  {
494  auto const& entry = signerEntries[i][sfSignerEntry.jsonName];
495  BEAST_EXPECT(entry.size() == 2);
496  BEAST_EXPECT(entry.isMember(sfAccount.jsonName));
497  BEAST_EXPECT(entry[sfSignerWeight.jsonName] == 1);
498  }
499  BEAST_EXPECT(
500  info.isMember(jss::jsonrpc) && info[jss::jsonrpc] == "2.0");
501  BEAST_EXPECT(
502  info.isMember(jss::ripplerpc) && info[jss::ripplerpc] == "2.0");
503  BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
504  }
505  }
506 
507  void
508  testAccountFlags(FeatureBitset const& features)
509  {
510  using namespace jtx;
511 
512  Env env(*this, features);
513  Account const alice{"alice"};
514  env.fund(XRP(1000), alice);
515 
516  auto getAccountFlag = [&env, &alice](std::string_view fName) {
517  auto const info = env.rpc(
518  "json",
519  "account_info",
520  R"({"account" : ")" + alice.human() + R"("})");
521 
523  if (info[jss::result][jss::status] == "success" &&
524  info[jss::result][jss::account_flags].isMember(fName.data()))
525  res.emplace(info[jss::result][jss::account_flags][fName.data()]
526  .asBool());
527 
528  return res;
529  };
530 
531  static constexpr std::
532  array<std::pair<std::string_view, std::uint32_t>, 7>
533  asFlags{
534  {{"defaultRipple", asfDefaultRipple},
535  {"depositAuth", asfDepositAuth},
536  {"disallowIncomingXRP", asfDisallowXRP},
537  {"globalFreeze", asfGlobalFreeze},
538  {"noFreeze", asfNoFreeze},
539  {"requireAuthorization", asfRequireAuth},
540  {"requireDestinationTag", asfRequireDest}}};
541 
542  for (auto& asf : asFlags)
543  {
544  // Clear a flag and check that account_info returns results
545  // as expected
546  env(fclear(alice, asf.second));
547  env.close();
548  auto const f1 = getAccountFlag(asf.first);
549  BEAST_EXPECT(f1.has_value());
550  BEAST_EXPECT(!f1.value());
551 
552  // Set a flag and check that account_info returns results
553  // as expected
554  env(fset(alice, asf.second));
555  env.close();
556  auto const f2 = getAccountFlag(asf.first);
557  BEAST_EXPECT(f2.has_value());
558  BEAST_EXPECT(f2.value());
559  }
560 
561  static constexpr std::
562  array<std::pair<std::string_view, std::uint32_t>, 4>
563  disallowIncomingFlags{
564  {{"disallowIncomingCheck", asfDisallowIncomingCheck},
565  {"disallowIncomingNFTokenOffer",
567  {"disallowIncomingPayChan", asfDisallowIncomingPayChan},
568  {"disallowIncomingTrustline",
570 
571  if (features[featureDisallowIncoming])
572  {
573  for (auto& asf : disallowIncomingFlags)
574  {
575  // Clear a flag and check that account_info returns results
576  // as expected
577  env(fclear(alice, asf.second));
578  env.close();
579  auto const f1 = getAccountFlag(asf.first);
580  BEAST_EXPECT(f1.has_value());
581  BEAST_EXPECT(!f1.value());
582 
583  // Set a flag and check that account_info returns results
584  // as expected
585  env(fset(alice, asf.second));
586  env.close();
587  auto const f2 = getAccountFlag(asf.first);
588  BEAST_EXPECT(f2.has_value());
589  BEAST_EXPECT(f2.value());
590  }
591  }
592  else
593  {
594  for (auto& asf : disallowIncomingFlags)
595  {
596  BEAST_EXPECT(!getAccountFlag(asf.first));
597  }
598  }
599  }
600 
601  void
602  run() override
603  {
604  testErrors();
605  testSignerLists();
606  testSignerListsApiVersion2();
607  testSignerListsV2();
608 
609  FeatureBitset const allFeatures{
611  testAccountFlags(allFeatures);
612  testAccountFlags(allFeatures - featureDisallowIncoming);
613  }
614 };
615 
616 BEAST_DEFINE_TESTSUITE(AccountInfo, app, ripple);
617 
618 } // namespace test
619 } // namespace ripple
ripple::sfSignerWeight
const SF_UINT16 sfSignerWeight
ripple::test::jtx::XRP
const XRP_t XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
ripple::asfDisallowXRP
constexpr std::uint32_t asfDisallowXRP
Definition: TxFlags.h:76
ripple::asfDepositAuth
constexpr std::uint32_t asfDepositAuth
Definition: TxFlags.h:82
std::string
STL class.
ripple::keylet::signers
Keylet signers(AccountID const &account) noexcept
A SignerList.
Definition: Indexes.cpp:275
std::string_view
STL class.
ripple::asfNoFreeze
constexpr std::uint32_t asfNoFreeze
Definition: TxFlags.h:79
std::optional::emplace
T emplace(T... args)
ripple::asfDisallowIncomingPayChan
constexpr std::uint32_t asfDisallowIncomingPayChan
Definition: TxFlags.h:89
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:49
ripple::SField::jsonName
const Json::StaticString jsonName
Definition: SField.h:136
ripple::sfSignerQuorum
const SF_UINT32 sfSignerQuorum
ripple::asfDisallowIncomingTrustline
constexpr std::uint32_t asfDisallowIncomingTrustline
Definition: TxFlags.h:90
ripple::asfDisallowIncomingCheck
constexpr std::uint32_t asfDisallowIncomingCheck
Definition: TxFlags.h:88
ripple::featureDisallowIncoming
const uint256 featureDisallowIncoming
ripple::test::AccountInfo_test
Definition: AccountInfo_test.cpp:33
ripple::rpcACT_NOT_FOUND
@ rpcACT_NOT_FOUND
Definition: ErrorCodes.h:70
ripple::test::jtx::fset
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Definition: flags.cpp:28
ripple::test::jtx::supported_amendments
FeatureBitset supported_amendments()
Definition: Env.h:70
ripple::test::jtx::fclear
Json::Value fclear(Account const &account, std::uint32_t off)
Remove account flag.
Definition: flags.h:40
ripple::sfSignerEntry
const SField sfSignerEntry
ripple::sfSignerEntries
const SField sfSignerEntries
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::rpcACT_MALFORMED
@ rpcACT_MALFORMED
Definition: ErrorCodes.h:90
ripple::asfRequireAuth
constexpr std::uint32_t asfRequireAuth
Definition: TxFlags.h:75
ripple::asfDefaultRipple
constexpr std::uint32_t asfDefaultRipple
Definition: TxFlags.h:81
ripple::asfRequireDest
constexpr std::uint32_t asfRequireDest
Definition: TxFlags.h:74
ripple::asfGlobalFreeze
constexpr std::uint32_t asfGlobalFreeze
Definition: TxFlags.h:80
std::optional< bool >
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
ripple::sfAccount
const SF_ACCOUNT sfAccount
std::unique_ptr
STL class.
std::data
T data(T... args)
ripple::test::AccountInfo_test::testErrors
void testErrors()
Definition: AccountInfo_test.cpp:37
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:116
ripple::asfDisallowIncomingNFTokenOffer
constexpr std::uint32_t asfDisallowIncomingNFTokenOffer
Definition: TxFlags.h:87
ripple::test::jtx::Env::rpc
Json::Value rpc(std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:687
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(DeliverMin, app, ripple)