rippled
AccountTx_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2017 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/beast/unit_test.h>
21 #include <ripple/protocol/ErrorCodes.h>
22 #include <ripple/protocol/jss.h>
23 #include <test/jtx.h>
24 
25 #include <boost/container/flat_set.hpp>
26 
27 namespace ripple {
28 
29 namespace test {
30 
31 class AccountTx_test : public beast::unit_test::suite
32 {
33  // A data structure used to describe the basic structure of a
34  // transactions array node as returned by the account_tx RPC command.
35  struct NodeSanity
36  {
37  int const index;
39  boost::container::flat_set<std::string> created;
40  boost::container::flat_set<std::string> deleted;
41  boost::container::flat_set<std::string> modified;
42 
44  int idx,
45  Json::StaticString const& t,
49  : index(idx), txType(t)
50  {
51  auto buildSet = [](auto&& init) {
52  boost::container::flat_set<std::string> r;
53  r.reserve(init.size());
54  for (auto&& s : init)
55  r.insert(s);
56  return r;
57  };
58 
59  created = buildSet(c);
60  deleted = buildSet(d);
61  modified = buildSet(m);
62  }
63  };
64 
65  // A helper method tests can use to validate returned JSON vs NodeSanity.
66  void
67  checkSanity(Json::Value const& txNode, NodeSanity const& sane)
68  {
69  BEAST_EXPECT(txNode[jss::validated].asBool() == true);
70  BEAST_EXPECT(
71  txNode[jss::tx][sfTransactionType.jsonName].asString() ==
72  sane.txType);
73 
74  // Make sure all of the expected node types are present.
75  boost::container::flat_set<std::string> createdNodes;
76  boost::container::flat_set<std::string> deletedNodes;
77  boost::container::flat_set<std::string> modifiedNodes;
78 
79  for (Json::Value const& metaNode :
80  txNode[jss::meta][sfAffectedNodes.jsonName])
81  {
82  if (metaNode.isMember(sfCreatedNode.jsonName))
83  createdNodes.insert(
85  .asString());
86 
87  else if (metaNode.isMember(sfDeletedNode.jsonName))
88  deletedNodes.insert(
90  .asString());
91 
92  else if (metaNode.isMember(sfModifiedNode.jsonName))
93  modifiedNodes.insert(metaNode[sfModifiedNode.jsonName]
95  .asString());
96 
97  else
98  fail(
99  "Unexpected or unlabeled node type in metadata.",
100  __FILE__,
101  __LINE__);
102  }
103 
104  BEAST_EXPECT(createdNodes == sane.created);
105  BEAST_EXPECT(deletedNodes == sane.deleted);
106  BEAST_EXPECT(modifiedNodes == sane.modified);
107  };
108 
109  void
111  {
112  using namespace test::jtx;
113 
114  Env env(*this);
115  Account A1{"A1"};
116  env.fund(XRP(10000), A1);
117  env.close();
118 
119  // Ledger 3 has the two txs associated with funding the account
120  // All other ledgers have no txs
121 
122  auto hasTxs = [](Json::Value const& j) {
123  return j.isMember(jss::result) &&
124  (j[jss::result][jss::status] == "success") &&
125  (j[jss::result][jss::transactions].size() == 2) &&
126  (j[jss::result][jss::transactions][0u][jss::tx]
127  [jss::TransactionType] == jss::AccountSet) &&
128  (j[jss::result][jss::transactions][1u][jss::tx]
129  [jss::TransactionType] == jss::Payment);
130  };
131 
132  auto noTxs = [](Json::Value const& j) {
133  return j.isMember(jss::result) &&
134  (j[jss::result][jss::status] == "success") &&
135  (j[jss::result][jss::transactions].size() == 0);
136  };
137 
138  auto isErr = [](Json::Value const& j, error_code_i code) {
139  return j.isMember(jss::result) &&
140  j[jss::result].isMember(jss::error) &&
141  j[jss::result][jss::error] == RPC::get_error_info(code).token;
142  };
143 
144  Json::Value jParms;
145 
146  BEAST_EXPECT(isErr(
147  env.rpc("json", "account_tx", to_string(jParms)),
149 
150  jParms[jss::account] = "0xDEADBEEF";
151 
152  BEAST_EXPECT(isErr(
153  env.rpc("json", "account_tx", to_string(jParms)),
155 
156  jParms[jss::account] = A1.human();
157  BEAST_EXPECT(hasTxs(env.rpc("json", "account_tx", to_string(jParms))));
158 
159  // Ledger min/max index
160  {
161  Json::Value p{jParms};
162  p[jss::ledger_index_min] = -1;
163  p[jss::ledger_index_max] = -1;
164  BEAST_EXPECT(hasTxs(env.rpc("json", "account_tx", to_string(p))));
165 
166  p[jss::ledger_index_min] = 0;
167  p[jss::ledger_index_max] = 100;
168  BEAST_EXPECT(hasTxs(env.rpc("json", "account_tx", to_string(p))));
169 
170  p[jss::ledger_index_min] = 1;
171  p[jss::ledger_index_max] = 2;
172  BEAST_EXPECT(noTxs(env.rpc("json", "account_tx", to_string(p))));
173 
174  p[jss::ledger_index_min] = 2;
175  p[jss::ledger_index_max] = 1;
176  BEAST_EXPECT(isErr(
177  env.rpc("json", "account_tx", to_string(p)),
179  }
180 
181  // Ledger index min only
182  {
183  Json::Value p{jParms};
184  p[jss::ledger_index_min] = -1;
185  BEAST_EXPECT(hasTxs(env.rpc("json", "account_tx", to_string(p))));
186 
187  p[jss::ledger_index_min] = 1;
188  BEAST_EXPECT(hasTxs(env.rpc("json", "account_tx", to_string(p))));
189 
190  p[jss::ledger_index_min] = env.current()->info().seq;
191  BEAST_EXPECT(isErr(
192  env.rpc("json", "account_tx", to_string(p)),
194  }
195 
196  // Ledger index max only
197  {
198  Json::Value p{jParms};
199  p[jss::ledger_index_max] = -1;
200  BEAST_EXPECT(hasTxs(env.rpc("json", "account_tx", to_string(p))));
201 
202  p[jss::ledger_index_max] = env.current()->info().seq;
203  BEAST_EXPECT(hasTxs(env.rpc("json", "account_tx", to_string(p))));
204 
205  p[jss::ledger_index_max] = env.closed()->info().seq;
206  BEAST_EXPECT(hasTxs(env.rpc("json", "account_tx", to_string(p))));
207 
208  p[jss::ledger_index_max] = env.closed()->info().seq - 1;
209  BEAST_EXPECT(noTxs(env.rpc("json", "account_tx", to_string(p))));
210  }
211 
212  // Ledger Sequence
213  {
214  Json::Value p{jParms};
215 
216  p[jss::ledger_index] = env.closed()->info().seq;
217  BEAST_EXPECT(hasTxs(env.rpc("json", "account_tx", to_string(p))));
218 
219  p[jss::ledger_index] = env.closed()->info().seq - 1;
220  BEAST_EXPECT(noTxs(env.rpc("json", "account_tx", to_string(p))));
221 
222  p[jss::ledger_index] = env.current()->info().seq;
223  BEAST_EXPECT(isErr(
224  env.rpc("json", "account_tx", to_string(p)),
226 
227  p[jss::ledger_index] = env.current()->info().seq + 1;
228  BEAST_EXPECT(isErr(
229  env.rpc("json", "account_tx", to_string(p)), rpcLGR_NOT_FOUND));
230  }
231 
232  // Ledger Hash
233  {
234  Json::Value p{jParms};
235 
236  p[jss::ledger_hash] = to_string(env.closed()->info().hash);
237  BEAST_EXPECT(hasTxs(env.rpc("json", "account_tx", to_string(p))));
238 
239  p[jss::ledger_hash] = to_string(env.closed()->info().parentHash);
240  BEAST_EXPECT(noTxs(env.rpc("json", "account_tx", to_string(p))));
241  }
242  }
243 
244  void
246  {
247  // Get results for all transaction types that can be associated
248  // with an account. Start by generating all transaction types.
249  using namespace test::jtx;
250  using namespace std::chrono_literals;
251 
252  Env env(*this);
253  Account const alice{"alice"};
254  Account const alie{"alie"};
255  Account const gw{"gw"};
256  auto const USD{gw["USD"]};
257 
258  env.fund(XRP(1000000), alice, gw);
259  env.close();
260 
261  // AccountSet
262  env(noop(alice));
263 
264  // Payment
265  env(pay(alice, gw, XRP(100)));
266 
267  // Regular key set
268  env(regkey(alice, alie));
269  env.close();
270 
271  // Trust and Offers
272  env(trust(alice, USD(200)), sig(alie));
273  std::uint32_t const offerSeq{env.seq(alice)};
274  env(offer(alice, USD(50), XRP(150)), sig(alie));
275  env.close();
276 
277  {
278  Json::Value cancelOffer;
279  cancelOffer[jss::Account] = alice.human();
280  cancelOffer[jss::OfferSequence] = offerSeq;
281  cancelOffer[jss::TransactionType] = jss::OfferCancel;
282  env(cancelOffer, sig(alie));
283  }
284  env.close();
285 
286  // SignerListSet
287  env(signers(alice, 1, {{"bogie", 1}, {"demon", 1}}), sig(alie));
288 
289  // Escrow
290  {
291  // Create an escrow. Requires either a CancelAfter or FinishAfter.
292  auto escrow = [](Account const& account,
293  Account const& to,
294  STAmount const& amount) {
295  Json::Value escro;
296  escro[jss::TransactionType] = jss::EscrowCreate;
297  escro[jss::Flags] = tfUniversal;
298  escro[jss::Account] = account.human();
299  escro[jss::Destination] = to.human();
300  escro[jss::Amount] = amount.getJson(JsonOptions::none);
301  return escro;
302  };
303 
304  NetClock::time_point const nextTime{env.now() + 2s};
305 
306  Json::Value escrowWithFinish{escrow(alice, alice, XRP(500))};
307  escrowWithFinish[sfFinishAfter.jsonName] =
308  nextTime.time_since_epoch().count();
309 
310  std::uint32_t const escrowFinishSeq{env.seq(alice)};
311  env(escrowWithFinish, sig(alie));
312 
313  Json::Value escrowWithCancel{escrow(alice, alice, XRP(500))};
314  escrowWithCancel[sfFinishAfter.jsonName] =
315  nextTime.time_since_epoch().count();
316  escrowWithCancel[sfCancelAfter.jsonName] =
317  nextTime.time_since_epoch().count() + 1;
318 
319  std::uint32_t const escrowCancelSeq{env.seq(alice)};
320  env(escrowWithCancel, sig(alie));
321  env.close();
322 
323  {
324  Json::Value escrowFinish;
325  escrowFinish[jss::TransactionType] = jss::EscrowFinish;
326  escrowFinish[jss::Flags] = tfUniversal;
327  escrowFinish[jss::Account] = alice.human();
328  escrowFinish[sfOwner.jsonName] = alice.human();
329  escrowFinish[sfOfferSequence.jsonName] = escrowFinishSeq;
330  env(escrowFinish, sig(alie));
331  }
332  {
333  Json::Value escrowCancel;
334  escrowCancel[jss::TransactionType] = jss::EscrowCancel;
335  escrowCancel[jss::Flags] = tfUniversal;
336  escrowCancel[jss::Account] = alice.human();
337  escrowCancel[sfOwner.jsonName] = alice.human();
338  escrowCancel[sfOfferSequence.jsonName] = escrowCancelSeq;
339  env(escrowCancel, sig(alie));
340  }
341  env.close();
342  }
343 
344  // PayChan
345  {
346  std::uint32_t payChanSeq{env.seq(alice)};
347  Json::Value payChanCreate;
348  payChanCreate[jss::TransactionType] = jss::PaymentChannelCreate;
349  payChanCreate[jss::Flags] = tfUniversal;
350  payChanCreate[jss::Account] = alice.human();
351  payChanCreate[jss::Destination] = gw.human();
352  payChanCreate[jss::Amount] =
353  XRP(500).value().getJson(JsonOptions::none);
354  payChanCreate[sfSettleDelay.jsonName] =
355  NetClock::duration{100s}.count();
356  payChanCreate[sfPublicKey.jsonName] = strHex(alice.pk().slice());
357  env(payChanCreate, sig(alie));
358  env.close();
359 
360  std::string const payChanIndex{
361  strHex(keylet::payChan(alice, gw, payChanSeq).key)};
362 
363  {
364  Json::Value payChanFund;
365  payChanFund[jss::TransactionType] = jss::PaymentChannelFund;
366  payChanFund[jss::Flags] = tfUniversal;
367  payChanFund[jss::Account] = alice.human();
368  payChanFund[sfPayChannel.jsonName] = payChanIndex;
369  payChanFund[jss::Amount] =
370  XRP(200).value().getJson(JsonOptions::none);
371  env(payChanFund, sig(alie));
372  env.close();
373  }
374  {
375  Json::Value payChanClaim;
376  payChanClaim[jss::TransactionType] = jss::PaymentChannelClaim;
377  payChanClaim[jss::Flags] = tfClose;
378  payChanClaim[jss::Account] = gw.human();
379  payChanClaim[sfPayChannel.jsonName] = payChanIndex;
380  payChanClaim[sfPublicKey.jsonName] = strHex(alice.pk().slice());
381  env(payChanClaim);
382  env.close();
383  }
384  }
385 
386  // Check
387  {
388  uint256 const aliceCheckId{getCheckIndex(alice, env.seq(alice))};
389  env(check::create(alice, gw, XRP(300)), sig(alie));
390 
391  uint256 const gwCheckId{getCheckIndex(gw, env.seq(gw))};
392  env(check::create(gw, alice, XRP(200)));
393  env.close();
394 
395  env(check::cash(alice, gwCheckId, XRP(200)), sig(alie));
396  env(check::cancel(alice, aliceCheckId), sig(alie));
397  env.close();
398  }
399 
400  // Deposit preauthorization.
401  env(deposit::auth(alice, gw), sig(alie));
402  env.close();
403 
404  // Setup is done. Look at the transactions returned by account_tx.
405  Json::Value params;
406  params[jss::account] = alice.human();
407  params[jss::ledger_index_min] = -1;
408  params[jss::ledger_index_max] = -1;
409 
410  Json::Value const result{
411  env.rpc("json", "account_tx", to_string(params))};
412 
413  BEAST_EXPECT(result[jss::result][jss::status] == "success");
414  BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
415 
416  Json::Value const& txs{result[jss::result][jss::transactions]};
417 
418  // Do a sanity check on each returned transaction. They should
419  // be returned in the reverse order of application to the ledger.
420  static const NodeSanity sanity[]{
421  // txType, created, deleted, modified
422  {0,
423  jss::DepositPreauth,
424  {jss::DepositPreauth},
425  {},
426  {jss::AccountRoot, jss::DirectoryNode}},
427  {1,
428  jss::CheckCancel,
429  {},
430  {jss::Check},
431  {jss::AccountRoot,
432  jss::AccountRoot,
433  jss::DirectoryNode,
434  jss::DirectoryNode}},
435  {2,
436  jss::CheckCash,
437  {},
438  {jss::Check},
439  {jss::AccountRoot,
440  jss::AccountRoot,
441  jss::DirectoryNode,
442  jss::DirectoryNode}},
443  {3,
444  jss::CheckCreate,
445  {jss::Check},
446  {},
447  {jss::AccountRoot,
448  jss::AccountRoot,
449  jss::DirectoryNode,
450  jss::DirectoryNode}},
451  {4,
452  jss::CheckCreate,
453  {jss::Check},
454  {},
455  {jss::AccountRoot,
456  jss::AccountRoot,
457  jss::DirectoryNode,
458  jss::DirectoryNode}},
459  {5,
460  jss::PaymentChannelClaim,
461  {},
462  {jss::PayChannel},
463  {jss::AccountRoot,
464  jss::AccountRoot,
465  jss::DirectoryNode,
466  jss::DirectoryNode}},
467  {6,
468  jss::PaymentChannelFund,
469  {},
470  {},
471  {jss::AccountRoot, jss::PayChannel}},
472  {7,
473  jss::PaymentChannelCreate,
474  {jss::PayChannel},
475  {},
476  {jss::AccountRoot,
477  jss::AccountRoot,
478  jss::DirectoryNode,
479  jss::DirectoryNode}},
480  {8,
481  jss::EscrowCancel,
482  {},
483  {jss::Escrow},
484  {jss::AccountRoot, jss::DirectoryNode}},
485  {9,
486  jss::EscrowFinish,
487  {},
488  {jss::Escrow},
489  {jss::AccountRoot, jss::DirectoryNode}},
490  {10,
491  jss::EscrowCreate,
492  {jss::Escrow},
493  {},
494  {jss::AccountRoot, jss::DirectoryNode}},
495  {11,
496  jss::EscrowCreate,
497  {jss::Escrow},
498  {},
499  {jss::AccountRoot, jss::DirectoryNode}},
500  {12,
501  jss::SignerListSet,
502  {jss::SignerList},
503  {},
504  {jss::AccountRoot, jss::DirectoryNode}},
505  {13,
506  jss::OfferCancel,
507  {},
508  {jss::Offer, jss::DirectoryNode},
509  {jss::AccountRoot, jss::DirectoryNode}},
510  {14,
511  jss::OfferCreate,
512  {jss::Offer, jss::DirectoryNode},
513  {},
514  {jss::AccountRoot, jss::DirectoryNode}},
515  {15,
516  jss::TrustSet,
517  {jss::RippleState, jss::DirectoryNode, jss::DirectoryNode},
518  {},
519  {jss::AccountRoot, jss::AccountRoot}},
520  {16, jss::SetRegularKey, {}, {}, {jss::AccountRoot}},
521  {17, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
522  {18, jss::AccountSet, {}, {}, {jss::AccountRoot}},
523  {19, jss::AccountSet, {}, {}, {jss::AccountRoot}},
524  {20, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
525  };
526 
527  BEAST_EXPECT(
528  std::extent<decltype(sanity)>::value ==
529  result[jss::result][jss::transactions].size());
530 
531  for (unsigned int index{0};
532  index < std::extent<decltype(sanity)>::value;
533  ++index)
534  {
535  checkSanity(txs[index], sanity[index]);
536  }
537  }
538 
539  void
541  {
542  // Verify that if an account is resurrected then the account_tx RPC
543  // command still recovers all transactions on that account before
544  // and after resurrection.
545  using namespace test::jtx;
546  using namespace std::chrono_literals;
547 
548  Env env(*this);
549  Account const alice{"alice"};
550  Account const becky{"becky"};
551 
552  env.fund(XRP(10000), alice, becky);
553  env.close();
554 
555  // Verify that becky's account root is present.
556  Keylet const beckyAcctKey{keylet::account(becky.id())};
557  BEAST_EXPECT(env.closed()->exists(beckyAcctKey));
558 
559  // becky does an AccountSet .
560  env(noop(becky));
561 
562  // Close enough ledgers to be able to delete becky's account.
563  std::uint32_t const ledgerCount{
564  env.current()->seq() + 257 - env.seq(becky)};
565 
566  for (std::uint32_t i = 0; i < ledgerCount; ++i)
567  env.close();
568 
569  auto const beckyPreDelBalance{env.balance(becky)};
570 
571  auto const acctDelFee{drops(env.current()->fees().increment)};
572  env(acctdelete(becky, alice), fee(acctDelFee));
573  env.close();
574 
575  // Verify that becky's account root is gone.
576  BEAST_EXPECT(!env.closed()->exists(beckyAcctKey));
577 
578  // All it takes is a large enough XRP payment to resurrect
579  // becky's account. Try too small a payment.
580  env(pay(alice, becky, XRP(19)), ter(tecNO_DST_INSUF_XRP));
581  env.close();
582 
583  // Actually resurrect becky's account.
584  env(pay(alice, becky, XRP(45)));
585  env.close();
586 
587  // becky's account root should be back.
588  BEAST_EXPECT(env.closed()->exists(beckyAcctKey));
589  BEAST_EXPECT(env.balance(becky) == XRP(45));
590 
591  // becky pays alice.
592  env(pay(becky, alice, XRP(20)));
593  env.close();
594 
595  // Setup is done. Look at the transactions returned by account_tx.
596  // Verify that account_tx locates all of becky's transactions.
597  Json::Value params;
598  params[jss::account] = becky.human();
599  params[jss::ledger_index_min] = -1;
600  params[jss::ledger_index_max] = -1;
601 
602  Json::Value const result{
603  env.rpc("json", "account_tx", to_string(params))};
604 
605  BEAST_EXPECT(result[jss::result][jss::status] == "success");
606  BEAST_EXPECT(result[jss::result][jss::transactions].isArray());
607 
608  Json::Value const& txs{result[jss::result][jss::transactions]};
609 
610  // Do a sanity check on each returned transaction. They should
611  // be returned in the reverse order of application to the ledger.
612  static const NodeSanity sanity[]{
613  // txType, created, deleted,
614  // modified
615  /* becky pays alice */ {
616  0, jss::Payment, {}, {}, {jss::AccountRoot, jss::AccountRoot}},
617  /* alice resurrects becky's acct */
618  {1, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}},
619  /* becky deletes her account */
620  {2, jss::AccountDelete, {}, {jss::AccountRoot}, {jss::AccountRoot}},
621  /* becky's noop */
622  {3, jss::AccountSet, {}, {}, {jss::AccountRoot}},
623  /* "fund" sets flags */
624  {4, jss::AccountSet, {}, {}, {jss::AccountRoot}},
625  /* "fund" creates becky's acct */
626  {5, jss::Payment, {jss::AccountRoot}, {}, {jss::AccountRoot}}};
627 
628  BEAST_EXPECT(
629  std::extent<decltype(sanity)>::value ==
630  result[jss::result][jss::transactions].size());
631 
632  for (unsigned int index{0};
633  index < std::extent<decltype(sanity)>::value;
634  ++index)
635  {
636  checkSanity(txs[index], sanity[index]);
637  }
638  }
639 
640 public:
641  void
642  run() override
643  {
644  testParameters();
645  testContents();
647  }
648 };
649 BEAST_DEFINE_TESTSUITE(AccountTx, app, ripple);
650 
651 } // namespace test
652 } // namespace ripple
ripple::test::AccountTx_test::testParameters
void testParameters()
Definition: AccountTx_test.cpp:110
ripple::test::AccountTx_test::NodeSanity::NodeSanity
NodeSanity(int idx, Json::StaticString const &t, std::initializer_list< char const * > c, std::initializer_list< char const * > d, std::initializer_list< char const * > m)
Definition: AccountTx_test.cpp:43
ripple::test::AccountTx_test::NodeSanity::txType
Json::StaticString const & txType
Definition: AccountTx_test.cpp:38
ripple::test::jtx::noop
Json::Value noop(Account const &account)
The null transaction.
Definition: noop.h:31
ripple::test::jtx::XRP
const XRP_t XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
ripple::Keylet
A pair of SHAMap key and LedgerEntryType.
Definition: Keylet.h:38
ripple::rpcLGR_IDXS_INVALID
@ rpcLGR_IDXS_INVALID
Definition: ErrorCodes.h:112
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountDelete, app, ripple)
std::string
STL class.
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
ripple::HashPrefix::txNode
@ txNode
transaction plus metadata
ripple::test::jtx::drops
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Definition: amount.h:241
ripple::sfLedgerEntryType
const SF_U16 sfLedgerEntryType(access, STI_UINT16, 1, "LedgerEntryType", SField::sMD_Never)
Definition: SField.h:345
ripple::RPC::get_error_info
ErrorInfo const & get_error_info(error_code_i code)
Returns an ErrorInfo that reflects the error code.
Definition: ErrorCodes.cpp:194
ripple::test::jtx::ter
Set the expected result code for a JTx The test will fail if the code doesn't match.
Definition: ter.h:33
ripple::test::jtx::Env::closed
std::shared_ptr< ReadView const > closed()
Returns the last closed ledger.
Definition: Env.cpp:105
ripple::tfClose
const std::uint32_t tfClose
Definition: TxFlags.h:106
ripple::test::jtx::trust
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Definition: trust.cpp:30
ripple::keylet::payChan
Keylet payChan(AccountID const &source, AccountID const &dst, std::uint32_t seq)
A PaymentChannel.
Definition: Indexes.cpp:326
std::chrono::duration
ripple::test::AccountTx_test::NodeSanity::index
const int index
Definition: AccountTx_test.cpp:37
ripple::test::AccountTx_test::NodeSanity
Definition: AccountTx_test.cpp:35
ripple::test::jtx::Env::balance
PrettyAmount balance(Account const &account) const
Returns the XRP balance on an account.
Definition: Env.cpp:156
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:41
ripple::sfPayChannel
const SF_U256 sfPayChannel(access, STI_HASH256, 22, "Channel")
Definition: SField.h:432
ripple::test::jtx::offer
Json::Value offer(Account const &account, STAmount const &in, STAmount const &out, std::uint32_t flags)
Create an offer.
Definition: offer.cpp:28
ripple::test::AccountTx_test::testContents
void testContents()
Definition: AccountTx_test.cpp:245
ripple::rpcLGR_NOT_FOUND
@ rpcLGR_NOT_FOUND
Definition: ErrorCodes.h:72
ripple::sfModifiedNode
const SField sfModifiedNode(access, STI_OBJECT, 5, "ModifiedNode")
Definition: SField.h:496
ripple::SField::jsonName
const Json::StaticString jsonName
Definition: SField.h:133
ripple::sfFinishAfter
const SF_U32 sfFinishAfter(access, STI_UINT32, 37, "FinishAfter")
Definition: SField.h:389
ripple::error_code_i
error_code_i
Definition: ErrorCodes.h:40
ripple::tecNO_DST_INSUF_XRP
@ tecNO_DST_INSUF_XRP
Definition: TER.h:249
ripple::base_uint< 256 >
ripple::test::AccountTx_test::run
void run() override
Definition: AccountTx_test.cpp:642
ripple::getCheckIndex
uint256 getCheckIndex(AccountID const &account, std::uint32_t uSequence)
Definition: Indexes.cpp:168
std::extent
ripple::sfOwner
const SF_Account sfOwner(access, STI_ACCOUNT, 2, "Owner")
Definition: SField.h:475
ripple::test::jtx::signers
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
Definition: multisign.cpp:33
ripple::keylet::account
static const account_t account
Definition: Indexes.h:120
ripple::JsonOptions::none
@ none
ripple::sfTransactionType
const SF_U16 sfTransactionType(access, STI_UINT16, 2, "TransactionType")
Definition: SField.h:346
ripple::STAmount
Definition: STAmount.h:42
ripple::test::AccountTx_test::NodeSanity::deleted
boost::container::flat_set< std::string > deleted
Definition: AccountTx_test.cpp:40
std::chrono::time_point
ripple::test::AccountTx_test
Definition: AccountTx_test.cpp:31
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:932
std::uint32_t
ripple::test::jtx::sig
Set the regular signature on a JTx.
Definition: sig.h:33
ripple::test::jtx::Env::seq
std::uint32_t seq(Account const &account) const
Returns the next sequence number on account.
Definition: Env.cpp:180
ripple::sfCreatedNode
const SField sfCreatedNode(access, STI_OBJECT, 3, "CreatedNode")
Definition: SField.h:494
ripple::tfUniversal
const std::uint32_t tfUniversal
Definition: TxFlags.h:49
ripple::test::jtx::fee
Set the fee on a JTx.
Definition: fee.h:34
ripple::sfPublicKey
const SF_Blob sfPublicKey(access, STI_VL, 1, "PublicKey")
Definition: SField.h:454
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::test::AccountTx_test::testAccountDelete
void testAccountDelete()
Definition: AccountTx_test.cpp:540
ripple::test::jtx::pay
Json::Value pay(Account const &account, Account const &to, AnyAmount amount)
Create a payment.
Definition: pay.cpp:29
ripple::test::jtx::Env::now
NetClock::time_point now()
Returns the current Ripple Network Time.
Definition: Env.h:261
ripple::sfOfferSequence
const SF_U32 sfOfferSequence(access, STI_UINT32, 25, "OfferSequence")
Definition: SField.h:377
ripple::rpcLGR_NOT_VALIDATED
@ rpcLGR_NOT_VALIDATED
Definition: ErrorCodes.h:73
ripple::sfAffectedNodes
const SField sfAffectedNodes(access, STI_ARRAY, 8, "AffectedNodes")
Definition: SField.h:514
ripple::test::jtx::Env::close
void close(NetClock::time_point closeTime, boost::optional< std::chrono::milliseconds > consensusDelay=boost::none)
Close and advance the ledger.
Definition: Env.cpp:111
ripple::test::jtx::regkey
Json::Value regkey(Account const &account, disabled_t)
Disable the regular key.
Definition: regkey.cpp:28
Json::StaticString
Lightweight wrapper to tag static string.
Definition: json_value.h:60
ripple::test::AccountTx_test::checkSanity
void checkSanity(Json::Value const &txNode, NodeSanity const &sane)
Definition: AccountTx_test.cpp:67
ripple::test::jtx::Env::fund
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
Definition: Env.cpp:201
ripple::test::jtx::acctdelete
Json::Value acctdelete(Account const &account, Account const &dest)
Delete account.
Definition: acctdelete.cpp:29
std::chrono::duration::count
T count(T... args)
ripple::sfSettleDelay
const SF_U32 sfSettleDelay(access, STI_UINT32, 39, "SettleDelay")
Definition: SField.h:391
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:67
ripple::test::AccountTx_test::NodeSanity::modified
boost::container::flat_set< std::string > modified
Definition: AccountTx_test.cpp:41
ripple::test::AccountTx_test::NodeSanity::created
boost::container::flat_set< std::string > created
Definition: AccountTx_test.cpp:39
ripple::sfDeletedNode
const SField sfDeletedNode(access, STI_OBJECT, 4, "DeletedNode")
Definition: SField.h:495
ripple::test::jtx::Env::current
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:297
ripple::sfCancelAfter
const SF_U32 sfCancelAfter(access, STI_UINT32, 36, "CancelAfter")
Definition: SField.h:388
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:114
ripple::RPC::ErrorInfo::token
Json::StaticString token
Definition: ErrorCodes.h:174
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:676
Json::Value
Represents a JSON value.
Definition: json_value.h:145
std::initializer_list