rippled
Check_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012-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 <test/jtx.h>
21 #include <ripple/protocol/Feature.h>
22 #include <ripple/protocol/jss.h>
23 
24 namespace ripple {
25 namespace test {
26 namespace jtx {
27 
30 {
31 private:
33 
34 public:
35  explicit expiration (NetClock::time_point const& expiry)
36  : expry_{expiry.time_since_epoch().count()}
37  {
38  }
39 
40  void
41  operator()(Env&, JTx& jt) const
42  {
44  }
45 };
46 
49 {
50 private:
52 
53 public:
54  explicit source_tag (std::uint32_t tag)
55  : tag_{tag}
56  {
57  }
58 
59  void
60  operator()(Env&, JTx& jt) const
61  {
63  }
64 };
65 
67 class dest_tag
68 {
69 private:
71 
72 public:
73  explicit dest_tag (std::uint32_t tag)
74  : tag_{tag}
75  {
76  }
77 
78  void
79  operator()(Env&, JTx& jt) const
80  {
82  }
83 };
84 
85 } // namespace jtx
86 } // namespace test
87 
88 class Check_test : public beast::unit_test::suite
89 {
90  // Helper function that returns the Checks on an account.
93  {
95  forEachItem (*env.current (), account,
96  [&result](std::shared_ptr<SLE const> const& sle)
97  {
98  if (sle->getType() == ltCHECK)
99  result.push_back (sle);
100  });
101  return result;
102  }
103 
104  // Helper function that returns the owner count on an account.
105  static std::uint32_t
106  ownerCount (test::jtx::Env const& env, test::jtx::Account const& account)
107  {
108  std::uint32_t ret {0};
109  if (auto const sleAccount = env.le(account))
110  ret = sleAccount->getFieldU32(sfOwnerCount);
111  return ret;
112  }
113 
114  // Helper function that verifies the expected DeliveredAmount is present.
115  //
116  // NOTE: the function _infers_ the transaction to operate on by calling
117  // env.tx(), which returns the result from the most recent transaction.
118  void verifyDeliveredAmount (test::jtx::Env& env, STAmount const& amount)
119  {
120  // Get the hash for the most recent transaction.
121  std::string const txHash {
122  env.tx()->getJson (JsonOptions::none)[jss::hash].asString()};
123 
124  // Verify DeliveredAmount and delivered_amount metadata are correct.
125  env.close();
126  Json::Value const meta = env.rpc ("tx", txHash)[jss::result][jss::meta];
127 
128  // Expect there to be a DeliveredAmount field.
129  if (! BEAST_EXPECT(meta.isMember (sfDeliveredAmount.jsonName)))
130  return;
131 
132  // DeliveredAmount and delivered_amount should both be present and
133  // equal amount.
134  BEAST_EXPECT (meta[sfDeliveredAmount.jsonName] ==
135  amount.getJson (JsonOptions::none));
136  BEAST_EXPECT (meta[jss::delivered_amount] ==
137  amount.getJson (JsonOptions::none));
138  }
139 
140  void testEnabled()
141  {
142  testcase ("Enabled");
143 
144  using namespace test::jtx;
145  Account const alice {"alice"};
146  {
147  // If the Checks amendment is not enabled, you should not be able
148  // to create, cash, or cancel checks.
149  Env env {*this, supported_amendments() - featureChecks};
150 
151  env.fund (XRP(1000), alice);
152 
153  uint256 const checkId {
154  getCheckIndex (env.master, env.seq (env.master))};
155  env (check::create (env.master, alice, XRP(100)),
156  ter(temDISABLED));
157  env.close();
158 
159  env (check::cash (alice, checkId, XRP(100)),
160  ter (temDISABLED));
161  env.close();
162 
163  env (check::cancel (alice, checkId), ter (temDISABLED));
164  env.close();
165  }
166  {
167  // If the Checks amendment is enabled all check-related
168  // facilities should be available.
169  Env env {*this};
170 
171  env.fund (XRP(1000), alice);
172 
173  uint256 const checkId1 {
174  getCheckIndex (env.master, env.seq (env.master))};
175  env (check::create (env.master, alice, XRP(100)));
176  env.close();
177 
178  env (check::cash (alice, checkId1, XRP(100)));
179  env.close();
180 
181  uint256 const checkId2 {
182  getCheckIndex (env.master, env.seq (env.master))};
183  env (check::create (env.master, alice, XRP(100)));
184  env.close();
185 
186  env (check::cancel (alice, checkId2));
187  env.close();
188  }
189  }
190 
192  {
193  // Explore many of the valid ways to create a check.
194  testcase ("Create valid");
195 
196  using namespace test::jtx;
197 
198  Account const gw {"gateway"};
199  Account const alice {"alice"};
200  Account const bob {"bob"};
201  IOU const USD {gw["USD"]};
202 
203  Env env {*this};
204 
205  STAmount const startBalance {XRP(1000).value()};
206  env.fund (startBalance, gw, alice, bob);
207 
208  // Note that no trust line has been set up for alice, but alice can
209  // still write a check for USD. You don't have to have the funds
210  // necessary to cover a check in order to write a check.
211  auto writeTwoChecks =
212  [&env, &USD, this] (Account const& from, Account const& to)
213  {
214  std::uint32_t const fromOwnerCount {ownerCount (env, from)};
215  std::uint32_t const toOwnerCount {ownerCount (env, to )};
216 
217  std::size_t const fromCkCount {checksOnAccount (env, from).size()};
218  std::size_t const toCkCount {checksOnAccount (env, to ).size()};
219 
220  env (check::create (from, to, XRP(2000)));
221  env.close();
222 
223  env (check::create (from, to, USD(50)));
224  env.close();
225 
226  BEAST_EXPECT (
227  checksOnAccount (env, from).size() == fromCkCount + 2);
228  BEAST_EXPECT (
229  checksOnAccount (env, to ).size() == toCkCount + 2);
230 
231  env.require (owners (from, fromOwnerCount + 2));
232  env.require (owners (to,
233  to == from ? fromOwnerCount + 2 : toOwnerCount));
234  };
235  // from to
236  writeTwoChecks (alice, bob);
237  writeTwoChecks (gw, alice);
238  writeTwoChecks (alice, gw);
239 
240  // Now try adding the various optional fields. There's no
241  // expected interaction between these optional fields; other than
242  // the expiration, they are just plopped into the ledger. So I'm
243  // not looking at interactions.
244  using namespace std::chrono_literals;
245  std::size_t const aliceCount {checksOnAccount (env, alice).size()};
246  std::size_t const bobCount {checksOnAccount (env, bob).size()};
247  env (check::create (alice, bob, USD(50)), expiration (env.now() + 1s));
248  env.close();
249 
250  env (check::create (alice, bob, USD(50)), source_tag (2));
251  env.close();
252  env (check::create (alice, bob, USD(50)), dest_tag (3));
253  env.close();
254  env (check::create (alice, bob, USD(50)), invoice_id (uint256{4}));
255  env.close();
256  env (check::create (alice, bob, USD(50)), expiration (env.now() + 1s),
257  source_tag (12), dest_tag (13), invoice_id (uint256{4}));
258  env.close();
259 
260  BEAST_EXPECT (checksOnAccount (env, alice).size() == aliceCount + 5);
261  BEAST_EXPECT (checksOnAccount (env, bob ).size() == bobCount + 5);
262 
263  // Use a regular key and also multisign to create a check.
264  Account const alie {"alie", KeyType::ed25519};
265  env (regkey (alice, alie));
266  env.close();
267 
268  Account const bogie {"bogie", KeyType::secp256k1};
269  Account const demon {"demon", KeyType::ed25519};
270  env (signers (alice, 2, {{bogie, 1}, {demon, 1}}), sig (alie));
271  env.close();
272 
273  // alice uses her regular key to create a check.
274  env (check::create (alice, bob, USD(50)), sig (alie));
275  env.close();
276  BEAST_EXPECT (checksOnAccount (env, alice).size() == aliceCount + 6);
277  BEAST_EXPECT (checksOnAccount (env, bob ).size() == bobCount + 6);
278 
279  // alice uses multisigning to create a check.
280  XRPAmount const baseFeeDrops {env.current()->fees().base};
281  env (check::create (alice, bob, USD(50)),
282  msig (bogie, demon), fee (3 * baseFeeDrops));
283  env.close();
284  BEAST_EXPECT (checksOnAccount (env, alice).size() == aliceCount + 7);
285  BEAST_EXPECT (checksOnAccount (env, bob ).size() == bobCount + 7);
286  }
287 
289  {
290  // Explore many of the invalid ways to create a check.
291  testcase ("Create invalid");
292 
293  using namespace test::jtx;
294 
295  Account const gw1 {"gateway1"};
296  Account const gwF {"gatewayFrozen"};
297  Account const alice {"alice"};
298  Account const bob {"bob"};
299  IOU const USD {gw1["USD"]};
300 
301  Env env {*this};
302 
303  STAmount const startBalance {XRP(1000).value()};
304  env.fund (startBalance, gw1, gwF, alice, bob);
305 
306  // Bad fee.
307  env (check::create (alice, bob, USD(50)), fee (drops(-10)),
308  ter (temBAD_FEE));
309  env.close();
310 
311  // Bad flags.
312  env (check::create (alice, bob, USD(50)),
313  txflags (tfImmediateOrCancel), ter (temINVALID_FLAG));
314  env.close();
315 
316  // Check to self.
317  env (check::create (alice, alice, XRP(10)), ter (temREDUNDANT));
318  env.close();
319 
320  // Bad amount.
321  env (check::create (alice, bob, drops(-1)), ter (temBAD_AMOUNT));
322  env.close();
323 
324  env (check::create (alice, bob, drops(0)), ter (temBAD_AMOUNT));
325  env.close();
326 
327  env (check::create (alice, bob, drops(1)));
328  env.close();
329 
330  env (check::create (alice, bob, USD(-1)), ter (temBAD_AMOUNT));
331  env.close();
332 
333  env (check::create (alice, bob, USD(0)), ter (temBAD_AMOUNT));
334  env.close();
335 
336  env (check::create (alice, bob, USD(1)));
337  env.close();
338  {
339  IOU const BAD {gw1, badCurrency()};
340  env (check::create (alice, bob, BAD(2)), ter (temBAD_CURRENCY));
341  env.close();
342  }
343 
344  // Bad expiration.
345  env (check::create (alice, bob, USD(50)),
346  expiration (NetClock::time_point{}), ter (temBAD_EXPIRATION));
347  env.close();
348 
349  // Destination does not exist.
350  Account const bogie {"bogie"};
351  env (check::create (alice, bogie, USD(50)), ter (tecNO_DST));
352  env.close();
353 
354  // Require destination tag.
355  env (fset (bob, asfRequireDest));
356  env.close();
357 
358  env (check::create (alice, bob, USD(50)), ter (tecDST_TAG_NEEDED));
359  env.close();
360 
361  env (check::create (alice, bob, USD(50)), dest_tag(11));
362  env.close();
363 
364  env (fclear (bob, asfRequireDest));
365  env.close();
366  {
367  // Globally frozen asset.
368  IOU const USF {gwF["USF"]};
369  env (fset(gwF, asfGlobalFreeze));
370  env.close();
371 
372  env (check::create (alice, bob, USF(50)), ter (tecFROZEN));
373  env.close();
374 
375  env (fclear(gwF, asfGlobalFreeze));
376  env.close();
377 
378  env (check::create (alice, bob, USF(50)));
379  env.close();
380  }
381  {
382  // Frozen trust line. Check creation should be similar to payment
383  // behavior in the face of frozen trust lines.
384  env.trust (USD(1000), alice);
385  env.trust (USD(1000), bob);
386  env.close();
387  env (pay (gw1, alice, USD(25)));
388  env (pay (gw1, bob, USD(25)));
389  env.close();
390 
391  // Setting trustline freeze in one direction prevents alice from
392  // creating a check for USD. But bob and gw1 should still be able
393  // to create a check for USD to alice.
394  env (trust(gw1, alice["USD"](0), tfSetFreeze));
395  env.close();
396  env (check::create (alice, bob, USD(50)), ter (tecFROZEN));
397  env.close();
398  env (pay (alice, bob, USD(1)), ter (tecPATH_DRY));
399  env.close();
400  env (check::create (bob, alice, USD(50)));
401  env.close();
402  env (pay (bob, alice, USD(1)));
403  env.close();
404  env (check::create (gw1, alice, USD(50)));
405  env.close();
406  env (pay (gw1, alice, USD(1)));
407  env.close();
408 
409  // Clear that freeze. Now check creation works.
410  env (trust(gw1, alice["USD"](0), tfClearFreeze));
411  env.close();
412  env (check::create (alice, bob, USD(50)));
413  env.close();
414  env (check::create (bob, alice, USD(50)));
415  env.close();
416  env (check::create (gw1, alice, USD(50)));
417  env.close();
418 
419  // Freezing in the other direction does not effect alice's USD
420  // check creation, but prevents bob and gw1 from writing a check
421  // for USD to alice.
422  env (trust(alice, USD(0), tfSetFreeze));
423  env.close();
424  env (check::create (alice, bob, USD(50)));
425  env.close();
426  env (pay (alice, bob, USD(1)));
427  env.close();
428  env (check::create (bob, alice, USD(50)), ter (tecFROZEN));
429  env.close();
430  env (pay (bob, alice, USD(1)), ter (tecPATH_DRY));
431  env.close();
432  env (check::create (gw1, alice, USD(50)), ter (tecFROZEN));
433  env.close();
434  env (pay (gw1, alice, USD(1)), ter (tecPATH_DRY));
435  env.close();
436 
437  // Clear that freeze.
438  env(trust(alice, USD(0), tfClearFreeze));
439  env.close();
440  }
441 
442  // Expired expiration.
443  env (check::create (alice, bob, USD(50)),
444  expiration (env.now()), ter (tecEXPIRED));
445  env.close();
446 
447  using namespace std::chrono_literals;
448  env (check::create (alice, bob, USD(50)), expiration (env.now() + 1s));
449  env.close();
450 
451  // Insufficient reserve.
452  Account const cheri {"cheri"};
453  env.fund (
454  env.current()->fees().accountReserve(1) - drops(1), cheri);
455 
456  env (check::create (cheri, bob, USD(50)),
457  fee (drops (env.current()->fees().base)),
459  env.close();
460 
461  env (pay (bob, cheri, drops (env.current()->fees().base + 1)));
462  env.close();
463 
464  env (check::create (cheri, bob, USD(50)));
465  env.close();
466  }
467 
468  void testCashXRP()
469  {
470  // Explore many of the valid ways to cash a check for XRP.
471  testcase ("Cash XRP");
472 
473  using namespace test::jtx;
474 
475  Account const alice {"alice"};
476  Account const bob {"bob"};
477 
478  Env env {*this};
479 
480  XRPAmount const baseFeeDrops {env.current()->fees().base};
481  STAmount const startBalance {XRP(300).value()};
482  env.fund (startBalance, alice, bob);
483  {
484  // Basic XRP check.
485  uint256 const chkId {getCheckIndex (alice, env.seq (alice))};
486  env (check::create (alice, bob, XRP(10)));
487  env.close();
488  env.require (balance (alice, startBalance - drops (baseFeeDrops)));
489  env.require (balance (bob, startBalance));
490  BEAST_EXPECT (checksOnAccount (env, alice).size() == 1);
491  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 1);
492  BEAST_EXPECT (ownerCount (env, alice) == 1);
493  BEAST_EXPECT (ownerCount (env, bob ) == 0);
494 
495  env (check::cash (bob, chkId, XRP(10)));
496  env.close();
497  env.require (balance (alice,
498  startBalance - XRP(10) - drops (baseFeeDrops)));
499  env.require (balance (bob,
500  startBalance + XRP(10) - drops (baseFeeDrops)));
501  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
502  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 0);
503  BEAST_EXPECT (ownerCount (env, alice) == 0);
504  BEAST_EXPECT (ownerCount (env, bob ) == 0);
505 
506  // Make alice's and bob's balances easy to think about.
507  env (pay (env.master, alice, XRP(10) + drops (baseFeeDrops)));
508  env (pay (bob, env.master, XRP(10) - drops (baseFeeDrops * 2)));
509  env.close();
510  env.require (balance (alice, startBalance));
511  env.require (balance (bob, startBalance));
512  }
513  {
514  // Write a check that chews into alice's reserve.
515  STAmount const reserve {env.current()->fees().accountReserve (0)};
516  STAmount const checkAmount {
517  startBalance - reserve - drops (baseFeeDrops)};
518  uint256 const chkId {getCheckIndex (alice, env.seq (alice))};
519  env (check::create (alice, bob, checkAmount));
520  env.close();
521 
522  // bob tries to cash for more than the check amount.
523  env (check::cash (bob, chkId, checkAmount + drops(1)),
524  ter (tecPATH_PARTIAL));
525  env.close();
526  env (check::cash (
527  bob, chkId, check::DeliverMin (checkAmount + drops(1))),
528  ter (tecPATH_PARTIAL));
529  env.close();
530 
531  // bob cashes exactly the check amount. This is successful
532  // because one unit of alice's reserve is released when the
533  // check is consumed.
534  env (check::cash (bob, chkId, check::DeliverMin (checkAmount)));
535  verifyDeliveredAmount (env, drops(checkAmount.mantissa()));
536  env.require (balance (alice, reserve));
537  env.require (balance (bob,
538  startBalance + checkAmount - drops (baseFeeDrops * 3)));
539  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
540  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 0);
541  BEAST_EXPECT (ownerCount (env, alice) == 0);
542  BEAST_EXPECT (ownerCount (env, bob ) == 0);
543 
544  // Make alice's and bob's balances easy to think about.
545  env (pay (env.master, alice, checkAmount + drops (baseFeeDrops)));
546  env (pay (bob, env.master, checkAmount - drops (baseFeeDrops * 4)));
547  env.close();
548  env.require (balance (alice, startBalance));
549  env.require (balance (bob, startBalance));
550  }
551  {
552  // Write a check that goes one drop past what alice can pay.
553  STAmount const reserve {env.current()->fees().accountReserve (0)};
554  STAmount const checkAmount {
555  startBalance - reserve - drops (baseFeeDrops - 1)};
556  uint256 const chkId {getCheckIndex (alice, env.seq (alice))};
557  env (check::create (alice, bob, checkAmount));
558  env.close();
559 
560  // bob tries to cash for exactly the check amount. Fails because
561  // alice is one drop shy of funding the check.
562  env (check::cash (bob, chkId, checkAmount), ter (tecPATH_PARTIAL));
563  env.close();
564 
565  // bob decides to get what he can from the bounced check.
566  env (check::cash (bob, chkId, check::DeliverMin (drops(1))));
567  verifyDeliveredAmount (env, drops(checkAmount.mantissa() - 1));
568  env.require (balance (alice, reserve));
569  env.require (balance (bob,
570  startBalance + checkAmount - drops (baseFeeDrops * 2 + 1)));
571  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
572  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 0);
573  BEAST_EXPECT (ownerCount (env, alice) == 0);
574  BEAST_EXPECT (ownerCount (env, bob ) == 0);
575 
576  // Make alice's and bob's balances easy to think about.
577  env (pay (env.master, alice,
578  checkAmount + drops (baseFeeDrops - 1)));
579  env (pay (bob, env.master,
580  checkAmount - drops (baseFeeDrops * 3 + 1)));
581  env.close();
582  env.require (balance (alice, startBalance));
583  env.require (balance (bob, startBalance));
584  }
585  }
586 
587  void testCashIOU ()
588  {
589  // Explore many of the valid ways to cash a check for an IOU.
590  testcase ("Cash IOU");
591 
592  using namespace test::jtx;
593 
594  Account const gw {"gateway"};
595  Account const alice {"alice"};
596  Account const bob {"bob"};
597  IOU const USD {gw["USD"]};
598  {
599  // Simple IOU check cashed with Amount (with failures).
600  Env env {*this};
601 
602  env.fund (XRP(1000), gw, alice, bob);
603 
604  // alice writes the check before she gets the funds.
605  uint256 const chkId1 {getCheckIndex (alice, env.seq (alice))};
606  env (check::create (alice, bob, USD(10)));
607  env.close();
608 
609  // bob attempts to cash the check. Should fail.
610  env (check::cash (bob, chkId1, USD(10)), ter (tecPATH_PARTIAL));
611  env.close();
612 
613  // alice gets almost enough funds. bob tries and fails again.
614  env (trust (alice, USD(20)));
615  env.close();
616  env (pay (gw, alice, USD(9.5)));
617  env.close();
618  env (check::cash (bob, chkId1, USD(10)), ter (tecPATH_PARTIAL));
619  env.close();
620 
621  // alice gets the last of the necessary funds. bob tries again
622  // and fails because he hasn't got a trust line for USD.
623  env (pay (gw, alice, USD(0.5)));
624  env.close();
625  env (check::cash (bob, chkId1, USD(10)), ter (tecNO_LINE));
626  env.close();
627 
628  // bob sets up the trust line, but not at a high enough limit.
629  env (trust (bob, USD(9.5)));
630  env.close();
631  env (check::cash (bob, chkId1, USD(10)), ter (tecPATH_PARTIAL));
632  env.close();
633 
634  // bob sets the trust line limit high enough but asks for more
635  // than the check's SendMax.
636  env (trust (bob, USD(10.5)));
637  env.close();
638  env (check::cash (bob, chkId1, USD(10.5)), ter (tecPATH_PARTIAL));
639  env.close();
640 
641  // bob asks for exactly the check amount and the check clears.
642  env (check::cash (bob, chkId1, USD(10)));
643  env.close();
644  env.require (balance (alice, USD( 0)));
645  env.require (balance (bob, USD(10)));
646  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
647  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 0);
648  BEAST_EXPECT (ownerCount (env, alice) == 1);
649  BEAST_EXPECT (ownerCount (env, bob ) == 1);
650 
651  // bob tries to cash the same check again, which fails.
652  env (check::cash (bob, chkId1, USD(10)), ter (tecNO_ENTRY));
653  env.close();
654 
655  // bob pays alice USD(7) so he can try another case.
656  env (pay (bob, alice, USD(7)));
657  env.close();
658 
659  uint256 const chkId2 {getCheckIndex (alice, env.seq (alice))};
660  env (check::create (alice, bob, USD(7)));
661  env.close();
662  BEAST_EXPECT (checksOnAccount (env, alice).size() == 1);
663  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 1);
664 
665  // bob cashes the check for less than the face amount. That works,
666  // consumes the check, and bob receives as much as he asked for.
667  env (check::cash (bob, chkId2, USD(5)));
668  env.close();
669  env.require (balance (alice, USD(2)));
670  env.require (balance (bob, USD(8)));
671  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
672  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 0);
673  BEAST_EXPECT (ownerCount (env, alice) == 1);
674  BEAST_EXPECT (ownerCount (env, bob ) == 1);
675 
676  // alice writes two checks for USD(2), although she only has USD(2).
677  uint256 const chkId3 {getCheckIndex (alice, env.seq (alice))};
678  env (check::create (alice, bob, USD(2)));
679  env.close();
680  uint256 const chkId4 {getCheckIndex (alice, env.seq (alice))};
681  env (check::create (alice, bob, USD(2)));
682  env.close();
683  BEAST_EXPECT (checksOnAccount (env, alice).size() == 2);
684  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 2);
685 
686  // bob cashes the second check for the face amount.
687  env (check::cash (bob, chkId4, USD(2)));
688  env.close();
689  env.require (balance (alice, USD( 0)));
690  env.require (balance (bob, USD(10)));
691  BEAST_EXPECT (checksOnAccount (env, alice).size() == 1);
692  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 1);
693  BEAST_EXPECT (ownerCount (env, alice) == 2);
694  BEAST_EXPECT (ownerCount (env, bob ) == 1);
695 
696  // bob is not allowed to cash the last check for USD(0), he must
697  // use check::cancel instead.
698  env (check::cash (bob, chkId3, USD(0)), ter (temBAD_AMOUNT));
699  env.close();
700  env.require (balance (alice, USD( 0)));
701  env.require (balance (bob, USD(10)));
702  BEAST_EXPECT (checksOnAccount (env, alice).size() == 1);
703  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 1);
704  BEAST_EXPECT (ownerCount (env, alice) == 2);
705  BEAST_EXPECT (ownerCount (env, bob ) == 1);
706 
707  // ... so bob cancels alice's remaining check.
708  env (check::cancel (bob, chkId3));
709  env.close();
710  env.require (balance (alice, USD( 0)));
711  env.require (balance (bob, USD(10)));
712  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
713  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 0);
714  BEAST_EXPECT (ownerCount (env, alice) == 1);
715  BEAST_EXPECT (ownerCount (env, bob ) == 1);
716  }
717  {
718  // Simple IOU check cashed with DeliverMin (with failures).
719  Env env {*this};
720 
721  env.fund (XRP(1000), gw, alice, bob);
722 
723  env (trust (alice, USD(20)));
724  env (trust (bob, USD(20)));
725  env.close();
726  env (pay (gw, alice, USD(8)));
727  env.close();
728 
729  // alice creates several checks ahead of time.
730  uint256 const chkId9 {getCheckIndex (alice, env.seq (alice))};
731  env (check::create (alice, bob, USD(9)));
732  env.close();
733  uint256 const chkId8 {getCheckIndex (alice, env.seq (alice))};
734  env (check::create (alice, bob, USD(8)));
735  env.close();
736  uint256 const chkId7 {getCheckIndex (alice, env.seq (alice))};
737  env (check::create (alice, bob, USD(7)));
738  env.close();
739  uint256 const chkId6 {getCheckIndex (alice, env.seq (alice))};
740  env (check::create (alice, bob, USD(6)));
741  env.close();
742 
743  // bob attempts to cash a check for the amount on the check.
744  // Should fail, since alice doesn't have the funds.
745  env (check::cash (bob, chkId9, check::DeliverMin (USD(9))),
746  ter (tecPATH_PARTIAL));
747  env.close();
748 
749  // bob sets a DeliverMin of 7 and gets all that alice has.
750  env (check::cash (bob, chkId9, check::DeliverMin (USD(7))));
751  verifyDeliveredAmount (env, USD(8));
752  env.require (balance (alice, USD(0)));
753  env.require (balance (bob, USD(8)));
754  BEAST_EXPECT (checksOnAccount (env, alice).size() == 3);
755  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 3);
756  BEAST_EXPECT (ownerCount (env, alice) == 4);
757  BEAST_EXPECT (ownerCount (env, bob ) == 1);
758 
759  // bob pays alice USD(7) so he can use another check.
760  env (pay (bob, alice, USD(7)));
761  env.close();
762 
763  // Using DeliverMin for the SendMax value of the check (and no
764  // transfer fees) should work just like setting Amount.
765  env (check::cash (bob, chkId7, check::DeliverMin (USD(7))));
766  verifyDeliveredAmount (env, USD(7));
767  env.require (balance (alice, USD(0)));
768  env.require (balance (bob, USD(8)));
769  BEAST_EXPECT (checksOnAccount (env, alice).size() == 2);
770  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 2);
771  BEAST_EXPECT (ownerCount (env, alice) == 3);
772  BEAST_EXPECT (ownerCount (env, bob ) == 1);
773 
774  // bob pays alice USD(8) so he can use the last two checks.
775  env (pay (bob, alice, USD(8)));
776  env.close();
777 
778  // alice has USD(8). If bob uses the check for USD(6) and uses a
779  // DeliverMin of 4, he should get the SendMax value of the check.
780  env (check::cash (bob, chkId6, check::DeliverMin (USD(4))));
781  verifyDeliveredAmount (env, USD(6));
782  env.require (balance (alice, USD(2)));
783  env.require (balance (bob, USD(6)));
784  BEAST_EXPECT (checksOnAccount (env, alice).size() == 1);
785  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 1);
786  BEAST_EXPECT (ownerCount (env, alice) == 2);
787  BEAST_EXPECT (ownerCount (env, bob ) == 1);
788 
789  // bob cashes the last remaining check setting a DeliverMin.
790  // of exactly alice's remaining USD.
791  env (check::cash (bob, chkId8, check::DeliverMin (USD(2))));
792  verifyDeliveredAmount (env, USD(2));
793  env.require (balance (alice, USD(0)));
794  env.require (balance (bob, USD(8)));
795  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
796  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 0);
797  BEAST_EXPECT (ownerCount (env, alice) == 1);
798  BEAST_EXPECT (ownerCount (env, bob ) == 1);
799  }
800  {
801  // Examine the effects of the asfRequireAuth flag.
802  Env env {*this};
803 
804  env.fund (XRP(1000), gw, alice, bob);
805  env (fset (gw, asfRequireAuth));
806  env.close();
807  env (trust (gw, alice["USD"](100)), txflags (tfSetfAuth));
808  env (trust (alice, USD(20)));
809  env.close();
810  env (pay (gw, alice, USD(8)));
811  env.close();
812 
813  // alice writes a check to bob for USD. bob can't cash it
814  // because he is not authorized to hold gw["USD"].
815  uint256 const chkId {getCheckIndex (alice, env.seq (alice))};
816  env (check::create (alice, bob, USD(7)));
817  env.close();
818 
819  env (check::cash (bob, chkId, USD(7)), ter (tecNO_LINE));
820  env.close();
821 
822  // Now give bob a trustline for USD. bob still can't cash the
823  // check because he is not authorized.
824  env (trust (bob, USD(5)));
825  env.close();
826 
827  env (check::cash (bob, chkId, USD(7)), ter (tecNO_AUTH));
828  env.close();
829 
830  // bob gets authorization to hold gw["USD"].
831  env (trust (gw, bob["USD"](1)), txflags (tfSetfAuth));
832  env.close();
833 
834  // bob tries to cash the check again but fails because his trust
835  // limit is too low.
836  env (check::cash (bob, chkId, USD(7)), ter (tecPATH_PARTIAL));
837  env.close();
838 
839  // Since bob set his limit low, he cashes the check with a
840  // DeliverMin and hits his trust limit.
841  env (check::cash (bob, chkId, check::DeliverMin (USD(4))));
842  verifyDeliveredAmount (env, USD(5));
843  env.require (balance (alice, USD(3)));
844  env.require (balance (bob, USD(5)));
845  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
846  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 0);
847  BEAST_EXPECT (ownerCount (env, alice) == 1);
848  BEAST_EXPECT (ownerCount (env, bob ) == 1);
849  }
850 
851  // Use a regular key and also multisign to cash a check.
852  // featureMultiSignReserve changes the reserve on a SignerList, so
853  // check both before and after.
854  FeatureBitset const allSupported {supported_amendments()};
855  for (auto const features :
856  {allSupported - featureMultiSignReserve,
857  allSupported | featureMultiSignReserve})
858  {
859  Env env {*this, features};
860 
861  env.fund (XRP(1000), gw, alice, bob);
862 
863  // alice creates her checks ahead of time.
864  uint256 const chkId1 {getCheckIndex (alice, env.seq (alice))};
865  env (check::create (alice, bob, USD(1)));
866  env.close();
867 
868  uint256 const chkId2 {getCheckIndex (alice, env.seq (alice))};
869  env (check::create (alice, bob, USD(2)));
870  env.close();
871 
872  env (trust (alice, USD(20)));
873  env (trust (bob, USD(20)));
874  env.close();
875  env (pay (gw, alice, USD(8)));
876  env.close();
877 
878  // Give bob a regular key and signers
879  Account const bobby {"bobby", KeyType::secp256k1};
880  env (regkey (bob, bobby));
881  env.close();
882 
883  Account const bogie {"bogie", KeyType::secp256k1};
884  Account const demon {"demon", KeyType::ed25519};
885  env (signers (bob, 2, {{bogie, 1}, {demon, 1}}), sig (bobby));
886  env.close();
887 
888  // If featureMultiSignReserve is enabled then bob's signer list
889  // has an owner count of 1, otherwise it's 4.
890  int const signersCount {features[featureMultiSignReserve] ? 1 : 4};
891  BEAST_EXPECT (ownerCount (env, bob) == signersCount + 1);
892 
893  // bob uses his regular key to cash a check.
894  env (check::cash (bob, chkId1, (USD(1))), sig (bobby));
895  env.close();
896  env.require (balance (alice, USD(7)));
897  env.require (balance (bob, USD(1)));
898  BEAST_EXPECT (checksOnAccount (env, alice).size() == 1);
899  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 1);
900  BEAST_EXPECT (ownerCount (env, alice) == 2);
901  BEAST_EXPECT (ownerCount (env, bob ) == signersCount + 1);
902 
903  // bob uses multisigning to cash a check.
904  XRPAmount const baseFeeDrops {env.current()->fees().base};
905  env (check::cash (bob, chkId2, (USD(2))),
906  msig (bogie, demon), fee (3 * baseFeeDrops));
907  env.close();
908  env.require (balance (alice, USD(5)));
909  env.require (balance (bob, USD(3)));
910  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
911  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 0);
912  BEAST_EXPECT (ownerCount (env, alice) == 1);
913  BEAST_EXPECT (ownerCount (env, bob ) == signersCount + 1);
914  }
915  }
916 
918  {
919  // Look at behavior when the issuer charges a transfer fee.
920  testcase ("Cash with transfer fee");
921 
922  using namespace test::jtx;
923 
924  Account const gw {"gateway"};
925  Account const alice {"alice"};
926  Account const bob {"bob"};
927  IOU const USD {gw["USD"]};
928 
929  Env env {*this};
930 
931  env.fund (XRP(1000), gw, alice, bob);
932 
933  env (trust (alice, USD(1000)));
934  env (trust (bob, USD(1000)));
935  env.close();
936  env (pay (gw, alice, USD(1000)));
937  env.close();
938 
939  // Set gw's transfer rate and see the consequences when cashing a check.
940  env (rate (gw, 1.25));
941  env.close();
942 
943  // alice writes a check with a SendMax of USD(125). The most bob
944  // can get is USD(100) because of the transfer rate.
945  uint256 const chkId125 {getCheckIndex (alice, env.seq (alice))};
946  env (check::create (alice, bob, USD(125)));
947  env.close();
948 
949  // alice writes another check that won't get cashed until the transfer
950  // rate changes so we can see the rate applies when the check is
951  // cashed, not when it is created.
952  uint256 const chkId120 {getCheckIndex (alice, env.seq (alice))};
953  env (check::create (alice, bob, USD(120)));
954  env.close();
955 
956  // bob attempts to cash the check for face value. Should fail.
957  env (check::cash (bob, chkId125, USD(125)), ter (tecPATH_PARTIAL));
958  env.close();
959  env (check::cash (bob, chkId125, check::DeliverMin (USD(101))),
960  ter (tecPATH_PARTIAL));
961  env.close();
962 
963  // bob decides that he'll accept anything USD(75) or up.
964  // He gets USD(100).
965  env (check::cash (bob, chkId125, check::DeliverMin (USD(75))));
966  verifyDeliveredAmount (env, USD(100));
967  env.require (balance (alice, USD(1000 - 125)));
968  env.require (balance (bob, USD( 0 + 100)));
969  BEAST_EXPECT (checksOnAccount (env, alice).size() == 1);
970  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 1);
971 
972  // Adjust gw's rate...
973  env (rate (gw, 1.2));
974  env.close();
975 
976  // bob cashes the second check for less than the face value. The new
977  // rate applies to the actual value transferred.
978  env (check::cash (bob, chkId120, USD(50)));
979  env.close();
980  env.require (balance (alice, USD(1000 - 125 - 60)));
981  env.require (balance (bob, USD( 0 + 100 + 50)));
982  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
983  BEAST_EXPECT (checksOnAccount (env, bob ).size() == 0);
984  }
985 
987  {
988  // Look at the eight possible cases for Quality In/Out.
989  testcase ("Cash quality");
990 
991  using namespace test::jtx;
992 
993  Account const gw {"gateway"};
994  Account const alice {"alice"};
995  Account const bob {"bob"};
996  IOU const USD {gw["USD"]};
997 
998  Env env {*this};
999 
1000  env.fund (XRP(1000), gw, alice, bob);
1001 
1002  env (trust (alice, USD(1000)));
1003  env (trust (bob, USD(1000)));
1004  env.close();
1005  env (pay (gw, alice, USD(1000)));
1006  env.close();
1007 
1008  //
1009  // Quality effects on transfers between two non-issuers.
1010  //
1011 
1012  // Provide lambdas that return a qualityInPercent and qualityOutPercent.
1013  auto qIn =
1014  [] (double percent) { return qualityInPercent (percent); };
1015  auto qOut =
1016  [] (double percent) { return qualityOutPercent (percent); };
1017 
1018  // There are two test lambdas: one for a Payment and one for a Check.
1019  // This shows whether a Payment and a Check behave the same.
1020  auto testNonIssuerQPay = [&env, &alice, &bob, &USD]
1021  (Account const& truster,
1022  IOU const& iou, auto const& inOrOut, double pct, double amount)
1023  {
1024  // Capture bob's and alice's balances so we can test at the end.
1025  STAmount const aliceStart {env.balance (alice, USD.issue()).value()};
1026  STAmount const bobStart {env.balance (bob, USD.issue()).value()};
1027 
1028  // Set the modified quality.
1029  env (trust (truster, iou(1000)), inOrOut (pct));
1030  env.close();
1031 
1032  env (pay (alice, bob, USD(amount)), sendmax (USD(10)));
1033  env.close();
1034  env.require (balance (alice, aliceStart - USD(10)));
1035  env.require (balance (bob, bobStart + USD(10)));
1036 
1037  // Return the quality to the unmodified state so it doesn't
1038  // interfere with upcoming tests.
1039  env (trust (truster, iou(1000)), inOrOut (0));
1040  env.close();
1041  };
1042 
1043  auto testNonIssuerQCheck = [&env, &alice, &bob, &USD]
1044  (Account const& truster,
1045  IOU const& iou, auto const& inOrOut, double pct, double amount)
1046  {
1047  // Capture bob's and alice's balances so we can test at the end.
1048  STAmount const aliceStart {env.balance (alice, USD.issue()).value()};
1049  STAmount const bobStart {env.balance (bob, USD.issue()).value()};
1050 
1051  // Set the modified quality.
1052  env (trust (truster, iou(1000)), inOrOut (pct));
1053  env.close();
1054 
1055  uint256 const chkId {getCheckIndex (alice, env.seq (alice))};
1056  env (check::create (alice, bob, USD(10)));
1057  env.close();
1058 
1059  env (check::cash (bob, chkId, USD(amount)));
1060  env.close();
1061  env.require (balance (alice, aliceStart - USD(10)));
1062  env.require (balance (bob, bobStart + USD(10)));
1063 
1064  // Return the quality to the unmodified state so it doesn't
1065  // interfere with upcoming tests.
1066  env (trust (truster, iou(1000)), inOrOut (0));
1067  env.close();
1068  };
1069 
1070  // pct amount
1071  testNonIssuerQPay (alice, gw["USD"], qIn, 50, 10);
1072  testNonIssuerQCheck (alice, gw["USD"], qIn, 50, 10);
1073 
1074  // This is the only case where the Quality affects the outcome.
1075  testNonIssuerQPay (bob, gw["USD"], qIn, 50, 5);
1076  testNonIssuerQCheck (bob, gw["USD"], qIn, 50, 5);
1077 
1078  testNonIssuerQPay (gw, alice["USD"], qIn, 50, 10);
1079  testNonIssuerQCheck (gw, alice["USD"], qIn, 50, 10);
1080 
1081  testNonIssuerQPay (gw, bob["USD"], qIn, 50, 10);
1082  testNonIssuerQCheck (gw, bob["USD"], qIn, 50, 10);
1083 
1084  testNonIssuerQPay (alice, gw["USD"], qOut, 200, 10);
1085  testNonIssuerQCheck (alice, gw["USD"], qOut, 200, 10);
1086 
1087  testNonIssuerQPay (bob, gw["USD"], qOut, 200, 10);
1088  testNonIssuerQCheck (bob, gw["USD"], qOut, 200, 10);
1089 
1090  testNonIssuerQPay (gw, alice["USD"], qOut, 200, 10);
1091  testNonIssuerQCheck (gw, alice["USD"], qOut, 200, 10);
1092 
1093  testNonIssuerQPay (gw, bob["USD"], qOut, 200, 10);
1094  testNonIssuerQCheck (gw, bob["USD"], qOut, 200, 10);
1095 
1096  //
1097  // Quality effects on transfers between an issuer and a non-issuer.
1098  //
1099 
1100  // There are two test lambdas for the same reason as before.
1101  auto testIssuerQPay = [&env, &gw, &alice, &USD]
1102  (Account const& truster, IOU const& iou,
1103  auto const& inOrOut, double pct,
1104  double amt1, double max1, double amt2, double max2)
1105  {
1106  // Capture alice's balance so we can test at the end. It doesn't
1107  // make any sense to look at the balance of a gateway.
1108  STAmount const aliceStart {env.balance (alice, USD.issue()).value()};
1109 
1110  // Set the modified quality.
1111  env (trust (truster, iou(1000)), inOrOut (pct));
1112  env.close();
1113 
1114  // alice pays gw.
1115  env (pay (alice, gw, USD(amt1)), sendmax (USD(max1)));
1116  env.close();
1117  env.require (balance (alice, aliceStart - USD(10)));
1118 
1119  // gw pays alice.
1120  env (pay (gw, alice, USD(amt2)), sendmax (USD(max2)));
1121  env.close();
1122  env.require (balance (alice, aliceStart));
1123 
1124  // Return the quality to the unmodified state so it doesn't
1125  // interfere with upcoming tests.
1126  env (trust (truster, iou(1000)), inOrOut (0));
1127  env.close();
1128  };
1129 
1130  auto testIssuerQCheck = [&env, &gw, &alice, &USD]
1131  (Account const& truster, IOU const& iou,
1132  auto const& inOrOut, double pct,
1133  double amt1, double max1, double amt2, double max2)
1134  {
1135  // Capture alice's balance so we can test at the end. It doesn't
1136  // make any sense to look at the balance of the issuer.
1137  STAmount const aliceStart {env.balance (alice, USD.issue()).value()};
1138 
1139  // Set the modified quality.
1140  env (trust (truster, iou(1000)), inOrOut (pct));
1141  env.close();
1142 
1143  // alice writes check to gw. gw cashes.
1144  uint256 const chkAliceId {getCheckIndex (alice, env.seq (alice))};
1145  env (check::create (alice, gw, USD(max1)));
1146  env.close();
1147 
1148  env (check::cash (gw, chkAliceId, USD(amt1)));
1149  env.close();
1150  env.require (balance (alice, aliceStart - USD(10)));
1151 
1152  // gw writes check to alice. alice cashes.
1153  uint256 const chkGwId {getCheckIndex (gw, env.seq (gw))};
1154  env (check::create (gw, alice, USD(max2)));
1155  env.close();
1156 
1157  env (check::cash (alice, chkGwId, USD(amt2)));
1158  env.close();
1159  env.require (balance (alice, aliceStart));
1160 
1161  // Return the quality to the unmodified state so it doesn't
1162  // interfere with upcoming tests.
1163  env (trust (truster, iou(1000)), inOrOut (0));
1164  env.close();
1165  };
1166 
1167  // The first case is the only one where the quality affects the outcome.
1168  // pct amt1 max1 amt2 max2
1169  testIssuerQPay (alice, gw["USD"], qIn, 50, 10, 10, 5, 10);
1170  testIssuerQCheck (alice, gw["USD"], qIn, 50, 10, 10, 5, 10);
1171 
1172  testIssuerQPay (gw, alice["USD"], qIn, 50, 10, 10, 10, 10);
1173  testIssuerQCheck (gw, alice["USD"], qIn, 50, 10, 10, 10, 10);
1174 
1175  testIssuerQPay (alice, gw["USD"], qOut, 200, 10, 10, 10, 10);
1176  testIssuerQCheck (alice, gw["USD"], qOut, 200, 10, 10, 10, 10);
1177 
1178  testIssuerQPay (gw, alice["USD"], qOut, 200, 10, 10, 10, 10);
1179  testIssuerQCheck (gw, alice["USD"], qOut, 200, 10, 10, 10, 10);
1180  }
1181 
1183  {
1184  // Explore many of the ways to fail at cashing a check.
1185  testcase ("Cash invalid");
1186 
1187  using namespace test::jtx;
1188 
1189  Account const gw {"gateway"};
1190  Account const alice {"alice"};
1191  Account const bob {"bob"};
1192  Account const zoe {"zoe"};
1193  IOU const USD {gw["USD"]};
1194 
1195  Env env {*this};
1196 
1197  env.fund (XRP(1000), gw, alice, bob, zoe);
1198 
1199  // Now set up alice's trustline.
1200  env (trust (alice, USD(20)));
1201  env.close();
1202  env (pay (gw, alice, USD(20)));
1203  env.close();
1204 
1205  // Before bob gets a trustline, have him try to cash a check.
1206  // Should fail.
1207  {
1208  uint256 const chkId {getCheckIndex (alice, env.seq (alice))};
1209  env (check::create (alice, bob, USD(20)));
1210  env.close();
1211 
1212  env (check::cash (bob, chkId, USD(20)), ter (tecNO_LINE));
1213  env.close();
1214  }
1215 
1216  // Now set up bob's trustline.
1217  env (trust (bob, USD(20)));
1218  env.close();
1219 
1220  // bob tries to cash a non-existent check from alice.
1221  {
1222  uint256 const chkId {getCheckIndex (alice, env.seq (alice))};
1223  env (check::cash (bob, chkId, USD(20)), ter (tecNO_ENTRY));
1224  env.close();
1225  }
1226 
1227  // alice creates her checks ahead of time.
1228  uint256 const chkIdU {getCheckIndex (alice, env.seq (alice))};
1229  env (check::create (alice, bob, USD(20)));
1230  env.close();
1231 
1232  uint256 const chkIdX {getCheckIndex (alice, env.seq (alice))};
1233  env (check::create (alice, bob, XRP(10)));
1234  env.close();
1235 
1236  using namespace std::chrono_literals;
1237  uint256 const chkIdExp {getCheckIndex (alice, env.seq (alice))};
1238  env (check::create (alice, bob, XRP(10)), expiration (env.now() + 1s));
1239  env.close();
1240 
1241  uint256 const chkIdFroz1 {getCheckIndex (alice, env.seq (alice))};
1242  env (check::create (alice, bob, USD(1)));
1243  env.close();
1244 
1245  uint256 const chkIdFroz2 {getCheckIndex (alice, env.seq (alice))};
1246  env (check::create (alice, bob, USD(2)));
1247  env.close();
1248 
1249  uint256 const chkIdFroz3 {getCheckIndex (alice, env.seq (alice))};
1250  env (check::create (alice, bob, USD(3)));
1251  env.close();
1252 
1253  uint256 const chkIdFroz4 {getCheckIndex (alice, env.seq (alice))};
1254  env (check::create (alice, bob, USD(4)));
1255  env.close();
1256 
1257  uint256 const chkIdNoDest1 {getCheckIndex (alice, env.seq (alice))};
1258  env (check::create (alice, bob, USD(1)));
1259  env.close();
1260 
1261  uint256 const chkIdHasDest2 {getCheckIndex (alice, env.seq (alice))};
1262  env (check::create (alice, bob, USD(2)), dest_tag (7));
1263  env.close();
1264 
1265  // Same set of failing cases for both IOU and XRP check cashing.
1266  auto failingCases = [&env, &gw, &alice, &bob] (
1267  uint256 const& chkId, STAmount const& amount)
1268  {
1269  // Bad fee.
1270  env (check::cash (bob, chkId, amount), fee (drops(-10)),
1271  ter (temBAD_FEE));
1272  env.close();
1273 
1274  // Bad flags.
1275  env (check::cash (bob, chkId, amount),
1276  txflags (tfImmediateOrCancel), ter (temINVALID_FLAG));
1277  env.close();
1278 
1279  // Missing both Amount and DeliverMin.
1280  {
1281  Json::Value tx {check::cash (bob, chkId, amount)};
1283  env (tx, ter (temMALFORMED));
1284  env.close();
1285  }
1286  // Both Amount and DeliverMin present.
1287  {
1288  Json::Value tx {check::cash (bob, chkId, amount)};
1289  tx[sfDeliverMin.jsonName] = amount.getJson(JsonOptions::none);
1290  env (tx, ter (temMALFORMED));
1291  env.close();
1292  }
1293 
1294  // Negative or zero amount.
1295  {
1296  STAmount neg {amount};
1297  neg.negate();
1298  env (check::cash (bob, chkId, neg), ter (temBAD_AMOUNT));
1299  env.close();
1300  env (check::cash (bob, chkId, amount.zeroed()),
1301  ter (temBAD_AMOUNT));
1302  env.close();
1303  }
1304 
1305  // Bad currency.
1306  if (! amount.native()) {
1307  Issue const badIssue {badCurrency(), amount.getIssuer()};
1308  STAmount badAmount {amount};
1309  badAmount.setIssue (Issue {badCurrency(), amount.getIssuer()});
1310  env (check::cash (bob, chkId, badAmount),
1311  ter (temBAD_CURRENCY));
1312  env.close();
1313  }
1314 
1315  // Not destination cashing check.
1316  env (check::cash (alice, chkId, amount), ter (tecNO_PERMISSION));
1317  env.close();
1318  env (check::cash (gw, chkId, amount), ter (tecNO_PERMISSION));
1319  env.close();
1320 
1321  // Currency mismatch.
1322  {
1323  IOU const wrongCurrency {gw["EUR"]};
1324  STAmount badAmount {amount};
1325  badAmount.setIssue (wrongCurrency.issue());
1326  env (check::cash (bob, chkId, badAmount),
1327  ter (temMALFORMED));
1328  env.close();
1329  }
1330 
1331  // Issuer mismatch.
1332  {
1333  IOU const wrongIssuer {alice["USD"]};
1334  STAmount badAmount {amount};
1335  badAmount.setIssue (wrongIssuer.issue());
1336  env (check::cash (bob, chkId, badAmount),
1337  ter (temMALFORMED));
1338  env.close();
1339  }
1340 
1341  // Amount bigger than SendMax.
1342  env (check::cash (bob, chkId, amount + amount),
1343  ter (tecPATH_PARTIAL));
1344  env.close();
1345 
1346  // DeliverMin bigger than SendMax.
1347  env (check::cash (bob, chkId, check::DeliverMin (amount + amount)),
1348  ter (tecPATH_PARTIAL));
1349  env.close();
1350  };
1351 
1352  failingCases (chkIdX, XRP(10));
1353  failingCases (chkIdU, USD(20));
1354 
1355  // Verify that those two checks really were cashable.
1356  env (check::cash (bob, chkIdU, USD(20)));
1357  env.close();
1358  env (check::cash (bob, chkIdX, check::DeliverMin (XRP(10))));
1359  verifyDeliveredAmount (env, XRP(10));
1360 
1361  // Try to cash an expired check.
1362  env (check::cash (bob, chkIdExp, XRP(10)), ter (tecEXPIRED));
1363  env.close();
1364 
1365  // Cancel the expired check. Anyone can cancel an expired check.
1366  env (check::cancel (zoe, chkIdExp));
1367  env.close();
1368 
1369  // Can we cash a check with frozen currency?
1370  {
1371  env (pay (bob, alice, USD(20)));
1372  env.close();
1373  env.require (balance (alice, USD(20)));
1374  env.require (balance (bob, USD( 0)));
1375 
1376  // Global freeze
1377  env (fset (gw, asfGlobalFreeze));
1378  env.close();
1379 
1380  env (check::cash (bob, chkIdFroz1, USD(1)), ter (tecPATH_PARTIAL));
1381  env.close();
1382  env (check::cash (bob, chkIdFroz1, check::DeliverMin (USD(0.5))),
1383  ter (tecPATH_PARTIAL));
1384  env.close();
1385 
1386  env (fclear (gw, asfGlobalFreeze));
1387  env.close();
1388 
1389  // No longer frozen. Success.
1390  env (check::cash (bob, chkIdFroz1, USD(1)));
1391  env.close();
1392  env.require (balance (alice, USD(19)));
1393  env.require (balance (bob, USD( 1)));
1394 
1395  // Freeze individual trustlines.
1396  env (trust(gw, alice["USD"](0), tfSetFreeze));
1397  env.close();
1398  env (check::cash (bob, chkIdFroz2, USD(2)), ter (tecPATH_PARTIAL));
1399  env.close();
1400  env (check::cash (bob, chkIdFroz2, check::DeliverMin (USD(1))),
1401  ter (tecPATH_PARTIAL));
1402  env.close();
1403 
1404  // Clear that freeze. Now check cashing works.
1405  env (trust(gw, alice["USD"](0), tfClearFreeze));
1406  env.close();
1407  env (check::cash (bob, chkIdFroz2, USD(2)));
1408  env.close();
1409  env.require (balance (alice, USD(17)));
1410  env.require (balance (bob, USD( 3)));
1411 
1412  // Freeze bob's trustline. bob can't cash the check.
1413  env (trust(gw, bob["USD"](0), tfSetFreeze));
1414  env.close();
1415  env (check::cash (bob, chkIdFroz3, USD(3)), ter (tecFROZEN));
1416  env.close();
1417  env (check::cash (bob, chkIdFroz3, check::DeliverMin (USD(1))),
1418  ter (tecFROZEN));
1419  env.close();
1420 
1421  // Clear that freeze. Now check cashing works again.
1422  env (trust(gw, bob["USD"](0), tfClearFreeze));
1423  env.close();
1424  env (check::cash (bob, chkIdFroz3, check::DeliverMin (USD(1))));
1425  verifyDeliveredAmount (env, USD(3));
1426  env.require (balance (alice, USD(14)));
1427  env.require (balance (bob, USD( 6)));
1428 
1429  // Set bob's freeze bit in the other direction. Check
1430  // cashing fails.
1431  env (trust (bob, USD(20), tfSetFreeze));
1432  env.close();
1433  env (check::cash (bob, chkIdFroz4, USD(4)), ter (terNO_LINE));
1434  env.close();
1435  env (check::cash (bob, chkIdFroz4, check::DeliverMin (USD(1))),
1436  ter (terNO_LINE));
1437  env.close();
1438 
1439  // Clear bob's freeze bit and the check should be cashable.
1440  env (trust (bob, USD(20), tfClearFreeze));
1441  env.close();
1442  env (check::cash (bob, chkIdFroz4, USD(4)));
1443  env.close();
1444  env.require (balance (alice, USD(10)));
1445  env.require (balance (bob, USD(10)));
1446  }
1447  {
1448  // Set the RequireDest flag on bob's account (after the check
1449  // was created) then cash a check without a destination tag.
1450  env (fset (bob, asfRequireDest));
1451  env.close();
1452  env (check::cash (bob, chkIdNoDest1, USD(1)),
1453  ter (tecDST_TAG_NEEDED));
1454  env.close();
1455  env (check::cash (bob, chkIdNoDest1, check::DeliverMin (USD(0.5))),
1456  ter (tecDST_TAG_NEEDED));
1457  env.close();
1458 
1459  // bob can cash a check with a destination tag.
1460  env (check::cash (bob, chkIdHasDest2, USD(2)));
1461  env.close();
1462  env.require (balance (alice, USD( 8)));
1463  env.require (balance (bob, USD(12)));
1464 
1465  // Clear the RequireDest flag on bob's account so he can
1466  // cash the check with no DestinationTag.
1467  env (fclear (bob, asfRequireDest));
1468  env.close();
1469  env (check::cash (bob, chkIdNoDest1, USD(1)));
1470  env.close();
1471  env.require (balance (alice, USD( 7)));
1472  env.require (balance (bob, USD(13)));
1473  }
1474  }
1475 
1477  {
1478  // Explore many of the ways to cancel a check.
1479  testcase ("Cancel valid");
1480 
1481  using namespace test::jtx;
1482 
1483  Account const gw {"gateway"};
1484  Account const alice {"alice"};
1485  Account const bob {"bob"};
1486  Account const zoe {"zoe"};
1487  IOU const USD {gw["USD"]};
1488 
1489  // featureMultiSignReserve changes the reserve on a SignerList, so
1490  // check both before and after.
1491  FeatureBitset const allSupported {supported_amendments()};
1492  for (auto const features :
1493  {allSupported - featureMultiSignReserve,
1494  allSupported | featureMultiSignReserve})
1495  {
1496  Env env {*this, features};
1497 
1498  env.fund (XRP(1000), gw, alice, bob, zoe);
1499 
1500  // alice creates her checks ahead of time.
1501  // Three ordinary checks with no expiration.
1502  uint256 const chkId1 {getCheckIndex (alice, env.seq (alice))};
1503  env (check::create (alice, bob, USD(10)));
1504  env.close();
1505 
1506  uint256 const chkId2 {getCheckIndex (alice, env.seq (alice))};
1507  env (check::create (alice, bob, XRP(10)));
1508  env.close();
1509 
1510  uint256 const chkId3 {getCheckIndex (alice, env.seq (alice))};
1511  env (check::create (alice, bob, USD(10)));
1512  env.close();
1513 
1514  // Three checks that expire in 10 minutes.
1515  using namespace std::chrono_literals;
1516  uint256 const chkIdNotExp1 {getCheckIndex (alice, env.seq (alice))};
1517  env (check::create (alice, bob, XRP(10)), expiration (env.now()+600s));
1518  env.close();
1519 
1520  uint256 const chkIdNotExp2 {getCheckIndex (alice, env.seq (alice))};
1521  env (check::create (alice, bob, USD(10)), expiration (env.now()+600s));
1522  env.close();
1523 
1524  uint256 const chkIdNotExp3 {getCheckIndex (alice, env.seq (alice))};
1525  env (check::create (alice, bob, XRP(10)), expiration (env.now()+600s));
1526  env.close();
1527 
1528  // Three checks that expire in one second.
1529  uint256 const chkIdExp1 {getCheckIndex (alice, env.seq (alice))};
1530  env (check::create (alice, bob, USD(10)), expiration (env.now()+1s));
1531  env.close();
1532 
1533  uint256 const chkIdExp2 {getCheckIndex (alice, env.seq (alice))};
1534  env (check::create (alice, bob, XRP(10)), expiration (env.now()+1s));
1535  env.close();
1536 
1537  uint256 const chkIdExp3 {getCheckIndex (alice, env.seq (alice))};
1538  env (check::create (alice, bob, USD(10)), expiration (env.now()+1s));
1539  env.close();
1540 
1541  // Two checks to cancel using a regular key and using multisigning.
1542  uint256 const chkIdReg {getCheckIndex (alice, env.seq (alice))};
1543  env (check::create (alice, bob, USD(10)));
1544  env.close();
1545 
1546  uint256 const chkIdMSig {getCheckIndex (alice, env.seq (alice))};
1547  env (check::create (alice, bob, XRP(10)));
1548  env.close();
1549  BEAST_EXPECT (checksOnAccount (env, alice).size() == 11);
1550  BEAST_EXPECT (ownerCount (env, alice) == 11);
1551 
1552  // Creator, destination, and an outsider cancel the checks.
1553  env (check::cancel (alice, chkId1));
1554  env.close();
1555  BEAST_EXPECT (checksOnAccount (env, alice).size() == 10);
1556  BEAST_EXPECT (ownerCount (env, alice) == 10);
1557 
1558  env (check::cancel (bob, chkId2));
1559  env.close();
1560  BEAST_EXPECT (checksOnAccount (env, alice).size() == 9);
1561  BEAST_EXPECT (ownerCount (env, alice) == 9);
1562 
1563  env (check::cancel (zoe, chkId3), ter (tecNO_PERMISSION));
1564  env.close();
1565  BEAST_EXPECT (checksOnAccount (env, alice).size() == 9);
1566  BEAST_EXPECT (ownerCount (env, alice) == 9);
1567 
1568  // Creator, destination, and an outsider cancel unexpired checks.
1569  env (check::cancel (alice, chkIdNotExp1));
1570  env.close();
1571  BEAST_EXPECT (checksOnAccount (env, alice).size() == 8);
1572  BEAST_EXPECT (ownerCount (env, alice) == 8);
1573 
1574  env (check::cancel (bob, chkIdNotExp2));
1575  env.close();
1576  BEAST_EXPECT (checksOnAccount (env, alice).size() == 7);
1577  BEAST_EXPECT (ownerCount (env, alice) == 7);
1578 
1579  env (check::cancel (zoe, chkIdNotExp3), ter (tecNO_PERMISSION));
1580  env.close();
1581  BEAST_EXPECT (checksOnAccount (env, alice).size() == 7);
1582  BEAST_EXPECT (ownerCount (env, alice) == 7);
1583 
1584  // Creator, destination, and an outsider cancel expired checks.
1585  env (check::cancel (alice, chkIdExp1));
1586  env.close();
1587  BEAST_EXPECT (checksOnAccount (env, alice).size() == 6);
1588  BEAST_EXPECT (ownerCount (env, alice) == 6);
1589 
1590  env (check::cancel (bob, chkIdExp2));
1591  env.close();
1592  BEAST_EXPECT (checksOnAccount (env, alice).size() == 5);
1593  BEAST_EXPECT (ownerCount (env, alice) == 5);
1594 
1595  env (check::cancel (zoe, chkIdExp3));
1596  env.close();
1597  BEAST_EXPECT (checksOnAccount (env, alice).size() == 4);
1598  BEAST_EXPECT (ownerCount (env, alice) == 4);
1599 
1600  // Use a regular key and also multisign to cancel checks.
1601  Account const alie {"alie", KeyType::ed25519};
1602  env (regkey (alice, alie));
1603  env.close();
1604 
1605  Account const bogie {"bogie", KeyType::secp256k1};
1606  Account const demon {"demon", KeyType::ed25519};
1607  env (signers (alice, 2, {{bogie, 1}, {demon, 1}}), sig (alie));
1608  env.close();
1609 
1610  // If featureMultiSignReserve is enabled then alices's signer list
1611  // has an owner count of 1, otherwise it's 4.
1612  int const signersCount {features[featureMultiSignReserve] ? 1 : 4};
1613 
1614  // alice uses her regular key to cancel a check.
1615  env (check::cancel (alice, chkIdReg), sig (alie));
1616  env.close();
1617  BEAST_EXPECT (checksOnAccount (env, alice).size() == 3);
1618  BEAST_EXPECT (ownerCount (env, alice) == signersCount + 3);
1619 
1620  // alice uses multisigning to cancel a check.
1621  XRPAmount const baseFeeDrops {env.current()->fees().base};
1622  env (check::cancel (alice, chkIdMSig),
1623  msig (bogie, demon), fee (3 * baseFeeDrops));
1624  env.close();
1625  BEAST_EXPECT (checksOnAccount (env, alice).size() == 2);
1626  BEAST_EXPECT (ownerCount (env, alice) == signersCount + 2);
1627 
1628  // Creator and destination cancel the remaining unexpired checks.
1629  env (check::cancel (alice, chkId3), sig (alice));
1630  env.close();
1631  BEAST_EXPECT (checksOnAccount (env, alice).size() == 1);
1632  BEAST_EXPECT (ownerCount (env, alice) == signersCount + 1);
1633 
1634  env (check::cancel (bob, chkIdNotExp3));
1635  env.close();
1636  BEAST_EXPECT (checksOnAccount (env, alice).size() == 0);
1637  BEAST_EXPECT (ownerCount (env, alice) == signersCount + 0);
1638  }
1639  }
1640 
1642  {
1643  // Explore many of the ways to fail at canceling a check.
1644  testcase ("Cancel invalid");
1645 
1646  using namespace test::jtx;
1647 
1648  Account const alice {"alice"};
1649  Account const bob {"bob"};
1650 
1651  Env env {*this};
1652 
1653  env.fund (XRP(1000), alice, bob);
1654 
1655  // Bad fee.
1656  env (check::cancel (bob, getCheckIndex (alice, env.seq (alice))),
1657  fee (drops(-10)), ter (temBAD_FEE));
1658  env.close();
1659 
1660  // Bad flags.
1661  env (check::cancel (bob, getCheckIndex (alice, env.seq (alice))),
1662  txflags (tfImmediateOrCancel), ter (temINVALID_FLAG));
1663  env.close();
1664 
1665  // Non-existent check.
1666  env (check::cancel (bob, getCheckIndex (alice, env.seq (alice))),
1667  ter (tecNO_ENTRY));
1668  env.close();
1669  }
1670 
1672  {
1673  testcase ("Fix1623 enable");
1674 
1675  using namespace test::jtx;
1676 
1677  auto testEnable = [this] (FeatureBitset const& features, bool hasFields)
1678  {
1679  // Unless fix1623 is enabled a "tx" RPC command should return
1680  // neither "DeliveredAmount" nor "delivered_amount" on a CheckCash
1681  // transaction.
1682  Account const alice {"alice"};
1683  Account const bob {"bob"};
1684 
1685  Env env {*this, features};
1686 
1687  env.fund (XRP(1000), alice, bob);
1688  env.close();
1689 
1690  uint256 const chkId {getCheckIndex (alice, env.seq (alice))};
1691  env (check::create (alice, bob, XRP(200)));
1692  env.close();
1693 
1694  env (check::cash (bob, chkId, check::DeliverMin (XRP(100))));
1695 
1696  // Get the hash for the most recent transaction.
1697  std::string const txHash {
1698  env.tx()->getJson (JsonOptions::none)[jss::hash].asString()};
1699 
1700  // DeliveredAmount and delivered_amount are either present or
1701  // not present in the metadata returned by "tx" based on fix1623.
1702  env.close();
1703  Json::Value const meta =
1704  env.rpc ("tx", txHash)[jss::result][jss::meta];
1705 
1706  BEAST_EXPECT(meta.isMember (
1707  sfDeliveredAmount.jsonName) == hasFields);
1708  BEAST_EXPECT(meta.isMember (jss::delivered_amount) == hasFields);
1709  };
1710 
1711  // Run both the disabled and enabled cases.
1712  testEnable (supported_amendments() - fix1623, false);
1713  testEnable (supported_amendments(), true);
1714  }
1715 
1716 public:
1717  void run () override
1718  {
1719  testEnabled();
1720  testCreateValid();
1722  testCashXRP();
1723  testCashIOU();
1724  testCashXferFee();
1725  testCashQuality();
1726  testCashInvalid();
1727  testCancelValid();
1730  }
1731 };
1732 
1733 BEAST_DEFINE_TESTSUITE (Check, tx, ripple);
1734 
1735 } // ripple
1736 
ripple::badCurrency
Currency const & badCurrency()
We deliberately disallow the currency that looks like "XRP" because too many people were using it ins...
Definition: UintTypes.cpp:123
ripple::STAmount::negate
void negate()
Definition: STAmount.h:216
ripple::tecFROZEN
@ tecFROZEN
Definition: TER.h:268
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
std::string
STL class.
std::shared_ptr
STL class.
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
ripple::test::jtx::dest_tag
Set DestinationTag on a JTx.
Definition: Check_test.cpp:67
ripple::temBAD_CURRENCY
@ temBAD_CURRENCY
Definition: TER.h:88
ripple::test::jtx::Env::tx
std::shared_ptr< STTx const > tx() const
Return the tx data for the last JTx.
Definition: Env.cpp:370
ripple::terNO_LINE
@ terNO_LINE
Definition: TER.h:197
ripple::Check_test::testEnabled
void testEnabled()
Definition: Check_test.cpp:140
ripple::asfGlobalFreeze
const std::uint32_t asfGlobalFreeze
Definition: TxFlags.h:71
ripple::sfDeliveredAmount
const SF_Amount sfDeliveredAmount(access, STI_AMOUNT, 18, "DeliveredAmount")
Definition: SField.h:437
std::vector
STL class.
ripple::STAmount::getJson
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:582
ripple::test::jtx::dest_tag::dest_tag
dest_tag(std::uint32_t tag)
Definition: Check_test.cpp:73
ripple::tecDST_TAG_NEEDED
@ tecDST_TAG_NEEDED
Definition: TER.h:274
ripple::test::jtx::expiration::operator()
void operator()(Env &, JTx &jt) const
Definition: Check_test.cpp:41
ripple::featureMultiSignReserve
const uint256 featureMultiSignReserve
Definition: Feature.cpp:172
ripple::test::jtx::source_tag::tag_
const std::uint32_t tag_
Definition: Check_test.cpp:51
ripple::sfAmount
const SF_Amount sfAmount(access, STI_AMOUNT, 1, "Amount")
Definition: SField.h:423
ripple::tfClearFreeze
const std::uint32_t tfClearFreeze
Definition: TxFlags.h:93
ripple::sfOwnerCount
const SF_U32 sfOwnerCount(access, STI_UINT32, 13, "OwnerCount")
Definition: SField.h:349
ripple::SField::jsonName
const Json::StaticString jsonName
Definition: SField.h:140
ripple::sfDestinationTag
const SF_U32 sfDestinationTag(access, STI_UINT32, 14, "DestinationTag")
Definition: SField.h:350
ripple::forEachItem
void forEachItem(ReadView const &view, AccountID const &id, std::function< void(std::shared_ptr< SLE const > const &)> f)
Iterate all items in an account's owner directory.
Definition: View.cpp:244
ripple::Check_test::testCashXferFee
void testCashXferFee()
Definition: Check_test.cpp:917
ripple::KeyType::ed25519
@ ed25519
ripple::test::jtx::expiration
Set Expiration on a JTx.
Definition: Check_test.cpp:29
ripple::base_uint< 256 >
ripple::test::jtx::source_tag
Set SourceTag on a JTx.
Definition: Check_test.cpp:48
ripple::getCheckIndex
uint256 getCheckIndex(AccountID const &account, std::uint32_t uSequence)
Definition: Indexes.cpp:186
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:109
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::Check_test::ownerCount
static std::uint32_t ownerCount(test::jtx::Env const &env, test::jtx::Account const &account)
Definition: Check_test.cpp:106
ripple::asfRequireAuth
const std::uint32_t asfRequireAuth
Definition: TxFlags.h:66
ripple::JsonOptions::none
@ none
ripple::Check_test::run
void run() override
Definition: Check_test.cpp:1717
ripple::test::jtx::JTx
Execution context for applying a JSON transaction.
Definition: JTx.h:41
ripple::test::jtx::dest_tag::operator()
void operator()(Env &, JTx &jt) const
Definition: Check_test.cpp:79
ripple::fix1623
const uint256 fix1623
Definition: Feature.cpp:168
ripple::Check_test::testCashXRP
void testCashXRP()
Definition: Check_test.cpp:468
ripple::STAmount
Definition: STAmount.h:42
std::chrono::time_point
ripple::temBAD_AMOUNT
@ temBAD_AMOUNT
Definition: TER.h:87
Json::Value::isMember
bool isMember(const char *key) const
Return true if the object has a member named key.
Definition: json_value.cpp:961
ripple::Check_test::testCashIOU
void testCashIOU()
Definition: Check_test.cpp:587
std::uint32_t
ripple::tfSetFreeze
const std::uint32_t tfSetFreeze
Definition: TxFlags.h:92
ripple::tfImmediateOrCancel
const std::uint32_t tfImmediateOrCancel
Definition: TxFlags.h:77
ripple::STAmount::setIssue
void setIssue(Issue const &issue)
Set the Issue for this amount and update mIsNative.
Definition: STAmount.cpp:407
ripple::tecPATH_PARTIAL
@ tecPATH_PARTIAL
Definition: TER.h:247
ripple::featureChecks
const uint256 featureChecks
Definition: Feature.cpp:165
ripple::Check_test::testCancelValid
void testCancelValid()
Definition: Check_test.cpp:1476
ripple::test::jtx::expiration::expry_
const std::uint32_t expry_
Definition: Check_test.cpp:32
ripple::sfSourceTag
const SF_U32 sfSourceTag(access, STI_UINT32, 3, "SourceTag")
Definition: SField.h:339
ripple::temREDUNDANT
@ temREDUNDANT
Definition: TER.h:110
ripple::temBAD_FEE
@ temBAD_FEE
Definition: TER.h:90
ripple::sfExpiration
const SF_U32 sfExpiration(access, STI_UINT32, 10, "Expiration")
Definition: SField.h:346
ripple::asfRequireDest
const std::uint32_t asfRequireDest
Definition: TxFlags.h:65
ripple::KeyType::secp256k1
@ secp256k1
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
Json::Value::removeMember
Value removeMember(const char *key)
Remove and return the named member.
Definition: json_value.cpp:936
ripple::tecNO_LINE
@ tecNO_LINE
Definition: TER.h:266
ripple::tecEXPIRED
@ tecEXPIRED
Definition: TER.h:279
ripple::sfDeliverMin
const SF_Amount sfDeliverMin(access, STI_AMOUNT, 10, "DeliverMin")
Definition: SField.h:432
ripple::Check_test::testCashInvalid
void testCashInvalid()
Definition: Check_test.cpp:1182
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:112
ripple::Check_test
Definition: Check_test.cpp:88
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:114
ripple::test::jtx::Env::le
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition: Env.cpp:202
ripple::Check_test::checksOnAccount
static std::vector< std::shared_ptr< SLE const > > checksOnAccount(test::jtx::Env &env, test::jtx::Account account)
Definition: Check_test.cpp:92
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:270
ripple::FeatureBitset
Definition: Feature.h:153
ripple::tecPATH_DRY
@ tecPATH_DRY
Definition: TER.h:259
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:272
std::size_t
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
ripple::Check_test::testCreateInvalid
void testCreateInvalid()
Definition: Check_test.cpp:288
ripple::test::jtx::source_tag::source_tag
source_tag(std::uint32_t tag)
Definition: Check_test.cpp:54
ripple::tecNO_ENTRY
@ tecNO_ENTRY
Definition: TER.h:271
ripple::Check_test::testFix1623Enable
void testFix1623Enable()
Definition: Check_test.cpp:1671
ripple::temMALFORMED
@ temMALFORMED
Definition: TER.h:85
ripple::Check_test::testCreateValid
void testCreateValid()
Definition: Check_test.cpp:191
ripple::test::jtx::expiration::expiration
expiration(NetClock::time_point const &expiry)
Definition: Check_test.cpp:35
ripple::tecNO_AUTH
@ tecNO_AUTH
Definition: TER.h:265
ripple::temBAD_EXPIRATION
@ temBAD_EXPIRATION
Definition: TER.h:89
ripple::tfSetfAuth
const std::uint32_t tfSetfAuth
Definition: TxFlags.h:89
ripple::test::jtx::dest_tag::tag_
const std::uint32_t tag_
Definition: Check_test.cpp:70
ripple::test::jtx::Env::current
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:296
ripple::Check_test::verifyDeliveredAmount
void verifyDeliveredAmount(test::jtx::Env &env, STAmount const &amount)
Definition: Check_test.cpp:118
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:117
ripple::tecNO_DST
@ tecNO_DST
Definition: TER.h:255
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
ripple::Check_test::testCashQuality
void testCashQuality()
Definition: Check_test.cpp:986
ripple::Check_test::testCancelInvalid
void testCancelInvalid()
Definition: Check_test.cpp:1641
Json::Value
Represents a JSON value.
Definition: json_value.h:141
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::test::jtx::source_tag::operator()
void operator()(Env &, JTx &jt) const
Definition: Check_test.cpp:60