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 
37  void testErrors()
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(info[jss::result][jss::error_message] ==
45  "Missing field 'account'.");
46  }
47  {
48  // account_info with a malformed account sting.
49  auto const info = env.rpc ("json", "account_info", "{\"account\": "
50  "\"n94JNrQYkDrpt62bbSR7nVEhdyAvcJXRAsjEkFYyqRkh9SUTYEqV\"}");
51  BEAST_EXPECT(info[jss::result][jss::error_message] ==
52  "Disallowed seed.");
53  }
54  {
55  // account_info with an account that's not in the ledger.
56  Account const bogie {"bogie"};
57  auto const info = env.rpc ("json", "account_info",
58  std::string ("{ ") + "\"account\": \"" + bogie.human() + "\"}");
59  BEAST_EXPECT(info[jss::result][jss::error_message] ==
60  "Account not found.");
61  }
62  }
63 
64  // Test the "signer_lists" argument in account_info.
66  {
67  using namespace jtx;
68  Env env(*this);
69  Account const alice {"alice"};
70  env.fund(XRP(1000), alice);
71 
72  auto const withoutSigners = std::string ("{ ") +
73  "\"account\": \"" + alice.human() + "\"}";
74 
75  auto const withSigners = std::string ("{ ") +
76  "\"account\": \"" + alice.human() + "\", " +
77  "\"signer_lists\": true }";
78 
79  // Alice has no SignerList yet.
80  {
81  // account_info without the "signer_lists" argument.
82  auto const info = env.rpc ("json", "account_info", withoutSigners);
83  BEAST_EXPECT(info.isMember(jss::result) &&
84  info[jss::result].isMember(jss::account_data));
85  BEAST_EXPECT(! info[jss::result][jss::account_data].
86  isMember (jss::signer_lists));
87  }
88  {
89  // account_info with the "signer_lists" argument.
90  auto const info = env.rpc ("json", "account_info", withSigners);
91  BEAST_EXPECT(info.isMember(jss::result) &&
92  info[jss::result].isMember(jss::account_data));
93  auto const& data = info[jss::result][jss::account_data];
94  BEAST_EXPECT(data.isMember (jss::signer_lists));
95  auto const& signerLists = data[jss::signer_lists];
96  BEAST_EXPECT(signerLists.isArray());
97  BEAST_EXPECT(signerLists.size() == 0);
98  }
99 
100  // Give alice a SignerList.
101  Account const bogie {"bogie"};
102 
103  Json::Value const smallSigners = signers(alice, 2, { { bogie, 3 } });
104  env(smallSigners);
105  {
106  // account_info without the "signer_lists" argument.
107  auto const info = env.rpc ("json", "account_info", withoutSigners);
108  BEAST_EXPECT(info.isMember(jss::result) &&
109  info[jss::result].isMember(jss::account_data));
110  BEAST_EXPECT(! info[jss::result][jss::account_data].
111  isMember (jss::signer_lists));
112  }
113  {
114  // account_info with the "signer_lists" argument.
115  auto const info = env.rpc ("json", "account_info", withSigners);
116  BEAST_EXPECT(info.isMember(jss::result) &&
117  info[jss::result].isMember(jss::account_data));
118  auto const& data = info[jss::result][jss::account_data];
119  BEAST_EXPECT(data.isMember (jss::signer_lists));
120  auto const& signerLists = data[jss::signer_lists];
121  BEAST_EXPECT(signerLists.isArray());
122  BEAST_EXPECT(signerLists.size() == 1);
123  auto const& signers = signerLists[0u];
124  BEAST_EXPECT(signers.isObject());
125  BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 2);
126  auto const& signerEntries = signers[sfSignerEntries.jsonName];
127  BEAST_EXPECT(signerEntries.size() == 1);
128  auto const& entry0 = signerEntries[0u][sfSignerEntry.jsonName];
129  BEAST_EXPECT(entry0[sfSignerWeight.jsonName] == 3);
130  }
131 
132  // Give alice a big signer list
133  Account const demon {"demon"};
134  Account const ghost {"ghost"};
135  Account const haunt {"haunt"};
136  Account const jinni {"jinni"};
137  Account const phase {"phase"};
138  Account const shade {"shade"};
139  Account const spook {"spook"};
140 
141  Json::Value const bigSigners = signers(alice, 4, {
142  {bogie, 1}, {demon, 1}, {ghost, 1}, {haunt, 1},
143  {jinni, 1}, {phase, 1}, {shade, 1}, {spook, 1}, });
144  env(bigSigners);
145  {
146  // account_info with the "signer_lists" argument.
147  auto const info = env.rpc ("json", "account_info", withSigners);
148  BEAST_EXPECT(info.isMember(jss::result) &&
149  info[jss::result].isMember(jss::account_data));
150  auto const& data = info[jss::result][jss::account_data];
151  BEAST_EXPECT(data.isMember (jss::signer_lists));
152  auto const& signerLists = data[jss::signer_lists];
153  BEAST_EXPECT(signerLists.isArray());
154  BEAST_EXPECT(signerLists.size() == 1);
155  auto const& signers = signerLists[0u];
156  BEAST_EXPECT(signers.isObject());
157  BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 4);
158  auto const& signerEntries = signers[sfSignerEntries.jsonName];
159  BEAST_EXPECT(signerEntries.size() == 8);
160  for (unsigned i = 0u; i < 8; ++i)
161  {
162  auto const& entry = signerEntries[i][sfSignerEntry.jsonName];
163  BEAST_EXPECT(entry.size() == 2);
164  BEAST_EXPECT(entry.isMember(sfAccount.jsonName));
165  BEAST_EXPECT(entry[sfSignerWeight.jsonName] == 1);
166  }
167  }
168  }
169 
170  // Test the "signer_lists" argument in account_info, version 2 API.
172  {
173  using namespace jtx;
174  Env env(*this);
175  Account const alice {"alice"};
176  env.fund(XRP(1000), alice);
177 
178  auto const withoutSigners = std::string ("{ ") +
179  "\"jsonrpc\": \"2.0\", "
180  "\"ripplerpc\": \"2.0\", "
181  "\"id\": 5, "
182  "\"method\": \"account_info\", "
183  "\"params\": { "
184  "\"account\": \"" + alice.human() + "\"}}";
185 
186  auto const withSigners = std::string ("{ ") +
187  "\"jsonrpc\": \"2.0\", "
188  "\"ripplerpc\": \"2.0\", "
189  "\"id\": 6, "
190  "\"method\": \"account_info\", "
191  "\"params\": { "
192  "\"account\": \"" + alice.human() + "\", " +
193  "\"signer_lists\": true }}";
194  // Alice has no SignerList yet.
195  {
196  // account_info without the "signer_lists" argument.
197  auto const info = env.rpc ("json2", withoutSigners);
198  BEAST_EXPECT(info.isMember(jss::result) &&
199  info[jss::result].isMember(jss::account_data));
200  BEAST_EXPECT(! info[jss::result][jss::account_data].
201  isMember (jss::signer_lists));
202  BEAST_EXPECT(info.isMember(jss::jsonrpc) && info[jss::jsonrpc] == "2.0");
203  BEAST_EXPECT(info.isMember(jss::ripplerpc) && info[jss::ripplerpc] == "2.0");
204  BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 5);
205  }
206  {
207  // account_info with the "signer_lists" argument.
208  auto const info = env.rpc ("json2", withSigners);
209  BEAST_EXPECT(info.isMember(jss::result) &&
210  info[jss::result].isMember(jss::account_data));
211  auto const& data = info[jss::result][jss::account_data];
212  BEAST_EXPECT(data.isMember (jss::signer_lists));
213  auto const& signerLists = data[jss::signer_lists];
214  BEAST_EXPECT(signerLists.isArray());
215  BEAST_EXPECT(signerLists.size() == 0);
216  BEAST_EXPECT(info.isMember(jss::jsonrpc) && info[jss::jsonrpc] == "2.0");
217  BEAST_EXPECT(info.isMember(jss::ripplerpc) && info[jss::ripplerpc] == "2.0");
218  BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
219  }
220  {
221  // Do both of the above as a batch job
222  auto const info = env.rpc ("json2", '[' + withoutSigners + ", "
223  + withSigners + ']');
224  BEAST_EXPECT(info[0u].isMember(jss::result) &&
225  info[0u][jss::result].isMember(jss::account_data));
226  BEAST_EXPECT(! info[0u][jss::result][jss::account_data].
227  isMember (jss::signer_lists));
228  BEAST_EXPECT(info[0u].isMember(jss::jsonrpc) && info[0u][jss::jsonrpc] == "2.0");
229  BEAST_EXPECT(info[0u].isMember(jss::ripplerpc) && info[0u][jss::ripplerpc] == "2.0");
230  BEAST_EXPECT(info[0u].isMember(jss::id) && info[0u][jss::id] == 5);
231 
232  BEAST_EXPECT(info[1u].isMember(jss::result) &&
233  info[1u][jss::result].isMember(jss::account_data));
234  auto const& data = info[1u][jss::result][jss::account_data];
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  BEAST_EXPECT(info[1u].isMember(jss::jsonrpc) && info[1u][jss::jsonrpc] == "2.0");
240  BEAST_EXPECT(info[1u].isMember(jss::ripplerpc) && info[1u][jss::ripplerpc] == "2.0");
241  BEAST_EXPECT(info[1u].isMember(jss::id) && info[1u][jss::id] == 6);
242  }
243 
244  // Give alice a SignerList.
245  Account const bogie {"bogie"};
246 
247  Json::Value const smallSigners = signers(alice, 2, { { bogie, 3 } });
248  env(smallSigners);
249  {
250  // account_info without the "signer_lists" argument.
251  auto const info = env.rpc ("json2", withoutSigners);
252  BEAST_EXPECT(info.isMember(jss::result) &&
253  info[jss::result].isMember(jss::account_data));
254  BEAST_EXPECT(! info[jss::result][jss::account_data].
255  isMember (jss::signer_lists));
256  BEAST_EXPECT(info.isMember(jss::jsonrpc) && info[jss::jsonrpc] == "2.0");
257  BEAST_EXPECT(info.isMember(jss::ripplerpc) && info[jss::ripplerpc] == "2.0");
258  BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 5);
259  }
260  {
261  // account_info with the "signer_lists" argument.
262  auto const info = env.rpc ("json2", withSigners);
263  BEAST_EXPECT(info.isMember(jss::result) &&
264  info[jss::result].isMember(jss::account_data));
265  auto const& data = info[jss::result][jss::account_data];
266  BEAST_EXPECT(data.isMember (jss::signer_lists));
267  auto const& signerLists = data[jss::signer_lists];
268  BEAST_EXPECT(signerLists.isArray());
269  BEAST_EXPECT(signerLists.size() == 1);
270  auto const& signers = signerLists[0u];
271  BEAST_EXPECT(signers.isObject());
272  BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 2);
273  auto const& signerEntries = signers[sfSignerEntries.jsonName];
274  BEAST_EXPECT(signerEntries.size() == 1);
275  auto const& entry0 = signerEntries[0u][sfSignerEntry.jsonName];
276  BEAST_EXPECT(entry0[sfSignerWeight.jsonName] == 3);
277  BEAST_EXPECT(info.isMember(jss::jsonrpc) && info[jss::jsonrpc] == "2.0");
278  BEAST_EXPECT(info.isMember(jss::ripplerpc) && info[jss::ripplerpc] == "2.0");
279  BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
280  }
281 
282  // Give alice a big signer list
283  Account const demon {"demon"};
284  Account const ghost {"ghost"};
285  Account const haunt {"haunt"};
286  Account const jinni {"jinni"};
287  Account const phase {"phase"};
288  Account const shade {"shade"};
289  Account const spook {"spook"};
290 
291  Json::Value const bigSigners = signers(alice, 4, {
292  {bogie, 1}, {demon, 1}, {ghost, 1}, {haunt, 1},
293  {jinni, 1}, {phase, 1}, {shade, 1}, {spook, 1}, });
294  env(bigSigners);
295  {
296  // account_info with the "signer_lists" argument.
297  auto const info = env.rpc ("json2", withSigners);
298  BEAST_EXPECT(info.isMember(jss::result) &&
299  info[jss::result].isMember(jss::account_data));
300  auto const& data = info[jss::result][jss::account_data];
301  BEAST_EXPECT(data.isMember (jss::signer_lists));
302  auto const& signerLists = data[jss::signer_lists];
303  BEAST_EXPECT(signerLists.isArray());
304  BEAST_EXPECT(signerLists.size() == 1);
305  auto const& signers = signerLists[0u];
306  BEAST_EXPECT(signers.isObject());
307  BEAST_EXPECT(signers[sfSignerQuorum.jsonName] == 4);
308  auto const& signerEntries = signers[sfSignerEntries.jsonName];
309  BEAST_EXPECT(signerEntries.size() == 8);
310  for (unsigned i = 0u; i < 8; ++i)
311  {
312  auto const& entry = signerEntries[i][sfSignerEntry.jsonName];
313  BEAST_EXPECT(entry.size() == 2);
314  BEAST_EXPECT(entry.isMember(sfAccount.jsonName));
315  BEAST_EXPECT(entry[sfSignerWeight.jsonName] == 1);
316  }
317  BEAST_EXPECT(info.isMember(jss::jsonrpc) && info[jss::jsonrpc] == "2.0");
318  BEAST_EXPECT(info.isMember(jss::ripplerpc) && info[jss::ripplerpc] == "2.0");
319  BEAST_EXPECT(info.isMember(jss::id) && info[jss::id] == 6);
320  }
321  }
322 
323  // gRPC stuff
325  {
326  public:
327  org::xrpl::rpc::v1::GetAccountInfoRequest request;
328  org::xrpl::rpc::v1::GetAccountInfoResponse reply;
329 
330  explicit GetAccountInfoClient(std::string const& port)
331  : GRPCTestClientBase(port)
332  {
333  }
334 
335  void
337  {
338  status = stub_->GetAccountInfo(&context, request, &reply);
339  }
340  };
341 
342  void
344  {
345  testcase("gRPC simple");
346 
347  using namespace jtx;
349  std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
350  Env env(*this, std::move(config));
351  Account const alice{"alice"};
352  env.fund(drops(1000 * 1000 * 1000), alice);
353 
354  {
355  // most simple case
356  GetAccountInfoClient client(grpcPort);
357  client.request.mutable_account()->set_address(alice.human());
358  client.GetAccountInfo();
359  if (!BEAST_EXPECT(client.status.ok()))
360  {
361  return;
362  }
363  BEAST_EXPECT(
364  client.reply.account_data().account().value().address() ==
365  alice.human());
366  }
367  {
368  GetAccountInfoClient client(grpcPort);
369  client.request.mutable_account()->set_address(alice.human());
370  client.request.set_queue(true);
371  client.request.mutable_ledger()->set_sequence(3);
372  client.GetAccountInfo();
373  if (!BEAST_EXPECT(client.status.ok()))
374  return;
375  BEAST_EXPECT(
376  client.reply.account_data().balance().value().xrp_amount().drops() ==
377  1000 * 1000 * 1000);
378  BEAST_EXPECT(
379  client.reply.account_data().account().value().address() ==
380  alice.human());
381  BEAST_EXPECT(
382  client.reply.account_data().sequence().value() == env.seq(alice));
383  BEAST_EXPECT(client.reply.queue_data().txn_count() == 0);
384  }
385  }
386 
387  void
389  {
390  testcase("gRPC errors");
391 
392  using namespace jtx;
394  std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
395  Env env(*this, std::move(config));
396  auto getClient = [&grpcPort]() {
397  return GetAccountInfoClient(grpcPort);
398  };
399  Account const alice{"alice"};
400  env.fund(drops(1000 * 1000 * 1000), alice);
401 
402  {
403  // bad address
404  auto client = getClient();
405  client.request.mutable_account()->set_address("deadbeef");
406  client.GetAccountInfo();
407  BEAST_EXPECT(!client.status.ok());
408  }
409  {
410  // no account
411  Account const bogie{"bogie"};
412  auto client = getClient();
413  client.request.mutable_account()->set_address(bogie.human());
414  client.GetAccountInfo();
415  BEAST_EXPECT(!client.status.ok());
416  }
417  {
418  // bad ledger_index
419  auto client = getClient();
420  client.request.mutable_account()->set_address(alice.human());
421  client.request.mutable_ledger()->set_sequence(0);
422  client.GetAccountInfo();
423  BEAST_EXPECT(!client.status.ok());
424  }
425  }
426 
427  void
429  {
430  testcase("gRPC singer lists");
431 
432  using namespace jtx;
434  std::string grpcPort = *(*config)["port_grpc"].get<std::string>("port");
435  Env env(*this, std::move(config));
436  auto getClient = [&grpcPort]() {
437  return GetAccountInfoClient(grpcPort);
438  };
439 
440  Account const alice{"alice"};
441  env.fund(drops(1000 * 1000 * 1000), alice);
442 
443  {
444  auto client = getClient();
445  client.request.mutable_account()->set_address(alice.human());
446  client.request.set_signer_lists(true);
447  client.GetAccountInfo();
448  if (!BEAST_EXPECT(client.status.ok()))
449  return;
450  BEAST_EXPECT(client.reply.signer_list().signer_entries_size() == 0);
451  }
452 
453  // Give alice a SignerList.
454  Account const bogie{"bogie"};
455  Json::Value const smallSigners = signers(alice, 2, {{bogie, 3}});
456  env(smallSigners);
457  {
458  auto client = getClient();
459  client.request.mutable_account()->set_address(alice.human());
460  client.request.set_signer_lists(false);
461  client.GetAccountInfo();
462  if (!BEAST_EXPECT(client.status.ok()))
463  return;
464  BEAST_EXPECT(client.reply.signer_list().signer_entries_size() == 0);
465  }
466  {
467  auto client = getClient();
468  client.request.mutable_account()->set_address(alice.human());
469  client.request.set_signer_lists(true);
470  client.GetAccountInfo();
471  if (!BEAST_EXPECT(client.status.ok()))
472  {
473  return;
474  }
475  BEAST_EXPECT(client.reply.account_data().owner_count().value() == 1);
476  BEAST_EXPECT(client.reply.signer_list().signer_entries_size() == 1);
477  }
478 
479  // Give alice a big signer list
480  Account const demon{"demon"};
481  Account const ghost{"ghost"};
482  Account const haunt{"haunt"};
483  Account const jinni{"jinni"};
484  Account const phase{"phase"};
485  Account const shade{"shade"};
486  Account const spook{"spook"};
487  Json::Value const bigSigners = signers(
488  alice,
489  4,
490  {
491  {bogie, 1},
492  {demon, 1},
493  {ghost, 1},
494  {haunt, 1},
495  {jinni, 1},
496  {phase, 1},
497  {shade, 1},
498  {spook, 1},
499  });
500  env(bigSigners);
501 
502  std::set<std::string> accounts;
503  accounts.insert(bogie.human());
504  accounts.insert(demon.human());
505  accounts.insert(ghost.human());
506  accounts.insert(haunt.human());
507  accounts.insert(jinni.human());
508  accounts.insert(phase.human());
509  accounts.insert(shade.human());
510  accounts.insert(spook.human());
511  {
512  auto client = getClient();
513  client.request.mutable_account()->set_address(alice.human());
514  client.request.set_signer_lists(true);
515  client.GetAccountInfo();
516  if (!BEAST_EXPECT(client.status.ok()))
517  {
518  return;
519  }
520  BEAST_EXPECT(client.reply.account_data().owner_count().value() == 1);
521  auto& signerList = client.reply.signer_list();
522  BEAST_EXPECT(signerList.signer_quorum().value() == 4);
523  BEAST_EXPECT(signerList.signer_entries_size() == 8);
524  for (int i = 0; i < 8; ++i)
525  {
526  BEAST_EXPECT(signerList.signer_entries(i).signer_weight().value() == 1);
527  BEAST_EXPECT(
528  accounts.erase(
529  signerList.signer_entries(i).account().value().address()) == 1);
530  }
531  BEAST_EXPECT(accounts.size() == 0);
532  }
533  }
534 
535  void
536  run() override
537  {
538  testErrors();
539  testSignerLists();
541  testSimpleGrpc();
542  testErrorsGrpc();
544  }
545 };
546 
547 BEAST_DEFINE_TESTSUITE(AccountInfo, app, ripple);
548 
549 } // namespace test
550 } // namespace ripple
ripple::test::jtx::XRP
const XRP_t XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:109
Json::Value::isObject
bool isObject() const
Definition: json_value.cpp:1069
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
std::string
STL class.
ripple::test::jtx::drops
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Definition: amount.h:261
ripple::test::AccountInfo_test::run
void run() override
Definition: AccountInfo_test.cpp:536
ripple::test::AccountInfo_test::testSignerListsV2
void testSignerListsV2()
Definition: AccountInfo_test.cpp:171
ripple::test::GRPCTestClientBase::stub_
std::unique_ptr< org::xrpl::rpc::v1::XRPLedgerAPIService::Stub > stub_
Definition: GRPCTestClientBase.h:43
ripple::sfSignerQuorum
const SF_U32 sfSignerQuorum(access, STI_UINT32, 35, "SignerQuorum")
Definition: SField.h:372
std::set::size
T size(T... args)
ripple::test::jtx::addGrpcConfig
std::unique_ptr< Config > addGrpcConfig(std::unique_ptr< Config >)
add a grpc address and port to config
Definition: envconfig.cpp:112
ripple::sfAccount
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
Definition: SField.h:460
ripple::test::AccountInfo_test::GetAccountInfoClient::request
org::xrpl::rpc::v1::GetAccountInfoRequest request
Definition: AccountInfo_test.cpp:327
ripple::test::jtx::envconfig
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Definition: envconfig.h:52
ripple::sfSignerEntries
const SField sfSignerEntries(access, STI_ARRAY, 4, "SignerEntries")
Definition: SField.h:496
ripple::test::AccountInfo_test::testErrorsGrpc
void testErrorsGrpc()
Definition: AccountInfo_test.cpp:388
ripple::SField::jsonName
const Json::StaticString jsonName
Definition: SField.h:140
ripple::test::GRPCTestClientBase::status
grpc::Status status
Definition: GRPCTestClientBase.h:41
ripple::test::GRPCTestClientBase
Definition: GRPCTestClientBase.h:29
ripple::test::jtx::signers
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
Definition: multisign.cpp:33
ripple::test::AccountInfo_test::GetAccountInfoClient::GetAccountInfoClient
GetAccountInfoClient(std::string const &port)
Definition: AccountInfo_test.cpp:330
ripple::test::AccountInfo_test
Definition: AccountInfo_test.cpp:33
ripple::test::AccountInfo_test::testSignerListsGrpc
void testSignerListsGrpc()
Definition: AccountInfo_test.cpp:428
ripple::test::AccountInfo_test::GetAccountInfoClient::reply
org::xrpl::rpc::v1::GetAccountInfoResponse reply
Definition: AccountInfo_test.cpp:328
std::set::erase
T erase(T... args)
ripple::test::AccountInfo_test::testSimpleGrpc
void testSimpleGrpc()
Definition: AccountInfo_test.cpp:343
ripple::sfSignerEntry
const SField sfSignerEntry(access, STI_OBJECT, 11, "SignerEntry")
Definition: SField.h:488
ripple::test::AccountInfo_test::testSignerLists
void testSignerLists()
Definition: AccountInfo_test.cpp:65
ripple::test::AccountInfo_test::GetAccountInfoClient
Definition: AccountInfo_test.cpp:324
ripple::test::GRPCTestClientBase::context
grpc::ClientContext context
Definition: GRPCTestClientBase.h:42
ripple::test::AccountInfo_test::GetAccountInfoClient::GetAccountInfo
void GetAccountInfo()
Definition: AccountInfo_test.cpp:336
ripple::sfSignerWeight
const SF_U16 sfSignerWeight(access, STI_UINT16, 3, "SignerWeight")
Definition: SField.h:332
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
std::set::insert
T insert(T... args)
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:214
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
std::unique_ptr
STL class.
ripple::test::AccountInfo_test::testErrors
void testErrors()
Definition: AccountInfo_test.cpp:37
std::set< std::string >
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:117
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:688
Json::Value
Represents a JSON value.
Definition: json_value.h:141