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 <ripple/protocol/Feature.h>
21 #include <ripple/protocol/jss.h>
22 #include <test/jtx.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) : tag_{tag}
55  {
56  }
57 
58  void
59  operator()(Env&, JTx& jt) const
60  {
62  }
63 };
64 
66 class dest_tag
67 {
68 private:
70 
71 public:
72  explicit dest_tag(std::uint32_t tag) : tag_{tag}
73  {
74  }
75 
76  void
77  operator()(Env&, JTx& jt) const
78  {
80  }
81 };
82 
83 } // namespace jtx
84 } // namespace test
85 
86 class Check_test : public beast::unit_test::suite
87 {
89 
90  static uint256
91  getCheckIndex(AccountID const& account, std::uint32_t uSequence)
92  {
93  return keylet::check(account, uSequence).key;
94  }
95 
96  // Helper function that returns the Checks on an account.
99  {
101  forEachItem(
102  *env.current(),
103  account,
104  [&result](std::shared_ptr<SLE const> const& sle) {
105  if (sle && sle->getType() == ltCHECK)
106  result.push_back(sle);
107  });
108  return result;
109  }
110 
111  // Helper function that returns the owner count on an account.
112  static std::uint32_t
113  ownerCount(test::jtx::Env const& env, test::jtx::Account const& account)
114  {
115  std::uint32_t ret{0};
116  if (auto const sleAccount = env.le(account))
117  ret = sleAccount->getFieldU32(sfOwnerCount);
118  return ret;
119  }
120 
121  // Helper function that verifies the expected DeliveredAmount is present.
122  //
123  // NOTE: the function _infers_ the transaction to operate on by calling
124  // env.tx(), which returns the result from the most recent transaction.
125  void
127  {
128  // Get the hash for the most recent transaction.
129  std::string const txHash{
130  env.tx()->getJson(JsonOptions::none)[jss::hash].asString()};
131 
132  // Verify DeliveredAmount and delivered_amount metadata are correct.
133  env.close();
134  Json::Value const meta = env.rpc("tx", txHash)[jss::result][jss::meta];
135 
136  // Expect there to be a DeliveredAmount field.
137  if (!BEAST_EXPECT(meta.isMember(sfDeliveredAmount.jsonName)))
138  return;
139 
140  // DeliveredAmount and delivered_amount should both be present and
141  // equal amount.
142  BEAST_EXPECT(
143  meta[sfDeliveredAmount.jsonName] ==
144  amount.getJson(JsonOptions::none));
145  BEAST_EXPECT(
146  meta[jss::delivered_amount] == amount.getJson(JsonOptions::none));
147  }
148 
149  void
151  {
152  testcase("Enabled");
153 
154  using namespace test::jtx;
155  Account const alice{"alice"};
156  {
157  // If the Checks amendment is not enabled, you should not be able
158  // to create, cash, or cancel checks.
159  Env env{*this, features - featureChecks};
160 
161  env.fund(XRP(1000), alice);
162 
163  uint256 const checkId{
164  getCheckIndex(env.master, env.seq(env.master))};
165  env(check::create(env.master, alice, XRP(100)), ter(temDISABLED));
166  env.close();
167 
168  env(check::cash(alice, checkId, XRP(100)), ter(temDISABLED));
169  env.close();
170 
171  env(check::cancel(alice, checkId), ter(temDISABLED));
172  env.close();
173  }
174  {
175  // If the Checks amendment is enabled all check-related
176  // facilities should be available.
177  Env env{*this, features};
178 
179  env.fund(XRP(1000), alice);
180 
181  uint256 const checkId1{
182  getCheckIndex(env.master, env.seq(env.master))};
183  env(check::create(env.master, alice, XRP(100)));
184  env.close();
185 
186  env(check::cash(alice, checkId1, XRP(100)));
187  env.close();
188 
189  uint256 const checkId2{
190  getCheckIndex(env.master, env.seq(env.master))};
191  env(check::create(env.master, alice, XRP(100)));
192  env.close();
193 
194  env(check::cancel(alice, checkId2));
195  env.close();
196  }
197  }
198 
199  void
201  {
202  // Explore many of the valid ways to create a check.
203  testcase("Create valid");
204 
205  using namespace test::jtx;
206 
207  Account const gw{"gateway"};
208  Account const alice{"alice"};
209  Account const bob{"bob"};
210  IOU const USD{gw["USD"]};
211 
212  Env env{*this, features};
213 
214  STAmount const startBalance{XRP(1000).value()};
215  env.fund(startBalance, gw, alice, bob);
216 
217  // Note that no trust line has been set up for alice, but alice can
218  // still write a check for USD. You don't have to have the funds
219  // necessary to cover a check in order to write a check.
220  auto writeTwoChecks = [&env, &USD, this](
221  Account const& from, Account const& to) {
222  std::uint32_t const fromOwnerCount{ownerCount(env, from)};
223  std::uint32_t const toOwnerCount{ownerCount(env, to)};
224 
225  std::size_t const fromCkCount{checksOnAccount(env, from).size()};
226  std::size_t const toCkCount{checksOnAccount(env, to).size()};
227 
228  env(check::create(from, to, XRP(2000)));
229  env.close();
230 
231  env(check::create(from, to, USD(50)));
232  env.close();
233 
234  BEAST_EXPECT(checksOnAccount(env, from).size() == fromCkCount + 2);
235  BEAST_EXPECT(checksOnAccount(env, to).size() == toCkCount + 2);
236 
237  env.require(owners(from, fromOwnerCount + 2));
238  env.require(
239  owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
240  };
241  // from to
242  writeTwoChecks(alice, bob);
243  writeTwoChecks(gw, alice);
244  writeTwoChecks(alice, gw);
245 
246  // Now try adding the various optional fields. There's no
247  // expected interaction between these optional fields; other than
248  // the expiration, they are just plopped into the ledger. So I'm
249  // not looking at interactions.
250  using namespace std::chrono_literals;
251  std::size_t const aliceCount{checksOnAccount(env, alice).size()};
252  std::size_t const bobCount{checksOnAccount(env, bob).size()};
253  env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
254  env.close();
255 
256  env(check::create(alice, bob, USD(50)), source_tag(2));
257  env.close();
258  env(check::create(alice, bob, USD(50)), dest_tag(3));
259  env.close();
260  env(check::create(alice, bob, USD(50)), invoice_id(uint256{4}));
261  env.close();
262  env(check::create(alice, bob, USD(50)),
263  expiration(env.now() + 1s),
264  source_tag(12),
265  dest_tag(13),
266  invoice_id(uint256{4}));
267  env.close();
268 
269  BEAST_EXPECT(checksOnAccount(env, alice).size() == aliceCount + 5);
270  BEAST_EXPECT(checksOnAccount(env, bob).size() == bobCount + 5);
271 
272  // Use a regular key and also multisign to create a check.
273  Account const alie{"alie", KeyType::ed25519};
274  env(regkey(alice, alie));
275  env.close();
276 
277  Account const bogie{"bogie", KeyType::secp256k1};
278  Account const demon{"demon", KeyType::ed25519};
279  env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
280  env.close();
281 
282  // alice uses her regular key to create a check.
283  env(check::create(alice, bob, USD(50)), sig(alie));
284  env.close();
285  BEAST_EXPECT(checksOnAccount(env, alice).size() == aliceCount + 6);
286  BEAST_EXPECT(checksOnAccount(env, bob).size() == bobCount + 6);
287 
288  // alice uses multisigning to create a check.
289  XRPAmount const baseFeeDrops{env.current()->fees().base};
290  env(check::create(alice, bob, USD(50)),
291  msig(bogie, demon),
292  fee(3 * baseFeeDrops));
293  env.close();
294  BEAST_EXPECT(checksOnAccount(env, alice).size() == aliceCount + 7);
295  BEAST_EXPECT(checksOnAccount(env, bob).size() == bobCount + 7);
296  }
297 
298  void
300  {
301  testcase("Create valid with disallow incoming");
302 
303  using namespace test::jtx;
304 
305  // test flag doesn't set unless amendment enabled
306  {
307  Env env{*this, features - disallowIncoming};
308  Account const alice{"alice"};
309  env.fund(XRP(10000), alice);
310  env(fset(alice, asfDisallowIncomingCheck));
311  env.close();
312  auto const sle = env.le(alice);
313  uint32_t flags = sle->getFlags();
314  BEAST_EXPECT(!(flags & lsfDisallowIncomingCheck));
315  }
316 
317  Account const gw{"gateway"};
318  Account const alice{"alice"};
319  Account const bob{"bob"};
320  IOU const USD{gw["USD"]};
321 
322  Env env{*this, features | disallowIncoming};
323 
324  STAmount const startBalance{XRP(1000).value()};
325  env.fund(startBalance, gw, alice, bob);
326 
327  /*
328  * Attempt to create two checks from `from` to `to` and
329  * require they both result in error/success code `expected`
330  */
331  auto writeTwoChecksDI = [&env, &USD, this](
332  Account const& from,
333  Account const& to,
334  TER expected) {
335  std::uint32_t const fromOwnerCount{ownerCount(env, from)};
336  std::uint32_t const toOwnerCount{ownerCount(env, to)};
337 
338  std::size_t const fromCkCount{checksOnAccount(env, from).size()};
339  std::size_t const toCkCount{checksOnAccount(env, to).size()};
340 
341  env(check::create(from, to, XRP(2000)), ter(expected));
342  env.close();
343 
344  env(check::create(from, to, USD(50)), ter(expected));
345  env.close();
346 
347  if (expected == tesSUCCESS)
348  {
349  BEAST_EXPECT(
350  checksOnAccount(env, from).size() == fromCkCount + 2);
351  BEAST_EXPECT(checksOnAccount(env, to).size() == toCkCount + 2);
352 
353  env.require(owners(from, fromOwnerCount + 2));
354  env.require(
355  owners(to, to == from ? fromOwnerCount + 2 : toOwnerCount));
356  return;
357  }
358 
359  BEAST_EXPECT(checksOnAccount(env, from).size() == fromCkCount);
360  BEAST_EXPECT(checksOnAccount(env, to).size() == toCkCount);
361 
362  env.require(owners(from, fromOwnerCount));
363  env.require(owners(to, to == from ? fromOwnerCount : toOwnerCount));
364  };
365 
366  // enable the DisallowIncoming flag on both bob and alice
367  env(fset(bob, asfDisallowIncomingCheck));
368  env(fset(alice, asfDisallowIncomingCheck));
369  env.close();
370 
371  // both alice and bob can't receive checks
372  writeTwoChecksDI(alice, bob, tecNO_PERMISSION);
373  writeTwoChecksDI(gw, alice, tecNO_PERMISSION);
374 
375  // remove the flag from alice but not from bob
376  env(fclear(alice, asfDisallowIncomingCheck));
377  env.close();
378 
379  // now bob can send alice a cheque but not visa-versa
380  writeTwoChecksDI(bob, alice, tesSUCCESS);
381  writeTwoChecksDI(alice, bob, tecNO_PERMISSION);
382 
383  // remove bob's flag too
384  env(fclear(bob, asfDisallowIncomingCheck));
385  env.close();
386 
387  // now they can send checks freely
388  writeTwoChecksDI(bob, alice, tesSUCCESS);
389  writeTwoChecksDI(alice, bob, tesSUCCESS);
390  }
391 
392  void
394  {
395  // Explore many of the invalid ways to create a check.
396  testcase("Create invalid");
397 
398  using namespace test::jtx;
399 
400  Account const gw1{"gateway1"};
401  Account const gwF{"gatewayFrozen"};
402  Account const alice{"alice"};
403  Account const bob{"bob"};
404  IOU const USD{gw1["USD"]};
405 
406  Env env{*this, features};
407 
408  STAmount const startBalance{XRP(1000).value()};
409  env.fund(startBalance, gw1, gwF, alice, bob);
410 
411  // Bad fee.
412  env(check::create(alice, bob, USD(50)),
413  fee(drops(-10)),
414  ter(temBAD_FEE));
415  env.close();
416 
417  // Bad flags.
418  env(check::create(alice, bob, USD(50)),
419  txflags(tfImmediateOrCancel),
420  ter(temINVALID_FLAG));
421  env.close();
422 
423  // Check to self.
424  env(check::create(alice, alice, XRP(10)), ter(temREDUNDANT));
425  env.close();
426 
427  // Bad amount.
428  env(check::create(alice, bob, drops(-1)), ter(temBAD_AMOUNT));
429  env.close();
430 
431  env(check::create(alice, bob, drops(0)), ter(temBAD_AMOUNT));
432  env.close();
433 
434  env(check::create(alice, bob, drops(1)));
435  env.close();
436 
437  env(check::create(alice, bob, USD(-1)), ter(temBAD_AMOUNT));
438  env.close();
439 
440  env(check::create(alice, bob, USD(0)), ter(temBAD_AMOUNT));
441  env.close();
442 
443  env(check::create(alice, bob, USD(1)));
444  env.close();
445  {
446  IOU const BAD{gw1, badCurrency()};
447  env(check::create(alice, bob, BAD(2)), ter(temBAD_CURRENCY));
448  env.close();
449  }
450 
451  // Bad expiration.
452  env(check::create(alice, bob, USD(50)),
453  expiration(NetClock::time_point{}),
454  ter(temBAD_EXPIRATION));
455  env.close();
456 
457  // Destination does not exist.
458  Account const bogie{"bogie"};
459  env(check::create(alice, bogie, USD(50)), ter(tecNO_DST));
460  env.close();
461 
462  // Require destination tag.
463  env(fset(bob, asfRequireDest));
464  env.close();
465 
466  env(check::create(alice, bob, USD(50)), ter(tecDST_TAG_NEEDED));
467  env.close();
468 
469  env(check::create(alice, bob, USD(50)), dest_tag(11));
470  env.close();
471 
472  env(fclear(bob, asfRequireDest));
473  env.close();
474  {
475  // Globally frozen asset.
476  IOU const USF{gwF["USF"]};
477  env(fset(gwF, asfGlobalFreeze));
478  env.close();
479 
480  env(check::create(alice, bob, USF(50)), ter(tecFROZEN));
481  env.close();
482 
483  env(fclear(gwF, asfGlobalFreeze));
484  env.close();
485 
486  env(check::create(alice, bob, USF(50)));
487  env.close();
488  }
489  {
490  // Frozen trust line. Check creation should be similar to payment
491  // behavior in the face of frozen trust lines.
492  env.trust(USD(1000), alice);
493  env.trust(USD(1000), bob);
494  env.close();
495  env(pay(gw1, alice, USD(25)));
496  env(pay(gw1, bob, USD(25)));
497  env.close();
498 
499  // Setting trustline freeze in one direction prevents alice from
500  // creating a check for USD. But bob and gw1 should still be able
501  // to create a check for USD to alice.
502  env(trust(gw1, alice["USD"](0), tfSetFreeze));
503  env.close();
504  env(check::create(alice, bob, USD(50)), ter(tecFROZEN));
505  env.close();
506  env(pay(alice, bob, USD(1)), ter(tecPATH_DRY));
507  env.close();
508  env(check::create(bob, alice, USD(50)));
509  env.close();
510  env(pay(bob, alice, USD(1)));
511  env.close();
512  env(check::create(gw1, alice, USD(50)));
513  env.close();
514  env(pay(gw1, alice, USD(1)));
515  env.close();
516 
517  // Clear that freeze. Now check creation works.
518  env(trust(gw1, alice["USD"](0), tfClearFreeze));
519  env.close();
520  env(check::create(alice, bob, USD(50)));
521  env.close();
522  env(check::create(bob, alice, USD(50)));
523  env.close();
524  env(check::create(gw1, alice, USD(50)));
525  env.close();
526 
527  // Freezing in the other direction does not effect alice's USD
528  // check creation, but prevents bob and gw1 from writing a check
529  // for USD to alice.
530  env(trust(alice, USD(0), tfSetFreeze));
531  env.close();
532  env(check::create(alice, bob, USD(50)));
533  env.close();
534  env(pay(alice, bob, USD(1)));
535  env.close();
536  env(check::create(bob, alice, USD(50)), ter(tecFROZEN));
537  env.close();
538  env(pay(bob, alice, USD(1)), ter(tecPATH_DRY));
539  env.close();
540  env(check::create(gw1, alice, USD(50)), ter(tecFROZEN));
541  env.close();
542  env(pay(gw1, alice, USD(1)), ter(tecPATH_DRY));
543  env.close();
544 
545  // Clear that freeze.
546  env(trust(alice, USD(0), tfClearFreeze));
547  env.close();
548  }
549 
550  // Expired expiration.
551  env(check::create(alice, bob, USD(50)),
552  expiration(env.now()),
553  ter(tecEXPIRED));
554  env.close();
555 
556  using namespace std::chrono_literals;
557  env(check::create(alice, bob, USD(50)), expiration(env.now() + 1s));
558  env.close();
559 
560  // Insufficient reserve.
561  Account const cheri{"cheri"};
562  env.fund(env.current()->fees().accountReserve(1) - drops(1), cheri);
563 
564  env(check::create(cheri, bob, USD(50)),
565  fee(drops(env.current()->fees().base)),
567  env.close();
568 
569  env(pay(bob, cheri, drops(env.current()->fees().base + 1)));
570  env.close();
571 
572  env(check::create(cheri, bob, USD(50)));
573  env.close();
574  }
575 
576  void
578  {
579  // Explore many of the valid ways to cash a check for XRP.
580  testcase("Cash XRP");
581 
582  using namespace test::jtx;
583 
584  Account const alice{"alice"};
585  Account const bob{"bob"};
586 
587  Env env{*this, features};
588 
589  XRPAmount const baseFeeDrops{env.current()->fees().base};
590  STAmount const startBalance{XRP(300).value()};
591  env.fund(startBalance, alice, bob);
592  {
593  // Basic XRP check.
594  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
595  env(check::create(alice, bob, XRP(10)));
596  env.close();
597  env.require(balance(alice, startBalance - drops(baseFeeDrops)));
598  env.require(balance(bob, startBalance));
599  BEAST_EXPECT(checksOnAccount(env, alice).size() == 1);
600  BEAST_EXPECT(checksOnAccount(env, bob).size() == 1);
601  BEAST_EXPECT(ownerCount(env, alice) == 1);
602  BEAST_EXPECT(ownerCount(env, bob) == 0);
603 
604  env(check::cash(bob, chkId, XRP(10)));
605  env.close();
606  env.require(
607  balance(alice, startBalance - XRP(10) - drops(baseFeeDrops)));
608  env.require(
609  balance(bob, startBalance + XRP(10) - drops(baseFeeDrops)));
610  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
611  BEAST_EXPECT(checksOnAccount(env, bob).size() == 0);
612  BEAST_EXPECT(ownerCount(env, alice) == 0);
613  BEAST_EXPECT(ownerCount(env, bob) == 0);
614 
615  // Make alice's and bob's balances easy to think about.
616  env(pay(env.master, alice, XRP(10) + drops(baseFeeDrops)));
617  env(pay(bob, env.master, XRP(10) - drops(baseFeeDrops * 2)));
618  env.close();
619  env.require(balance(alice, startBalance));
620  env.require(balance(bob, startBalance));
621  }
622  {
623  // Write a check that chews into alice's reserve.
624  STAmount const reserve{env.current()->fees().accountReserve(0)};
625  STAmount const checkAmount{
626  startBalance - reserve - drops(baseFeeDrops)};
627  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
628  env(check::create(alice, bob, checkAmount));
629  env.close();
630 
631  // bob tries to cash for more than the check amount.
632  env(check::cash(bob, chkId, checkAmount + drops(1)),
633  ter(tecPATH_PARTIAL));
634  env.close();
635  env(check::cash(
636  bob, chkId, check::DeliverMin(checkAmount + drops(1))),
637  ter(tecPATH_PARTIAL));
638  env.close();
639 
640  // bob cashes exactly the check amount. This is successful
641  // because one unit of alice's reserve is released when the
642  // check is consumed.
643  env(check::cash(bob, chkId, check::DeliverMin(checkAmount)));
644  verifyDeliveredAmount(env, drops(checkAmount.mantissa()));
645  env.require(balance(alice, reserve));
646  env.require(balance(
647  bob, startBalance + checkAmount - drops(baseFeeDrops * 3)));
648  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
649  BEAST_EXPECT(checksOnAccount(env, bob).size() == 0);
650  BEAST_EXPECT(ownerCount(env, alice) == 0);
651  BEAST_EXPECT(ownerCount(env, bob) == 0);
652 
653  // Make alice's and bob's balances easy to think about.
654  env(pay(env.master, alice, checkAmount + drops(baseFeeDrops)));
655  env(pay(bob, env.master, checkAmount - drops(baseFeeDrops * 4)));
656  env.close();
657  env.require(balance(alice, startBalance));
658  env.require(balance(bob, startBalance));
659  }
660  {
661  // Write a check that goes one drop past what alice can pay.
662  STAmount const reserve{env.current()->fees().accountReserve(0)};
663  STAmount const checkAmount{
664  startBalance - reserve - drops(baseFeeDrops - 1)};
665  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
666  env(check::create(alice, bob, checkAmount));
667  env.close();
668 
669  // bob tries to cash for exactly the check amount. Fails because
670  // alice is one drop shy of funding the check.
671  env(check::cash(bob, chkId, checkAmount), ter(tecPATH_PARTIAL));
672  env.close();
673 
674  // bob decides to get what he can from the bounced check.
675  env(check::cash(bob, chkId, check::DeliverMin(drops(1))));
676  verifyDeliveredAmount(env, drops(checkAmount.mantissa() - 1));
677  env.require(balance(alice, reserve));
678  env.require(balance(
679  bob, startBalance + checkAmount - drops(baseFeeDrops * 2 + 1)));
680  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
681  BEAST_EXPECT(checksOnAccount(env, bob).size() == 0);
682  BEAST_EXPECT(ownerCount(env, alice) == 0);
683  BEAST_EXPECT(ownerCount(env, bob) == 0);
684 
685  // Make alice's and bob's balances easy to think about.
686  env(pay(env.master, alice, checkAmount + drops(baseFeeDrops - 1)));
687  env(pay(
688  bob, env.master, checkAmount - drops(baseFeeDrops * 3 + 1)));
689  env.close();
690  env.require(balance(alice, startBalance));
691  env.require(balance(bob, startBalance));
692  }
693  }
694 
695  void
697  {
698  // Explore many of the valid ways to cash a check for an IOU.
699  testcase("Cash IOU");
700 
701  using namespace test::jtx;
702 
703  bool const cashCheckMakesTrustLine =
705 
706  Account const gw{"gateway"};
707  Account const alice{"alice"};
708  Account const bob{"bob"};
709  IOU const USD{gw["USD"]};
710  {
711  // Simple IOU check cashed with Amount (with failures).
712  Env env{*this, features};
713 
714  env.fund(XRP(1000), gw, alice, bob);
715 
716  // alice writes the check before she gets the funds.
717  uint256 const chkId1{getCheckIndex(alice, env.seq(alice))};
718  env(check::create(alice, bob, USD(10)));
719  env.close();
720 
721  // bob attempts to cash the check. Should fail.
722  env(check::cash(bob, chkId1, USD(10)), ter(tecPATH_PARTIAL));
723  env.close();
724 
725  // alice gets almost enough funds. bob tries and fails again.
726  env(trust(alice, USD(20)));
727  env.close();
728  env(pay(gw, alice, USD(9.5)));
729  env.close();
730  env(check::cash(bob, chkId1, USD(10)), ter(tecPATH_PARTIAL));
731  env.close();
732 
733  // alice gets the last of the necessary funds. bob tries again
734  // and fails because he hasn't got a trust line for USD.
735  env(pay(gw, alice, USD(0.5)));
736  env.close();
737  if (!cashCheckMakesTrustLine)
738  {
739  // If cashing a check automatically creates a trustline then
740  // this returns tesSUCCESS and the check is removed from the
741  // ledger which would mess up later tests.
742  env(check::cash(bob, chkId1, USD(10)), ter(tecNO_LINE));
743  env.close();
744  }
745 
746  // bob sets up the trust line, but not at a high enough limit.
747  env(trust(bob, USD(9.5)));
748  env.close();
749  if (!cashCheckMakesTrustLine)
750  {
751  // If cashing a check is allowed to exceed the trust line
752  // limit then this returns tesSUCCESS and the check is
753  // removed from the ledger which would mess up later tests.
754  env(check::cash(bob, chkId1, USD(10)), ter(tecPATH_PARTIAL));
755  env.close();
756  }
757 
758  // bob sets the trust line limit high enough but asks for more
759  // than the check's SendMax.
760  env(trust(bob, USD(10.5)));
761  env.close();
762  env(check::cash(bob, chkId1, USD(10.5)), ter(tecPATH_PARTIAL));
763  env.close();
764 
765  // bob asks for exactly the check amount and the check clears.
766  env(check::cash(bob, chkId1, USD(10)));
767  env.close();
768  env.require(balance(alice, USD(0)));
769  env.require(balance(bob, USD(10)));
770  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
771  BEAST_EXPECT(checksOnAccount(env, bob).size() == 0);
772  BEAST_EXPECT(ownerCount(env, alice) == 1);
773  BEAST_EXPECT(ownerCount(env, bob) == 1);
774 
775  // bob tries to cash the same check again, which fails.
776  env(check::cash(bob, chkId1, USD(10)), ter(tecNO_ENTRY));
777  env.close();
778 
779  // bob pays alice USD(7) so he can try another case.
780  env(pay(bob, alice, USD(7)));
781  env.close();
782 
783  uint256 const chkId2{getCheckIndex(alice, env.seq(alice))};
784  env(check::create(alice, bob, USD(7)));
785  env.close();
786  BEAST_EXPECT(checksOnAccount(env, alice).size() == 1);
787  BEAST_EXPECT(checksOnAccount(env, bob).size() == 1);
788 
789  // bob cashes the check for less than the face amount. That works,
790  // consumes the check, and bob receives as much as he asked for.
791  env(check::cash(bob, chkId2, USD(5)));
792  env.close();
793  env.require(balance(alice, USD(2)));
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  // alice writes two checks for USD(2), although she only has USD(2).
801  uint256 const chkId3{getCheckIndex(alice, env.seq(alice))};
802  env(check::create(alice, bob, USD(2)));
803  env.close();
804  uint256 const chkId4{getCheckIndex(alice, env.seq(alice))};
805  env(check::create(alice, bob, USD(2)));
806  env.close();
807  BEAST_EXPECT(checksOnAccount(env, alice).size() == 2);
808  BEAST_EXPECT(checksOnAccount(env, bob).size() == 2);
809 
810  // bob cashes the second check for the face amount.
811  env(check::cash(bob, chkId4, USD(2)));
812  env.close();
813  env.require(balance(alice, USD(0)));
814  env.require(balance(bob, USD(10)));
815  BEAST_EXPECT(checksOnAccount(env, alice).size() == 1);
816  BEAST_EXPECT(checksOnAccount(env, bob).size() == 1);
817  BEAST_EXPECT(ownerCount(env, alice) == 2);
818  BEAST_EXPECT(ownerCount(env, bob) == 1);
819 
820  // bob is not allowed to cash the last check for USD(0), he must
821  // use check::cancel instead.
822  env(check::cash(bob, chkId3, USD(0)), ter(temBAD_AMOUNT));
823  env.close();
824  env.require(balance(alice, USD(0)));
825  env.require(balance(bob, USD(10)));
826  BEAST_EXPECT(checksOnAccount(env, alice).size() == 1);
827  BEAST_EXPECT(checksOnAccount(env, bob).size() == 1);
828  BEAST_EXPECT(ownerCount(env, alice) == 2);
829  BEAST_EXPECT(ownerCount(env, bob) == 1);
830 
831  if (cashCheckMakesTrustLine)
832  {
833  // Automatic trust lines are enabled. But one aspect of
834  // automatic trust lines is that they allow the account
835  // cashing a check to exceed their trust line limit. Show
836  // that at work.
837  //
838  // bob's trust line limit is currently USD(10.5). Show that
839  // a payment to bob cannot exceed that trust line, but cashing
840  // a check can.
841 
842  // Payment of 20 USD fails.
843  env(pay(gw, bob, USD(20)), ter(tecPATH_PARTIAL));
844  env.close();
845 
846  uint256 const chkId20{getCheckIndex(gw, env.seq(gw))};
847  env(check::create(gw, bob, USD(20)));
848  env.close();
849 
850  // However cashing a check for 20 USD succeeds.
851  env(check::cash(bob, chkId20, USD(20)));
852  env.close();
853  env.require(balance(bob, USD(30)));
854 
855  // Clean up this most recent experiment so the rest of the
856  // tests work.
857  env(pay(bob, gw, USD(20)));
858  }
859 
860  // ... so bob cancels alice's remaining check.
861  env(check::cancel(bob, chkId3));
862  env.close();
863  env.require(balance(alice, USD(0)));
864  env.require(balance(bob, USD(10)));
865  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
866  BEAST_EXPECT(checksOnAccount(env, bob).size() == 0);
867  BEAST_EXPECT(ownerCount(env, alice) == 1);
868  BEAST_EXPECT(ownerCount(env, bob) == 1);
869  }
870  {
871  // Simple IOU check cashed with DeliverMin (with failures).
872  Env env{*this, features};
873 
874  env.fund(XRP(1000), gw, alice, bob);
875 
876  env(trust(alice, USD(20)));
877  env(trust(bob, USD(20)));
878  env.close();
879  env(pay(gw, alice, USD(8)));
880  env.close();
881 
882  // alice creates several checks ahead of time.
883  uint256 const chkId9{getCheckIndex(alice, env.seq(alice))};
884  env(check::create(alice, bob, USD(9)));
885  env.close();
886  uint256 const chkId8{getCheckIndex(alice, env.seq(alice))};
887  env(check::create(alice, bob, USD(8)));
888  env.close();
889  uint256 const chkId7{getCheckIndex(alice, env.seq(alice))};
890  env(check::create(alice, bob, USD(7)));
891  env.close();
892  uint256 const chkId6{getCheckIndex(alice, env.seq(alice))};
893  env(check::create(alice, bob, USD(6)));
894  env.close();
895 
896  // bob attempts to cash a check for the amount on the check.
897  // Should fail, since alice doesn't have the funds.
898  env(check::cash(bob, chkId9, check::DeliverMin(USD(9))),
899  ter(tecPATH_PARTIAL));
900  env.close();
901 
902  // bob sets a DeliverMin of 7 and gets all that alice has.
903  env(check::cash(bob, chkId9, check::DeliverMin(USD(7))));
904  verifyDeliveredAmount(env, USD(8));
905  env.require(balance(alice, USD(0)));
906  env.require(balance(bob, USD(8)));
907  BEAST_EXPECT(checksOnAccount(env, alice).size() == 3);
908  BEAST_EXPECT(checksOnAccount(env, bob).size() == 3);
909  BEAST_EXPECT(ownerCount(env, alice) == 4);
910  BEAST_EXPECT(ownerCount(env, bob) == 1);
911 
912  // bob pays alice USD(7) so he can use another check.
913  env(pay(bob, alice, USD(7)));
914  env.close();
915 
916  // Using DeliverMin for the SendMax value of the check (and no
917  // transfer fees) should work just like setting Amount.
918  env(check::cash(bob, chkId7, check::DeliverMin(USD(7))));
919  verifyDeliveredAmount(env, USD(7));
920  env.require(balance(alice, USD(0)));
921  env.require(balance(bob, USD(8)));
922  BEAST_EXPECT(checksOnAccount(env, alice).size() == 2);
923  BEAST_EXPECT(checksOnAccount(env, bob).size() == 2);
924  BEAST_EXPECT(ownerCount(env, alice) == 3);
925  BEAST_EXPECT(ownerCount(env, bob) == 1);
926 
927  // bob pays alice USD(8) so he can use the last two checks.
928  env(pay(bob, alice, USD(8)));
929  env.close();
930 
931  // alice has USD(8). If bob uses the check for USD(6) and uses a
932  // DeliverMin of 4, he should get the SendMax value of the check.
933  env(check::cash(bob, chkId6, check::DeliverMin(USD(4))));
934  verifyDeliveredAmount(env, USD(6));
935  env.require(balance(alice, USD(2)));
936  env.require(balance(bob, USD(6)));
937  BEAST_EXPECT(checksOnAccount(env, alice).size() == 1);
938  BEAST_EXPECT(checksOnAccount(env, bob).size() == 1);
939  BEAST_EXPECT(ownerCount(env, alice) == 2);
940  BEAST_EXPECT(ownerCount(env, bob) == 1);
941 
942  // bob cashes the last remaining check setting a DeliverMin.
943  // of exactly alice's remaining USD.
944  env(check::cash(bob, chkId8, check::DeliverMin(USD(2))));
945  verifyDeliveredAmount(env, USD(2));
946  env.require(balance(alice, USD(0)));
947  env.require(balance(bob, USD(8)));
948  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
949  BEAST_EXPECT(checksOnAccount(env, bob).size() == 0);
950  BEAST_EXPECT(ownerCount(env, alice) == 1);
951  BEAST_EXPECT(ownerCount(env, bob) == 1);
952  }
953  {
954  // Examine the effects of the asfRequireAuth flag.
955  Env env(*this, features);
956 
957  env.fund(XRP(1000), gw, alice, bob);
958  env(fset(gw, asfRequireAuth));
959  env.close();
960  env(trust(gw, alice["USD"](100)), txflags(tfSetfAuth));
961  env(trust(alice, USD(20)));
962  env.close();
963  env(pay(gw, alice, USD(8)));
964  env.close();
965 
966  // alice writes a check to bob for USD. bob can't cash it
967  // because he is not authorized to hold gw["USD"].
968  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
969  env(check::create(alice, bob, USD(7)));
970  env.close();
971 
972  env(check::cash(bob, chkId, USD(7)),
973  ter(cashCheckMakesTrustLine ? tecNO_AUTH : tecNO_LINE));
974  env.close();
975 
976  // Now give bob a trustline for USD. bob still can't cash the
977  // check because he is not authorized.
978  env(trust(bob, USD(5)));
979  env.close();
980 
981  env(check::cash(bob, chkId, USD(7)), ter(tecNO_AUTH));
982  env.close();
983 
984  // bob gets authorization to hold gw["USD"].
985  env(trust(gw, bob["USD"](1)), txflags(tfSetfAuth));
986  env.close();
987 
988  // bob tries to cash the check again but fails because his trust
989  // limit is too low.
990  if (!cashCheckMakesTrustLine)
991  {
992  // If cashing a check is allowed to exceed the trust line
993  // limit then this returns tesSUCCESS and the check is
994  // removed from the ledger which would mess up later tests.
995  env(check::cash(bob, chkId, USD(7)), ter(tecPATH_PARTIAL));
996  env.close();
997  }
998 
999  // Two possible outcomes here depending on whether cashing a
1000  // check can build a trust line:
1001  // o If it can't build a trust line, then since bob set his
1002  // limit low, he cashes the check with a DeliverMin and hits
1003  // his trust limit.
1004  // o If it can build a trust line, then the check is allowed to
1005  // exceed the trust limit and bob gets the full transfer.
1006  env(check::cash(bob, chkId, check::DeliverMin(USD(4))));
1007  STAmount const bobGot = cashCheckMakesTrustLine ? USD(7) : USD(5);
1008  verifyDeliveredAmount(env, bobGot);
1009  env.require(balance(alice, USD(8) - bobGot));
1010  env.require(balance(bob, bobGot));
1011 
1012  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
1013  BEAST_EXPECT(checksOnAccount(env, bob).size() == 0);
1014  BEAST_EXPECT(ownerCount(env, alice) == 1);
1015  BEAST_EXPECT(ownerCount(env, bob) == 1);
1016  }
1017 
1018  // Use a regular key and also multisign to cash a check.
1019  // featureMultiSignReserve changes the reserve on a SignerList, so
1020  // check both before and after.
1021  for (auto const& testFeatures :
1022  {features - featureMultiSignReserve,
1023  features | featureMultiSignReserve})
1024  {
1025  Env env{*this, testFeatures};
1026 
1027  env.fund(XRP(1000), gw, alice, bob);
1028 
1029  // alice creates her checks ahead of time.
1030  uint256 const chkId1{getCheckIndex(alice, env.seq(alice))};
1031  env(check::create(alice, bob, USD(1)));
1032  env.close();
1033 
1034  uint256 const chkId2{getCheckIndex(alice, env.seq(alice))};
1035  env(check::create(alice, bob, USD(2)));
1036  env.close();
1037 
1038  env(trust(alice, USD(20)));
1039  env(trust(bob, USD(20)));
1040  env.close();
1041  env(pay(gw, alice, USD(8)));
1042  env.close();
1043 
1044  // Give bob a regular key and signers
1045  Account const bobby{"bobby", KeyType::secp256k1};
1046  env(regkey(bob, bobby));
1047  env.close();
1048 
1049  Account const bogie{"bogie", KeyType::secp256k1};
1050  Account const demon{"demon", KeyType::ed25519};
1051  env(signers(bob, 2, {{bogie, 1}, {demon, 1}}), sig(bobby));
1052  env.close();
1053 
1054  // If featureMultiSignReserve is enabled then bob's signer list
1055  // has an owner count of 1, otherwise it's 4.
1056  int const signersCount = {
1057  testFeatures[featureMultiSignReserve] ? 1 : 4};
1058  BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1059 
1060  // bob uses his regular key to cash a check.
1061  env(check::cash(bob, chkId1, (USD(1))), sig(bobby));
1062  env.close();
1063  env.require(balance(alice, USD(7)));
1064  env.require(balance(bob, USD(1)));
1065  BEAST_EXPECT(checksOnAccount(env, alice).size() == 1);
1066  BEAST_EXPECT(checksOnAccount(env, bob).size() == 1);
1067  BEAST_EXPECT(ownerCount(env, alice) == 2);
1068  BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1069 
1070  // bob uses multisigning to cash a check.
1071  XRPAmount const baseFeeDrops{env.current()->fees().base};
1072  env(check::cash(bob, chkId2, (USD(2))),
1073  msig(bogie, demon),
1074  fee(3 * baseFeeDrops));
1075  env.close();
1076  env.require(balance(alice, USD(5)));
1077  env.require(balance(bob, USD(3)));
1078  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
1079  BEAST_EXPECT(checksOnAccount(env, bob).size() == 0);
1080  BEAST_EXPECT(ownerCount(env, alice) == 1);
1081  BEAST_EXPECT(ownerCount(env, bob) == signersCount + 1);
1082  }
1083  }
1084 
1085  void
1087  {
1088  // Look at behavior when the issuer charges a transfer fee.
1089  testcase("Cash with transfer fee");
1090 
1091  using namespace test::jtx;
1092 
1093  Account const gw{"gateway"};
1094  Account const alice{"alice"};
1095  Account const bob{"bob"};
1096  IOU const USD{gw["USD"]};
1097 
1098  Env env{*this, features};
1099 
1100  env.fund(XRP(1000), gw, alice, bob);
1101 
1102  env(trust(alice, USD(1000)));
1103  env(trust(bob, USD(1000)));
1104  env.close();
1105  env(pay(gw, alice, USD(1000)));
1106  env.close();
1107 
1108  // Set gw's transfer rate and see the consequences when cashing a check.
1109  env(rate(gw, 1.25));
1110  env.close();
1111 
1112  // alice writes a check with a SendMax of USD(125). The most bob
1113  // can get is USD(100) because of the transfer rate.
1114  uint256 const chkId125{getCheckIndex(alice, env.seq(alice))};
1115  env(check::create(alice, bob, USD(125)));
1116  env.close();
1117 
1118  // alice writes another check that won't get cashed until the transfer
1119  // rate changes so we can see the rate applies when the check is
1120  // cashed, not when it is created.
1121  uint256 const chkId120{getCheckIndex(alice, env.seq(alice))};
1122  env(check::create(alice, bob, USD(120)));
1123  env.close();
1124 
1125  // bob attempts to cash the check for face value. Should fail.
1126  env(check::cash(bob, chkId125, USD(125)), ter(tecPATH_PARTIAL));
1127  env.close();
1128  env(check::cash(bob, chkId125, check::DeliverMin(USD(101))),
1129  ter(tecPATH_PARTIAL));
1130  env.close();
1131 
1132  // bob decides that he'll accept anything USD(75) or up.
1133  // He gets USD(100).
1134  env(check::cash(bob, chkId125, check::DeliverMin(USD(75))));
1135  verifyDeliveredAmount(env, USD(100));
1136  env.require(balance(alice, USD(1000 - 125)));
1137  env.require(balance(bob, USD(0 + 100)));
1138  BEAST_EXPECT(checksOnAccount(env, alice).size() == 1);
1139  BEAST_EXPECT(checksOnAccount(env, bob).size() == 1);
1140 
1141  // Adjust gw's rate...
1142  env(rate(gw, 1.2));
1143  env.close();
1144 
1145  // bob cashes the second check for less than the face value. The new
1146  // rate applies to the actual value transferred.
1147  env(check::cash(bob, chkId120, USD(50)));
1148  env.close();
1149  env.require(balance(alice, USD(1000 - 125 - 60)));
1150  env.require(balance(bob, USD(0 + 100 + 50)));
1151  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
1152  BEAST_EXPECT(checksOnAccount(env, bob).size() == 0);
1153  }
1154 
1155  void
1157  {
1158  // Look at the eight possible cases for Quality In/Out.
1159  testcase("Cash quality");
1160 
1161  using namespace test::jtx;
1162 
1163  Account const gw{"gateway"};
1164  Account const alice{"alice"};
1165  Account const bob{"bob"};
1166  IOU const USD{gw["USD"]};
1167 
1168  Env env{*this, features};
1169 
1170  env.fund(XRP(1000), gw, alice, bob);
1171 
1172  env(trust(alice, USD(1000)));
1173  env(trust(bob, USD(1000)));
1174  env.close();
1175  env(pay(gw, alice, USD(1000)));
1176  env.close();
1177 
1178  //
1179  // Quality effects on transfers between two non-issuers.
1180  //
1181 
1182  // Provide lambdas that return a qualityInPercent and qualityOutPercent.
1183  auto qIn = [](double percent) { return qualityInPercent(percent); };
1184  auto qOut = [](double percent) { return qualityOutPercent(percent); };
1185 
1186  // There are two test lambdas: one for a Payment and one for a Check.
1187  // This shows whether a Payment and a Check behave the same.
1188  auto testNonIssuerQPay = [&env, &alice, &bob, &USD](
1189  Account const& truster,
1190  IOU const& iou,
1191  auto const& inOrOut,
1192  double pct,
1193  double amount) {
1194  // Capture bob's and alice's balances so we can test at the end.
1195  STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1196  STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1197 
1198  // Set the modified quality.
1199  env(trust(truster, iou(1000)), inOrOut(pct));
1200  env.close();
1201 
1202  env(pay(alice, bob, USD(amount)), sendmax(USD(10)));
1203  env.close();
1204  env.require(balance(alice, aliceStart - USD(10)));
1205  env.require(balance(bob, bobStart + USD(10)));
1206 
1207  // Return the quality to the unmodified state so it doesn't
1208  // interfere with upcoming tests.
1209  env(trust(truster, iou(1000)), inOrOut(0));
1210  env.close();
1211  };
1212 
1213  auto testNonIssuerQCheck = [&env, &alice, &bob, &USD](
1214  Account const& truster,
1215  IOU const& iou,
1216  auto const& inOrOut,
1217  double pct,
1218  double amount) {
1219  // Capture bob's and alice's balances so we can test at the end.
1220  STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1221  STAmount const bobStart{env.balance(bob, USD.issue()).value()};
1222 
1223  // Set the modified quality.
1224  env(trust(truster, iou(1000)), inOrOut(pct));
1225  env.close();
1226 
1227  uint256 const chkId = getCheckIndex(alice, env.seq(alice));
1228  env(check::create(alice, bob, USD(10)));
1229  env.close();
1230 
1231  env(check::cash(bob, chkId, USD(amount)));
1232  env.close();
1233  env.require(balance(alice, aliceStart - USD(10)));
1234  env.require(balance(bob, bobStart + USD(10)));
1235 
1236  // Return the quality to the unmodified state so it doesn't
1237  // interfere with upcoming tests.
1238  env(trust(truster, iou(1000)), inOrOut(0));
1239  env.close();
1240  };
1241 
1242  // pct amount
1243  testNonIssuerQPay(alice, gw["USD"], qIn, 50, 10);
1244  testNonIssuerQCheck(alice, gw["USD"], qIn, 50, 10);
1245 
1246  // This is the only case where the Quality affects the outcome.
1247  testNonIssuerQPay(bob, gw["USD"], qIn, 50, 5);
1248  testNonIssuerQCheck(bob, gw["USD"], qIn, 50, 5);
1249 
1250  testNonIssuerQPay(gw, alice["USD"], qIn, 50, 10);
1251  testNonIssuerQCheck(gw, alice["USD"], qIn, 50, 10);
1252 
1253  testNonIssuerQPay(gw, bob["USD"], qIn, 50, 10);
1254  testNonIssuerQCheck(gw, bob["USD"], qIn, 50, 10);
1255 
1256  testNonIssuerQPay(alice, gw["USD"], qOut, 200, 10);
1257  testNonIssuerQCheck(alice, gw["USD"], qOut, 200, 10);
1258 
1259  testNonIssuerQPay(bob, gw["USD"], qOut, 200, 10);
1260  testNonIssuerQCheck(bob, gw["USD"], qOut, 200, 10);
1261 
1262  testNonIssuerQPay(gw, alice["USD"], qOut, 200, 10);
1263  testNonIssuerQCheck(gw, alice["USD"], qOut, 200, 10);
1264 
1265  testNonIssuerQPay(gw, bob["USD"], qOut, 200, 10);
1266  testNonIssuerQCheck(gw, bob["USD"], qOut, 200, 10);
1267 
1268  //
1269  // Quality effects on transfers between an issuer and a non-issuer.
1270  //
1271 
1272  // There are two test lambdas for the same reason as before.
1273  auto testIssuerQPay = [&env, &gw, &alice, &USD](
1274  Account const& truster,
1275  IOU const& iou,
1276  auto const& inOrOut,
1277  double pct,
1278  double amt1,
1279  double max1,
1280  double amt2,
1281  double max2) {
1282  // Capture alice's balance so we can test at the end. It doesn't
1283  // make any sense to look at the balance of a gateway.
1284  STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1285 
1286  // Set the modified quality.
1287  env(trust(truster, iou(1000)), inOrOut(pct));
1288  env.close();
1289 
1290  // alice pays gw.
1291  env(pay(alice, gw, USD(amt1)), sendmax(USD(max1)));
1292  env.close();
1293  env.require(balance(alice, aliceStart - USD(10)));
1294 
1295  // gw pays alice.
1296  env(pay(gw, alice, USD(amt2)), sendmax(USD(max2)));
1297  env.close();
1298  env.require(balance(alice, aliceStart));
1299 
1300  // Return the quality to the unmodified state so it doesn't
1301  // interfere with upcoming tests.
1302  env(trust(truster, iou(1000)), inOrOut(0));
1303  env.close();
1304  };
1305 
1306  auto testIssuerQCheck = [&env, &gw, &alice, &USD](
1307  Account const& truster,
1308  IOU const& iou,
1309  auto const& inOrOut,
1310  double pct,
1311  double amt1,
1312  double max1,
1313  double amt2,
1314  double max2) {
1315  // Capture alice's balance so we can test at the end. It doesn't
1316  // make any sense to look at the balance of the issuer.
1317  STAmount const aliceStart{env.balance(alice, USD.issue()).value()};
1318 
1319  // Set the modified quality.
1320  env(trust(truster, iou(1000)), inOrOut(pct));
1321  env.close();
1322 
1323  // alice writes check to gw. gw cashes.
1324  uint256 const chkAliceId{getCheckIndex(alice, env.seq(alice))};
1325  env(check::create(alice, gw, USD(max1)));
1326  env.close();
1327 
1328  env(check::cash(gw, chkAliceId, USD(amt1)));
1329  env.close();
1330  env.require(balance(alice, aliceStart - USD(10)));
1331 
1332  // gw writes check to alice. alice cashes.
1333  uint256 const chkGwId{getCheckIndex(gw, env.seq(gw))};
1334  env(check::create(gw, alice, USD(max2)));
1335  env.close();
1336 
1337  env(check::cash(alice, chkGwId, USD(amt2)));
1338  env.close();
1339  env.require(balance(alice, aliceStart));
1340 
1341  // Return the quality to the unmodified state so it doesn't
1342  // interfere with upcoming tests.
1343  env(trust(truster, iou(1000)), inOrOut(0));
1344  env.close();
1345  };
1346 
1347  // The first case is the only one where the quality affects the outcome.
1348  // pct amt1 max1 amt2 max2
1349  testIssuerQPay(alice, gw["USD"], qIn, 50, 10, 10, 5, 10);
1350  testIssuerQCheck(alice, gw["USD"], qIn, 50, 10, 10, 5, 10);
1351 
1352  testIssuerQPay(gw, alice["USD"], qIn, 50, 10, 10, 10, 10);
1353  testIssuerQCheck(gw, alice["USD"], qIn, 50, 10, 10, 10, 10);
1354 
1355  testIssuerQPay(alice, gw["USD"], qOut, 200, 10, 10, 10, 10);
1356  testIssuerQCheck(alice, gw["USD"], qOut, 200, 10, 10, 10, 10);
1357 
1358  testIssuerQPay(gw, alice["USD"], qOut, 200, 10, 10, 10, 10);
1359  testIssuerQCheck(gw, alice["USD"], qOut, 200, 10, 10, 10, 10);
1360  }
1361 
1362  void
1364  {
1365  // Explore many of the ways to fail at cashing a check.
1366  testcase("Cash invalid");
1367 
1368  using namespace test::jtx;
1369 
1370  Account const gw{"gateway"};
1371  Account const alice{"alice"};
1372  Account const bob{"bob"};
1373  Account const zoe{"zoe"};
1374  IOU const USD{gw["USD"]};
1375 
1376  Env env(*this, features);
1377 
1378  env.fund(XRP(1000), gw, alice, bob, zoe);
1379 
1380  // Now set up alice's trustline.
1381  env(trust(alice, USD(20)));
1382  env.close();
1383  env(pay(gw, alice, USD(20)));
1384  env.close();
1385 
1386  // Before bob gets a trustline, have him try to cash a check.
1387  // Should fail.
1388  {
1389  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
1390  env(check::create(alice, bob, USD(20)));
1391  env.close();
1392 
1393  if (!features[featureCheckCashMakesTrustLine])
1394  {
1395  // If cashing a check automatically creates a trustline then
1396  // this returns tesSUCCESS and the check is removed from the
1397  // ledger which would mess up later tests.
1398  env(check::cash(bob, chkId, USD(20)), ter(tecNO_LINE));
1399  env.close();
1400  }
1401  }
1402 
1403  // Now set up bob's trustline.
1404  env(trust(bob, USD(20)));
1405  env.close();
1406 
1407  // bob tries to cash a non-existent check from alice.
1408  {
1409  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
1410  env(check::cash(bob, chkId, USD(20)), ter(tecNO_ENTRY));
1411  env.close();
1412  }
1413 
1414  // alice creates her checks ahead of time.
1415  uint256 const chkIdU{getCheckIndex(alice, env.seq(alice))};
1416  env(check::create(alice, bob, USD(20)));
1417  env.close();
1418 
1419  uint256 const chkIdX{getCheckIndex(alice, env.seq(alice))};
1420  env(check::create(alice, bob, XRP(10)));
1421  env.close();
1422 
1423  using namespace std::chrono_literals;
1424  uint256 const chkIdExp{getCheckIndex(alice, env.seq(alice))};
1425  env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1426  env.close();
1427 
1428  uint256 const chkIdFroz1{getCheckIndex(alice, env.seq(alice))};
1429  env(check::create(alice, bob, USD(1)));
1430  env.close();
1431 
1432  uint256 const chkIdFroz2{getCheckIndex(alice, env.seq(alice))};
1433  env(check::create(alice, bob, USD(2)));
1434  env.close();
1435 
1436  uint256 const chkIdFroz3{getCheckIndex(alice, env.seq(alice))};
1437  env(check::create(alice, bob, USD(3)));
1438  env.close();
1439 
1440  uint256 const chkIdFroz4{getCheckIndex(alice, env.seq(alice))};
1441  env(check::create(alice, bob, USD(4)));
1442  env.close();
1443 
1444  uint256 const chkIdNoDest1{getCheckIndex(alice, env.seq(alice))};
1445  env(check::create(alice, bob, USD(1)));
1446  env.close();
1447 
1448  uint256 const chkIdHasDest2{getCheckIndex(alice, env.seq(alice))};
1449  env(check::create(alice, bob, USD(2)), dest_tag(7));
1450  env.close();
1451 
1452  // Same set of failing cases for both IOU and XRP check cashing.
1453  auto failingCases = [&env, &gw, &alice, &bob](
1454  uint256 const& chkId, STAmount const& amount) {
1455  // Bad fee.
1456  env(check::cash(bob, chkId, amount),
1457  fee(drops(-10)),
1458  ter(temBAD_FEE));
1459  env.close();
1460 
1461  // Bad flags.
1462  env(check::cash(bob, chkId, amount),
1463  txflags(tfImmediateOrCancel),
1464  ter(temINVALID_FLAG));
1465  env.close();
1466 
1467  // Missing both Amount and DeliverMin.
1468  {
1469  Json::Value tx{check::cash(bob, chkId, amount)};
1471  env(tx, ter(temMALFORMED));
1472  env.close();
1473  }
1474  // Both Amount and DeliverMin present.
1475  {
1476  Json::Value tx{check::cash(bob, chkId, amount)};
1477  tx[sfDeliverMin.jsonName] = amount.getJson(JsonOptions::none);
1478  env(tx, ter(temMALFORMED));
1479  env.close();
1480  }
1481 
1482  // Negative or zero amount.
1483  {
1484  STAmount neg{amount};
1485  neg.negate();
1486  env(check::cash(bob, chkId, neg), ter(temBAD_AMOUNT));
1487  env.close();
1488  env(check::cash(bob, chkId, amount.zeroed()),
1489  ter(temBAD_AMOUNT));
1490  env.close();
1491  }
1492 
1493  // Bad currency.
1494  if (!amount.native())
1495  {
1496  Issue const badIssue{badCurrency(), amount.getIssuer()};
1497  STAmount badAmount{amount};
1498  badAmount.setIssue(Issue{badCurrency(), amount.getIssuer()});
1499  env(check::cash(bob, chkId, badAmount), ter(temBAD_CURRENCY));
1500  env.close();
1501  }
1502 
1503  // Not destination cashing check.
1504  env(check::cash(alice, chkId, amount), ter(tecNO_PERMISSION));
1505  env.close();
1506  env(check::cash(gw, chkId, amount), ter(tecNO_PERMISSION));
1507  env.close();
1508 
1509  // Currency mismatch.
1510  {
1511  IOU const wrongCurrency{gw["EUR"]};
1512  STAmount badAmount{amount};
1513  badAmount.setIssue(wrongCurrency.issue());
1514  env(check::cash(bob, chkId, badAmount), ter(temMALFORMED));
1515  env.close();
1516  }
1517 
1518  // Issuer mismatch.
1519  {
1520  IOU const wrongIssuer{alice["USD"]};
1521  STAmount badAmount{amount};
1522  badAmount.setIssue(wrongIssuer.issue());
1523  env(check::cash(bob, chkId, badAmount), ter(temMALFORMED));
1524  env.close();
1525  }
1526 
1527  // Amount bigger than SendMax.
1528  env(check::cash(bob, chkId, amount + amount), ter(tecPATH_PARTIAL));
1529  env.close();
1530 
1531  // DeliverMin bigger than SendMax.
1532  env(check::cash(bob, chkId, check::DeliverMin(amount + amount)),
1533  ter(tecPATH_PARTIAL));
1534  env.close();
1535  };
1536 
1537  failingCases(chkIdX, XRP(10));
1538  failingCases(chkIdU, USD(20));
1539 
1540  // Verify that those two checks really were cashable.
1541  env(check::cash(bob, chkIdU, USD(20)));
1542  env.close();
1543  env(check::cash(bob, chkIdX, check::DeliverMin(XRP(10))));
1544  verifyDeliveredAmount(env, XRP(10));
1545 
1546  // Try to cash an expired check.
1547  env(check::cash(bob, chkIdExp, XRP(10)), ter(tecEXPIRED));
1548  env.close();
1549 
1550  // Cancel the expired check. Anyone can cancel an expired check.
1551  env(check::cancel(zoe, chkIdExp));
1552  env.close();
1553 
1554  // Can we cash a check with frozen currency?
1555  {
1556  env(pay(bob, alice, USD(20)));
1557  env.close();
1558  env.require(balance(alice, USD(20)));
1559  env.require(balance(bob, USD(0)));
1560 
1561  // Global freeze
1562  env(fset(gw, asfGlobalFreeze));
1563  env.close();
1564 
1565  env(check::cash(bob, chkIdFroz1, USD(1)), ter(tecPATH_PARTIAL));
1566  env.close();
1567  env(check::cash(bob, chkIdFroz1, check::DeliverMin(USD(0.5))),
1568  ter(tecPATH_PARTIAL));
1569  env.close();
1570 
1571  env(fclear(gw, asfGlobalFreeze));
1572  env.close();
1573 
1574  // No longer frozen. Success.
1575  env(check::cash(bob, chkIdFroz1, USD(1)));
1576  env.close();
1577  env.require(balance(alice, USD(19)));
1578  env.require(balance(bob, USD(1)));
1579 
1580  // Freeze individual trustlines.
1581  env(trust(gw, alice["USD"](0), tfSetFreeze));
1582  env.close();
1583  env(check::cash(bob, chkIdFroz2, USD(2)), ter(tecPATH_PARTIAL));
1584  env.close();
1585  env(check::cash(bob, chkIdFroz2, check::DeliverMin(USD(1))),
1586  ter(tecPATH_PARTIAL));
1587  env.close();
1588 
1589  // Clear that freeze. Now check cashing works.
1590  env(trust(gw, alice["USD"](0), tfClearFreeze));
1591  env.close();
1592  env(check::cash(bob, chkIdFroz2, USD(2)));
1593  env.close();
1594  env.require(balance(alice, USD(17)));
1595  env.require(balance(bob, USD(3)));
1596 
1597  // Freeze bob's trustline. bob can't cash the check.
1598  env(trust(gw, bob["USD"](0), tfSetFreeze));
1599  env.close();
1600  env(check::cash(bob, chkIdFroz3, USD(3)), ter(tecFROZEN));
1601  env.close();
1602  env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))),
1603  ter(tecFROZEN));
1604  env.close();
1605 
1606  // Clear that freeze. Now check cashing works again.
1607  env(trust(gw, bob["USD"](0), tfClearFreeze));
1608  env.close();
1609  env(check::cash(bob, chkIdFroz3, check::DeliverMin(USD(1))));
1610  verifyDeliveredAmount(env, USD(3));
1611  env.require(balance(alice, USD(14)));
1612  env.require(balance(bob, USD(6)));
1613 
1614  // Set bob's freeze bit in the other direction. Check
1615  // cashing fails.
1616  env(trust(bob, USD(20), tfSetFreeze));
1617  env.close();
1618  env(check::cash(bob, chkIdFroz4, USD(4)), ter(terNO_LINE));
1619  env.close();
1620  env(check::cash(bob, chkIdFroz4, check::DeliverMin(USD(1))),
1621  ter(terNO_LINE));
1622  env.close();
1623 
1624  // Clear bob's freeze bit and the check should be cashable.
1625  env(trust(bob, USD(20), tfClearFreeze));
1626  env.close();
1627  env(check::cash(bob, chkIdFroz4, USD(4)));
1628  env.close();
1629  env.require(balance(alice, USD(10)));
1630  env.require(balance(bob, USD(10)));
1631  }
1632  {
1633  // Set the RequireDest flag on bob's account (after the check
1634  // was created) then cash a check without a destination tag.
1635  env(fset(bob, asfRequireDest));
1636  env.close();
1637  env(check::cash(bob, chkIdNoDest1, USD(1)), ter(tecDST_TAG_NEEDED));
1638  env.close();
1639  env(check::cash(bob, chkIdNoDest1, check::DeliverMin(USD(0.5))),
1640  ter(tecDST_TAG_NEEDED));
1641  env.close();
1642 
1643  // bob can cash a check with a destination tag.
1644  env(check::cash(bob, chkIdHasDest2, USD(2)));
1645  env.close();
1646  env.require(balance(alice, USD(8)));
1647  env.require(balance(bob, USD(12)));
1648 
1649  // Clear the RequireDest flag on bob's account so he can
1650  // cash the check with no DestinationTag.
1651  env(fclear(bob, asfRequireDest));
1652  env.close();
1653  env(check::cash(bob, chkIdNoDest1, USD(1)));
1654  env.close();
1655  env.require(balance(alice, USD(7)));
1656  env.require(balance(bob, USD(13)));
1657  }
1658  }
1659 
1660  void
1662  {
1663  // Explore many of the ways to cancel a check.
1664  testcase("Cancel valid");
1665 
1666  using namespace test::jtx;
1667 
1668  Account const gw{"gateway"};
1669  Account const alice{"alice"};
1670  Account const bob{"bob"};
1671  Account const zoe{"zoe"};
1672  IOU const USD{gw["USD"]};
1673 
1674  // featureMultiSignReserve changes the reserve on a SignerList, so
1675  // check both before and after.
1676  for (auto const& testFeatures :
1677  {features - featureMultiSignReserve,
1678  features | featureMultiSignReserve})
1679  {
1680  Env env{*this, testFeatures};
1681 
1682  env.fund(XRP(1000), gw, alice, bob, zoe);
1683 
1684  // alice creates her checks ahead of time.
1685  // Three ordinary checks with no expiration.
1686  uint256 const chkId1{getCheckIndex(alice, env.seq(alice))};
1687  env(check::create(alice, bob, USD(10)));
1688  env.close();
1689 
1690  uint256 const chkId2{getCheckIndex(alice, env.seq(alice))};
1691  env(check::create(alice, bob, XRP(10)));
1692  env.close();
1693 
1694  uint256 const chkId3{getCheckIndex(alice, env.seq(alice))};
1695  env(check::create(alice, bob, USD(10)));
1696  env.close();
1697 
1698  // Three checks that expire in 10 minutes.
1699  using namespace std::chrono_literals;
1700  uint256 const chkIdNotExp1{getCheckIndex(alice, env.seq(alice))};
1701  env(check::create(alice, bob, XRP(10)),
1702  expiration(env.now() + 600s));
1703  env.close();
1704 
1705  uint256 const chkIdNotExp2{getCheckIndex(alice, env.seq(alice))};
1706  env(check::create(alice, bob, USD(10)),
1707  expiration(env.now() + 600s));
1708  env.close();
1709 
1710  uint256 const chkIdNotExp3{getCheckIndex(alice, env.seq(alice))};
1711  env(check::create(alice, bob, XRP(10)),
1712  expiration(env.now() + 600s));
1713  env.close();
1714 
1715  // Three checks that expire in one second.
1716  uint256 const chkIdExp1{getCheckIndex(alice, env.seq(alice))};
1717  env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1718  env.close();
1719 
1720  uint256 const chkIdExp2{getCheckIndex(alice, env.seq(alice))};
1721  env(check::create(alice, bob, XRP(10)), expiration(env.now() + 1s));
1722  env.close();
1723 
1724  uint256 const chkIdExp3{getCheckIndex(alice, env.seq(alice))};
1725  env(check::create(alice, bob, USD(10)), expiration(env.now() + 1s));
1726  env.close();
1727 
1728  // Two checks to cancel using a regular key and using multisigning.
1729  uint256 const chkIdReg{getCheckIndex(alice, env.seq(alice))};
1730  env(check::create(alice, bob, USD(10)));
1731  env.close();
1732 
1733  uint256 const chkIdMSig{getCheckIndex(alice, env.seq(alice))};
1734  env(check::create(alice, bob, XRP(10)));
1735  env.close();
1736  BEAST_EXPECT(checksOnAccount(env, alice).size() == 11);
1737  BEAST_EXPECT(ownerCount(env, alice) == 11);
1738 
1739  // Creator, destination, and an outsider cancel the checks.
1740  env(check::cancel(alice, chkId1));
1741  env.close();
1742  BEAST_EXPECT(checksOnAccount(env, alice).size() == 10);
1743  BEAST_EXPECT(ownerCount(env, alice) == 10);
1744 
1745  env(check::cancel(bob, chkId2));
1746  env.close();
1747  BEAST_EXPECT(checksOnAccount(env, alice).size() == 9);
1748  BEAST_EXPECT(ownerCount(env, alice) == 9);
1749 
1750  env(check::cancel(zoe, chkId3), ter(tecNO_PERMISSION));
1751  env.close();
1752  BEAST_EXPECT(checksOnAccount(env, alice).size() == 9);
1753  BEAST_EXPECT(ownerCount(env, alice) == 9);
1754 
1755  // Creator, destination, and an outsider cancel unexpired checks.
1756  env(check::cancel(alice, chkIdNotExp1));
1757  env.close();
1758  BEAST_EXPECT(checksOnAccount(env, alice).size() == 8);
1759  BEAST_EXPECT(ownerCount(env, alice) == 8);
1760 
1761  env(check::cancel(bob, chkIdNotExp2));
1762  env.close();
1763  BEAST_EXPECT(checksOnAccount(env, alice).size() == 7);
1764  BEAST_EXPECT(ownerCount(env, alice) == 7);
1765 
1766  env(check::cancel(zoe, chkIdNotExp3), ter(tecNO_PERMISSION));
1767  env.close();
1768  BEAST_EXPECT(checksOnAccount(env, alice).size() == 7);
1769  BEAST_EXPECT(ownerCount(env, alice) == 7);
1770 
1771  // Creator, destination, and an outsider cancel expired checks.
1772  env(check::cancel(alice, chkIdExp1));
1773  env.close();
1774  BEAST_EXPECT(checksOnAccount(env, alice).size() == 6);
1775  BEAST_EXPECT(ownerCount(env, alice) == 6);
1776 
1777  env(check::cancel(bob, chkIdExp2));
1778  env.close();
1779  BEAST_EXPECT(checksOnAccount(env, alice).size() == 5);
1780  BEAST_EXPECT(ownerCount(env, alice) == 5);
1781 
1782  env(check::cancel(zoe, chkIdExp3));
1783  env.close();
1784  BEAST_EXPECT(checksOnAccount(env, alice).size() == 4);
1785  BEAST_EXPECT(ownerCount(env, alice) == 4);
1786 
1787  // Use a regular key and also multisign to cancel checks.
1788  Account const alie{"alie", KeyType::ed25519};
1789  env(regkey(alice, alie));
1790  env.close();
1791 
1792  Account const bogie{"bogie", KeyType::secp256k1};
1793  Account const demon{"demon", KeyType::ed25519};
1794  env(signers(alice, 2, {{bogie, 1}, {demon, 1}}), sig(alie));
1795  env.close();
1796 
1797  // If featureMultiSignReserve is enabled then alices's signer list
1798  // has an owner count of 1, otherwise it's 4.
1799  int const signersCount{
1800  testFeatures[featureMultiSignReserve] ? 1 : 4};
1801 
1802  // alice uses her regular key to cancel a check.
1803  env(check::cancel(alice, chkIdReg), sig(alie));
1804  env.close();
1805  BEAST_EXPECT(checksOnAccount(env, alice).size() == 3);
1806  BEAST_EXPECT(ownerCount(env, alice) == signersCount + 3);
1807 
1808  // alice uses multisigning to cancel a check.
1809  XRPAmount const baseFeeDrops{env.current()->fees().base};
1810  env(check::cancel(alice, chkIdMSig),
1811  msig(bogie, demon),
1812  fee(3 * baseFeeDrops));
1813  env.close();
1814  BEAST_EXPECT(checksOnAccount(env, alice).size() == 2);
1815  BEAST_EXPECT(ownerCount(env, alice) == signersCount + 2);
1816 
1817  // Creator and destination cancel the remaining unexpired checks.
1818  env(check::cancel(alice, chkId3), sig(alice));
1819  env.close();
1820  BEAST_EXPECT(checksOnAccount(env, alice).size() == 1);
1821  BEAST_EXPECT(ownerCount(env, alice) == signersCount + 1);
1822 
1823  env(check::cancel(bob, chkIdNotExp3));
1824  env.close();
1825  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
1826  BEAST_EXPECT(ownerCount(env, alice) == signersCount + 0);
1827  }
1828  }
1829 
1830  void
1832  {
1833  // Explore many of the ways to fail at canceling a check.
1834  testcase("Cancel invalid");
1835 
1836  using namespace test::jtx;
1837 
1838  Account const alice{"alice"};
1839  Account const bob{"bob"};
1840 
1841  Env env{*this, features};
1842 
1843  env.fund(XRP(1000), alice, bob);
1844 
1845  // Bad fee.
1846  env(check::cancel(bob, getCheckIndex(alice, env.seq(alice))),
1847  fee(drops(-10)),
1848  ter(temBAD_FEE));
1849  env.close();
1850 
1851  // Bad flags.
1852  env(check::cancel(bob, getCheckIndex(alice, env.seq(alice))),
1853  txflags(tfImmediateOrCancel),
1854  ter(temINVALID_FLAG));
1855  env.close();
1856 
1857  // Non-existent check.
1858  env(check::cancel(bob, getCheckIndex(alice, env.seq(alice))),
1859  ter(tecNO_ENTRY));
1860  env.close();
1861  }
1862 
1863  void
1865  {
1866  testcase("Fix1623 enable");
1867 
1868  using namespace test::jtx;
1869 
1870  auto testEnable = [this](
1871  FeatureBitset const& features, bool hasFields) {
1872  // Unless fix1623 is enabled a "tx" RPC command should return
1873  // neither "DeliveredAmount" nor "delivered_amount" on a CheckCash
1874  // transaction.
1875  Account const alice{"alice"};
1876  Account const bob{"bob"};
1877 
1878  Env env{*this, features};
1879 
1880  env.fund(XRP(1000), alice, bob);
1881  env.close();
1882 
1883  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
1884  env(check::create(alice, bob, XRP(200)));
1885  env.close();
1886 
1887  env(check::cash(bob, chkId, check::DeliverMin(XRP(100))));
1888 
1889  // Get the hash for the most recent transaction.
1890  std::string const txHash{
1891  env.tx()->getJson(JsonOptions::none)[jss::hash].asString()};
1892 
1893  // DeliveredAmount and delivered_amount are either present or
1894  // not present in the metadata returned by "tx" based on fix1623.
1895  env.close();
1896  Json::Value const meta =
1897  env.rpc("tx", txHash)[jss::result][jss::meta];
1898 
1899  BEAST_EXPECT(
1900  meta.isMember(sfDeliveredAmount.jsonName) == hasFields);
1901  BEAST_EXPECT(meta.isMember(jss::delivered_amount) == hasFields);
1902  };
1903 
1904  // Run both the disabled and enabled cases.
1905  testEnable(features - fix1623, false);
1906  testEnable(features, true);
1907  }
1908 
1909  void
1911  {
1912  testcase("With Tickets");
1913 
1914  using namespace test::jtx;
1915 
1916  Account const gw{"gw"};
1917  Account const alice{"alice"};
1918  Account const bob{"bob"};
1919  IOU const USD{gw["USD"]};
1920 
1921  Env env{*this, features};
1922  env.fund(XRP(1000), gw, alice, bob);
1923  env.close();
1924 
1925  // alice and bob grab enough tickets for all of the following
1926  // transactions. Note that once the tickets are acquired alice's
1927  // and bob's account sequence numbers should not advance.
1928  std::uint32_t aliceTicketSeq{env.seq(alice) + 1};
1929  env(ticket::create(alice, 10));
1930  std::uint32_t const aliceSeq{env.seq(alice)};
1931 
1932  std::uint32_t bobTicketSeq{env.seq(bob) + 1};
1933  env(ticket::create(bob, 10));
1934  std::uint32_t const bobSeq{env.seq(bob)};
1935 
1936  env.close();
1937  env.require(owners(alice, 10));
1938  env.require(owners(bob, 10));
1939 
1940  // alice gets enough USD to write a few checks.
1941  env(trust(alice, USD(1000)), ticket::use(aliceTicketSeq++));
1942  env(trust(bob, USD(1000)), ticket::use(bobTicketSeq++));
1943  env.close();
1944  env.require(owners(alice, 10));
1945  env.require(owners(bob, 10));
1946 
1947  env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1948  BEAST_EXPECT(env.seq(alice) == aliceSeq);
1949 
1950  env.require(tickets(bob, env.seq(bob) - bobTicketSeq));
1951  BEAST_EXPECT(env.seq(bob) == bobSeq);
1952 
1953  env(pay(gw, alice, USD(900)));
1954  env.close();
1955 
1956  // alice creates four checks; two XRP, two IOU. Bob will cash
1957  // one of each and cancel one of each.
1958  uint256 const chkIdXrp1{getCheckIndex(alice, aliceTicketSeq)};
1959  env(check::create(alice, bob, XRP(200)), ticket::use(aliceTicketSeq++));
1960 
1961  uint256 const chkIdXrp2{getCheckIndex(alice, aliceTicketSeq)};
1962  env(check::create(alice, bob, XRP(300)), ticket::use(aliceTicketSeq++));
1963 
1964  uint256 const chkIdUsd1{getCheckIndex(alice, aliceTicketSeq)};
1965  env(check::create(alice, bob, USD(200)), ticket::use(aliceTicketSeq++));
1966 
1967  uint256 const chkIdUsd2{getCheckIndex(alice, aliceTicketSeq)};
1968  env(check::create(alice, bob, USD(300)), ticket::use(aliceTicketSeq++));
1969 
1970  env.close();
1971  // Alice used four tickets but created four checks.
1972  env.require(owners(alice, 10));
1973  env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1974  BEAST_EXPECT(checksOnAccount(env, alice).size() == 4);
1975  BEAST_EXPECT(env.seq(alice) == aliceSeq);
1976 
1977  env.require(owners(bob, 10));
1978  BEAST_EXPECT(env.seq(bob) == bobSeq);
1979 
1980  // Bob cancels two of alice's checks.
1981  env(check::cancel(bob, chkIdXrp1), ticket::use(bobTicketSeq++));
1982  env(check::cancel(bob, chkIdUsd2), ticket::use(bobTicketSeq++));
1983  env.close();
1984 
1985  env.require(owners(alice, 8));
1986  env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
1987  BEAST_EXPECT(checksOnAccount(env, alice).size() == 2);
1988  BEAST_EXPECT(env.seq(alice) == aliceSeq);
1989 
1990  env.require(owners(bob, 8));
1991  BEAST_EXPECT(env.seq(bob) == bobSeq);
1992 
1993  // Bob cashes alice's two remaining checks.
1994  env(check::cash(bob, chkIdXrp2, XRP(300)), ticket::use(bobTicketSeq++));
1995  env(check::cash(bob, chkIdUsd1, USD(200)), ticket::use(bobTicketSeq++));
1996  env.close();
1997 
1998  env.require(owners(alice, 6));
1999  env.require(tickets(alice, env.seq(alice) - aliceTicketSeq));
2000  BEAST_EXPECT(checksOnAccount(env, alice).size() == 0);
2001  BEAST_EXPECT(env.seq(alice) == aliceSeq);
2002  env.require(balance(alice, USD(700)));
2003  env.require(balance(alice, drops(699'999'940)));
2004 
2005  env.require(owners(bob, 6));
2006  BEAST_EXPECT(env.seq(bob) == bobSeq);
2007  env.require(balance(bob, USD(200)));
2008  env.require(balance(bob, drops(1'299'999'940)));
2009  }
2010 
2011  void
2012  testTrustLineCreation(FeatureBitset features)
2013  {
2014  // Explore automatic trust line creation when a check is cashed.
2015  //
2016  // This capability is enabled by the featureCheckCashMakesTrustLine
2017  // amendment. So this test executes only when that amendment is
2018  // active.
2019  assert(features[featureCheckCashMakesTrustLine]);
2020 
2021  testcase("Trust Line Creation");
2022 
2023  using namespace test::jtx;
2024 
2025  Env env{*this, features};
2026 
2027  // An account that independently tracks its owner count.
2028  struct AccountOwns
2029  {
2030  beast::unit_test::suite& suite;
2031  Env const& env;
2032  Account const acct;
2033  std::size_t owners;
2034 
2035  void
2036  verifyOwners(std::uint32_t line) const
2037  {
2038  suite.expect(
2039  ownerCount(env, acct) == owners,
2040  "Owner count mismatch",
2041  __FILE__,
2042  line);
2043  }
2044 
2045  // Operators to make using the class more convenient.
2046  operator Account const() const
2047  {
2048  return acct;
2049  }
2050 
2051  operator ripple::AccountID() const
2052  {
2053  return acct.id();
2054  }
2055 
2056  IOU
2057  operator[](std::string const& s) const
2058  {
2059  return acct[s];
2060  }
2061  };
2062 
2063  AccountOwns alice{*this, env, "alice", 0};
2064  AccountOwns bob{*this, env, "bob", 0};
2065 
2066  // Fund with noripple so the accounts do not have any flags set.
2067  env.fund(XRP(5000), noripple(alice, bob));
2068  env.close();
2069 
2070  // Automatic trust line creation should fail if the check destination
2071  // can't afford the reserve for the trust line.
2072  {
2073  AccountOwns gw1{*this, env, "gw1", 0};
2074 
2075  // Fund gw1 with noripple (even though that's atypical for a
2076  // gateway) so it does not have any flags set. We'll set flags
2077  // on gw1 later.
2078  env.fund(XRP(5000), noripple(gw1));
2079  env.close();
2080 
2081  IOU const CK8 = gw1["CK8"];
2082  gw1.verifyOwners(__LINE__);
2083 
2084  Account const yui{"yui"};
2085 
2086  // Note the reserve in unit tests is 200 XRP, not 20. So here
2087  // we're just barely giving yui enough XRP to meet the
2088  // account reserve.
2089  env.fund(XRP(200), yui);
2090  env.close();
2091 
2092  uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
2093  env(check::create(gw1, yui, CK8(99)));
2094  env.close();
2095 
2096  env(check::cash(yui, chkId, CK8(99)),
2098  env.close();
2099  alice.verifyOwners(__LINE__);
2100 
2101  // Give yui enough XRP to meet the trust line's reserve. Cashing
2102  // the check succeeds and creates the trust line.
2103  env(pay(env.master, yui, XRP(51)));
2104  env.close();
2105  env(check::cash(yui, chkId, CK8(99)));
2106  verifyDeliveredAmount(env, CK8(99));
2107  env.close();
2108  BEAST_EXPECT(ownerCount(env, yui) == 1);
2109 
2110  // The automatic trust line does not take a reserve from gw1.
2111  // Since gw1's check was consumed it has no owners.
2112  gw1.verifyOwners(__LINE__);
2113  }
2114 
2115  // We'll be looking at the effects of various account root flags.
2116 
2117  // Automatically create trust lines using
2118  // o Offers and
2119  // o Check cashing
2120  // Compare the resulting trust lines and expect them to be very similar.
2121 
2122  // Lambda that compares two trust lines created by
2123  // o Offer crossing and
2124  // o Check cashing
2125  // between the same two accounts but with two different currencies.
2126  // The lambda expects the two trust lines to be largely similar.
2127  auto cmpTrustLines = [this, &env](
2128  Account const& acct1,
2129  Account const& acct2,
2130  IOU const& offerIou,
2131  IOU const& checkIou) {
2132  auto const offerLine =
2133  env.le(keylet::line(acct1, acct2, offerIou.currency));
2134  auto const checkLine =
2135  env.le(keylet::line(acct1, acct2, checkIou.currency));
2136  if (offerLine == nullptr || checkLine == nullptr)
2137  {
2138  BEAST_EXPECT(offerLine == nullptr && checkLine == nullptr);
2139  return;
2140  }
2141 
2142  {
2143  // Compare the contents of required fields.
2144  BEAST_EXPECT(offerLine->at(sfFlags) == checkLine->at(sfFlags));
2145 
2146  // Lambda that compares the contents of required STAmounts
2147  // without comparing the currency.
2148  auto cmpReqAmount =
2149  [this, offerLine, checkLine](SF_AMOUNT const& sfield) {
2150  STAmount const offerAmount = offerLine->at(sfield);
2151  STAmount const checkAmount = checkLine->at(sfield);
2152 
2153  // Neither STAmount should be native.
2154  if (!BEAST_EXPECT(
2155  !offerAmount.native() && !checkAmount.native()))
2156  return;
2157 
2158  BEAST_EXPECT(
2159  offerAmount.issue().account ==
2160  checkAmount.issue().account);
2161  BEAST_EXPECT(
2162  offerAmount.negative() == checkAmount.negative());
2163  BEAST_EXPECT(
2164  offerAmount.mantissa() == checkAmount.mantissa());
2165  BEAST_EXPECT(
2166  offerAmount.exponent() == checkAmount.exponent());
2167  };
2168  cmpReqAmount(sfBalance);
2169  cmpReqAmount(sfLowLimit);
2170  cmpReqAmount(sfHighLimit);
2171  }
2172  {
2173  // Lambda that compares the contents of optional fields.
2174  auto cmpOptField =
2175  [this, offerLine, checkLine](auto const& sfield) {
2176  // Expect both fields to either be present or absent.
2177  if (!BEAST_EXPECT(
2178  offerLine->isFieldPresent(sfield) ==
2179  checkLine->isFieldPresent(sfield)))
2180  return;
2181 
2182  // If both fields are absent then there's nothing
2183  // further to check.
2184  if (!offerLine->isFieldPresent(sfield))
2185  return;
2186 
2187  // Both optional fields are present so we can compare
2188  // them.
2189  BEAST_EXPECT(
2190  offerLine->at(sfield) == checkLine->at(sfield));
2191  };
2192  cmpOptField(sfLowNode);
2193  cmpOptField(sfLowQualityIn);
2194  cmpOptField(sfLowQualityOut);
2195 
2196  cmpOptField(sfHighNode);
2197  cmpOptField(sfHighQualityIn);
2198  cmpOptField(sfHighQualityOut);
2199  }
2200  };
2201 
2202  //----------- No account root flags, check written by issuer -----------
2203  {
2204  // No account root flags on any participant.
2205  // Automatic trust line from issuer to destination.
2206  AccountOwns gw1{*this, env, "gw1", 0};
2207 
2208  BEAST_EXPECT((*env.le(gw1))[sfFlags] == 0);
2209  BEAST_EXPECT((*env.le(alice))[sfFlags] == 0);
2210  BEAST_EXPECT((*env.le(bob))[sfFlags] == 0);
2211 
2212  // Use offers to automatically create the trust line.
2213  IOU const OF1 = gw1["OF1"];
2214  env(offer(gw1, XRP(98), OF1(98)));
2215  env.close();
2216  BEAST_EXPECT(
2217  env.le(keylet::line(gw1, alice, OF1.currency)) == nullptr);
2218  env(offer(alice, OF1(98), XRP(98)));
2219  ++alice.owners;
2220  env.close();
2221 
2222  // Both offers should be consumed.
2223  // Since gw1's offer was consumed and the trust line was not
2224  // created by gw1, gw1's owner count should be 0.
2225  gw1.verifyOwners(__LINE__);
2226 
2227  // alice's automatically created trust line bumps her owner count.
2228  alice.verifyOwners(__LINE__);
2229 
2230  // Use check cashing to automatically create the trust line.
2231  IOU const CK1 = gw1["CK1"];
2232  uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
2233  env(check::create(gw1, alice, CK1(98)));
2234  env.close();
2235  BEAST_EXPECT(
2236  env.le(keylet::line(gw1, alice, CK1.currency)) == nullptr);
2237  env(check::cash(alice, chkId, CK1(98)));
2238  ++alice.owners;
2239  verifyDeliveredAmount(env, CK1(98));
2240  env.close();
2241 
2242  // gw1's check should be consumed.
2243  // Since gw1's check was consumed and the trust line was not
2244  // created by gw1, gw1's owner count should be 0.
2245  gw1.verifyOwners(__LINE__);
2246 
2247  // alice's automatically created trust line bumps her owner count.
2248  alice.verifyOwners(__LINE__);
2249 
2250  cmpTrustLines(gw1, alice, OF1, CK1);
2251  }
2252  //--------- No account root flags, check written by non-issuer ---------
2253  {
2254  // No account root flags on any participant.
2255  // Automatic trust line from non-issuer to non-issuer.
2256 
2257  // Use offers to automatically create the trust line.
2258  // Transfer of assets using offers does not require rippling.
2259  // So bob's offer is successfully crossed which creates the
2260  // trust line.
2261  AccountOwns gw1{*this, env, "gw1", 0};
2262  IOU const OF1 = gw1["OF1"];
2263  env(offer(alice, XRP(97), OF1(97)));
2264  env.close();
2265  BEAST_EXPECT(
2266  env.le(keylet::line(alice, bob, OF1.currency)) == nullptr);
2267  env(offer(bob, OF1(97), XRP(97)));
2268  ++bob.owners;
2269  env.close();
2270 
2271  // Both offers should be consumed.
2272  env.require(balance(alice, OF1(1)));
2273  env.require(balance(bob, OF1(97)));
2274 
2275  // bob now has an owner count of 1 due to the new trust line.
2276  gw1.verifyOwners(__LINE__);
2277  alice.verifyOwners(__LINE__);
2278  bob.verifyOwners(__LINE__);
2279 
2280  // Use check cashing to automatically create the trust line.
2281  //
2282  // However cashing a check (unlike crossing offers) requires
2283  // rippling through the currency's issuer. Since gw1 does not
2284  // have rippling enabled the check cash fails and bob does not
2285  // have a trust line created.
2286  IOU const CK1 = gw1["CK1"];
2287  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
2288  env(check::create(alice, bob, CK1(97)));
2289  env.close();
2290  BEAST_EXPECT(
2291  env.le(keylet::line(alice, bob, CK1.currency)) == nullptr);
2292  env(check::cash(bob, chkId, CK1(97)), ter(terNO_RIPPLE));
2293  env.close();
2294 
2295  BEAST_EXPECT(
2296  env.le(keylet::line(gw1, bob, OF1.currency)) != nullptr);
2297  BEAST_EXPECT(
2298  env.le(keylet::line(gw1, bob, CK1.currency)) == nullptr);
2299 
2300  // Delete alice's check since it is no longer needed.
2301  env(check::cancel(alice, chkId));
2302  env.close();
2303 
2304  // No one's owner count should have changed.
2305  gw1.verifyOwners(__LINE__);
2306  alice.verifyOwners(__LINE__);
2307  bob.verifyOwners(__LINE__);
2308  }
2309 
2310  //------------- lsfDefaultRipple, check written by issuer --------------
2311  {
2312  // gw1 enables rippling.
2313  // Automatic trust line from issuer to non-issuer should still work.
2314  AccountOwns gw1{*this, env, "gw1", 0};
2315  env(fset(gw1, asfDefaultRipple));
2316  env.close();
2317 
2318  // Use offers to automatically create the trust line.
2319  IOU const OF2 = gw1["OF2"];
2320  env(offer(gw1, XRP(96), OF2(96)));
2321  env.close();
2322  BEAST_EXPECT(
2323  env.le(keylet::line(gw1, alice, OF2.currency)) == nullptr);
2324  env(offer(alice, OF2(96), XRP(96)));
2325  ++alice.owners;
2326  env.close();
2327 
2328  // Both offers should be consumed.
2329  // Since gw1's offer was consumed and the trust line was not
2330  // created by gw1, gw1's owner count should still be 0.
2331  gw1.verifyOwners(__LINE__);
2332 
2333  // alice's automatically created trust line bumps her owner count.
2334  alice.verifyOwners(__LINE__);
2335 
2336  // Use check cashing to automatically create the trust line.
2337  IOU const CK2 = gw1["CK2"];
2338  uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
2339  env(check::create(gw1, alice, CK2(96)));
2340  env.close();
2341  BEAST_EXPECT(
2342  env.le(keylet::line(gw1, alice, CK2.currency)) == nullptr);
2343  env(check::cash(alice, chkId, CK2(96)));
2344  ++alice.owners;
2345  verifyDeliveredAmount(env, CK2(96));
2346  env.close();
2347 
2348  // gw1's check should be consumed.
2349  // Since gw1's check was consumed and the trust line was not
2350  // created by gw1, gw1's owner count should still be 0.
2351  gw1.verifyOwners(__LINE__);
2352 
2353  // alice's automatically created trust line bumps her owner count.
2354  alice.verifyOwners(__LINE__);
2355 
2356  cmpTrustLines(gw1, alice, OF2, CK2);
2357  }
2358  //----------- lsfDefaultRipple, check written by non-issuer ------------
2359  {
2360  // gw1 enabled rippling, so automatic trust line from non-issuer
2361  // to non-issuer should work.
2362 
2363  // Use offers to automatically create the trust line.
2364  AccountOwns gw1{*this, env, "gw1", 0};
2365  IOU const OF2 = gw1["OF2"];
2366  env(offer(alice, XRP(95), OF2(95)));
2367  env.close();
2368  BEAST_EXPECT(
2369  env.le(keylet::line(alice, bob, OF2.currency)) == nullptr);
2370  env(offer(bob, OF2(95), XRP(95)));
2371  ++bob.owners;
2372  env.close();
2373 
2374  // bob's owner count should increase due to the new trust line.
2375  gw1.verifyOwners(__LINE__);
2376  alice.verifyOwners(__LINE__);
2377  bob.verifyOwners(__LINE__);
2378 
2379  // Use check cashing to automatically create the trust line.
2380  IOU const CK2 = gw1["CK2"];
2381  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
2382  env(check::create(alice, bob, CK2(95)));
2383  env.close();
2384  BEAST_EXPECT(
2385  env.le(keylet::line(alice, bob, CK2.currency)) == nullptr);
2386  env(check::cash(bob, chkId, CK2(95)));
2387  ++bob.owners;
2388  verifyDeliveredAmount(env, CK2(95));
2389  env.close();
2390 
2391  // bob's owner count should increase due to the new trust line.
2392  gw1.verifyOwners(__LINE__);
2393  alice.verifyOwners(__LINE__);
2394  bob.verifyOwners(__LINE__);
2395 
2396  cmpTrustLines(alice, bob, OF2, CK2);
2397  }
2398 
2399  //-------------- lsfDepositAuth, check written by issuer ---------------
2400  {
2401  // Both offers and checks ignore the lsfDepositAuth flag, since
2402  // the destination signs the transaction that delivers their funds.
2403  // So setting lsfDepositAuth on all the participants should not
2404  // change any outcomes.
2405  //
2406  // Automatic trust line from issuer to non-issuer should still work.
2407  AccountOwns gw1{*this, env, "gw1", 0};
2408  env(fset(gw1, asfDepositAuth));
2409  env(fset(alice, asfDepositAuth));
2410  env(fset(bob, asfDepositAuth));
2411  env.close();
2412 
2413  // Use offers to automatically create the trust line.
2414  IOU const OF3 = gw1["OF3"];
2415  env(offer(gw1, XRP(94), OF3(94)));
2416  env.close();
2417  BEAST_EXPECT(
2418  env.le(keylet::line(gw1, alice, OF3.currency)) == nullptr);
2419  env(offer(alice, OF3(94), XRP(94)));
2420  ++alice.owners;
2421  env.close();
2422 
2423  // Both offers should be consumed.
2424  // Since gw1's offer was consumed and the trust line was not
2425  // created by gw1, gw1's owner count should still be 0.
2426  gw1.verifyOwners(__LINE__);
2427 
2428  // alice's automatically created trust line bumps her owner count.
2429  alice.verifyOwners(__LINE__);
2430 
2431  // Use check cashing to automatically create the trust line.
2432  IOU const CK3 = gw1["CK3"];
2433  uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
2434  env(check::create(gw1, alice, CK3(94)));
2435  env.close();
2436  BEAST_EXPECT(
2437  env.le(keylet::line(gw1, alice, CK3.currency)) == nullptr);
2438  env(check::cash(alice, chkId, CK3(94)));
2439  ++alice.owners;
2440  verifyDeliveredAmount(env, CK3(94));
2441  env.close();
2442 
2443  // gw1's check should be consumed.
2444  // Since gw1's check was consumed and the trust line was not
2445  // created by gw1, gw1's owner count should still be 0.
2446  gw1.verifyOwners(__LINE__);
2447 
2448  // alice's automatically created trust line bumps her owner count.
2449  alice.verifyOwners(__LINE__);
2450 
2451  cmpTrustLines(gw1, alice, OF3, CK3);
2452  }
2453  //------------ lsfDepositAuth, check written by non-issuer -------------
2454  {
2455  // The presence of the lsfDepositAuth flag should not affect
2456  // automatic trust line creation.
2457 
2458  // Use offers to automatically create the trust line.
2459  AccountOwns gw1{*this, env, "gw1", 0};
2460  IOU const OF3 = gw1["OF3"];
2461  env(offer(alice, XRP(93), OF3(93)));
2462  env.close();
2463  BEAST_EXPECT(
2464  env.le(keylet::line(alice, bob, OF3.currency)) == nullptr);
2465  env(offer(bob, OF3(93), XRP(93)));
2466  ++bob.owners;
2467  env.close();
2468 
2469  // bob's owner count should increase due to the new trust line.
2470  gw1.verifyOwners(__LINE__);
2471  alice.verifyOwners(__LINE__);
2472  bob.verifyOwners(__LINE__);
2473 
2474  // Use check cashing to automatically create the trust line.
2475  IOU const CK3 = gw1["CK3"];
2476  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
2477  env(check::create(alice, bob, CK3(93)));
2478  env.close();
2479  BEAST_EXPECT(
2480  env.le(keylet::line(alice, bob, CK3.currency)) == nullptr);
2481  env(check::cash(bob, chkId, CK3(93)));
2482  ++bob.owners;
2483  verifyDeliveredAmount(env, CK3(93));
2484  env.close();
2485 
2486  // bob's owner count should increase due to the new trust line.
2487  gw1.verifyOwners(__LINE__);
2488  alice.verifyOwners(__LINE__);
2489  bob.verifyOwners(__LINE__);
2490 
2491  cmpTrustLines(alice, bob, OF3, CK3);
2492  }
2493 
2494  //-------------- lsfGlobalFreeze, check written by issuer --------------
2495  {
2496  // Set lsfGlobalFreeze on gw1. That should stop any automatic
2497  // trust lines from being created.
2498  AccountOwns gw1{*this, env, "gw1", 0};
2499  env(fset(gw1, asfGlobalFreeze));
2500  env.close();
2501 
2502  // Use offers to automatically create the trust line.
2503  IOU const OF4 = gw1["OF4"];
2504  env(offer(gw1, XRP(92), OF4(92)), ter(tecFROZEN));
2505  env.close();
2506  BEAST_EXPECT(
2507  env.le(keylet::line(gw1, alice, OF4.currency)) == nullptr);
2508  env(offer(alice, OF4(92), XRP(92)), ter(tecFROZEN));
2509  env.close();
2510 
2511  // No one's owner count should have changed.
2512  gw1.verifyOwners(__LINE__);
2513  alice.verifyOwners(__LINE__);
2514  bob.verifyOwners(__LINE__);
2515 
2516  // Use check cashing to automatically create the trust line.
2517  IOU const CK4 = gw1["CK4"];
2518  uint256 const chkId{getCheckIndex(gw1, env.seq(gw1))};
2519  env(check::create(gw1, alice, CK4(92)), ter(tecFROZEN));
2520  env.close();
2521  BEAST_EXPECT(
2522  env.le(keylet::line(gw1, alice, CK4.currency)) == nullptr);
2523  env(check::cash(alice, chkId, CK4(92)), ter(tecNO_ENTRY));
2524  env.close();
2525 
2526  // No one's owner count should have changed.
2527  gw1.verifyOwners(__LINE__);
2528  alice.verifyOwners(__LINE__);
2529  bob.verifyOwners(__LINE__);
2530 
2531  // Because gw1 has set lsfGlobalFreeze, neither trust line
2532  // is created.
2533  BEAST_EXPECT(
2534  env.le(keylet::line(gw1, alice, OF4.currency)) == nullptr);
2535  BEAST_EXPECT(
2536  env.le(keylet::line(gw1, alice, CK4.currency)) == nullptr);
2537  }
2538  //------------ lsfGlobalFreeze, check written by non-issuer ------------
2539  {
2540  // Since gw1 has the lsfGlobalFreeze flag set, there should be
2541  // no automatic trust line creation between non-issuers.
2542 
2543  // Use offers to automatically create the trust line.
2544  AccountOwns gw1{*this, env, "gw1", 0};
2545  IOU const OF4 = gw1["OF4"];
2546  env(offer(alice, XRP(91), OF4(91)), ter(tecFROZEN));
2547  env.close();
2548  BEAST_EXPECT(
2549  env.le(keylet::line(alice, bob, OF4.currency)) == nullptr);
2550  env(offer(bob, OF4(91), XRP(91)), ter(tecFROZEN));
2551  env.close();
2552 
2553  // No one's owner count should have changed.
2554  gw1.verifyOwners(__LINE__);
2555  alice.verifyOwners(__LINE__);
2556  bob.verifyOwners(__LINE__);
2557 
2558  // Use check cashing to automatically create the trust line.
2559  IOU const CK4 = gw1["CK4"];
2560  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
2561  env(check::create(alice, bob, CK4(91)), ter(tecFROZEN));
2562  env.close();
2563  BEAST_EXPECT(
2564  env.le(keylet::line(alice, bob, CK4.currency)) == nullptr);
2565  env(check::cash(bob, chkId, CK4(91)), ter(tecNO_ENTRY));
2566  env.close();
2567 
2568  // No one's owner count should have changed.
2569  gw1.verifyOwners(__LINE__);
2570  alice.verifyOwners(__LINE__);
2571  bob.verifyOwners(__LINE__);
2572 
2573  // Because gw1 has set lsfGlobalFreeze, neither trust line
2574  // is created.
2575  BEAST_EXPECT(
2576  env.le(keylet::line(gw1, bob, OF4.currency)) == nullptr);
2577  BEAST_EXPECT(
2578  env.le(keylet::line(gw1, bob, CK4.currency)) == nullptr);
2579  }
2580 
2581  //-------------- lsfRequireAuth, check written by issuer ---------------
2582 
2583  // We want to test the lsfRequireAuth flag, but we can't set that
2584  // flag on an account that already has trust lines. So we'll fund
2585  // a new gateway and use that.
2586  {
2587  AccountOwns gw2{*this, env, "gw2", 0};
2588  env.fund(XRP(5000), gw2);
2589  env.close();
2590 
2591  // Set lsfRequireAuth on gw2. That should stop any automatic
2592  // trust lines from being created.
2593  env(fset(gw2, asfRequireAuth));
2594  env.close();
2595 
2596  // Use offers to automatically create the trust line.
2597  IOU const OF5 = gw2["OF5"];
2598  std::uint32_t gw2OfferSeq = {env.seq(gw2)};
2599  env(offer(gw2, XRP(92), OF5(92)));
2600  ++gw2.owners;
2601  env.close();
2602  BEAST_EXPECT(
2603  env.le(keylet::line(gw2, alice, OF5.currency)) == nullptr);
2604  env(offer(alice, OF5(92), XRP(92)), ter(tecNO_LINE));
2605  env.close();
2606 
2607  // gw2 should still own the offer, but no one else's owner
2608  // count should have changed.
2609  gw2.verifyOwners(__LINE__);
2610  alice.verifyOwners(__LINE__);
2611  bob.verifyOwners(__LINE__);
2612 
2613  // Since we don't need it any more, remove gw2's offer.
2614  env(offer_cancel(gw2, gw2OfferSeq));
2615  --gw2.owners;
2616  env.close();
2617  gw2.verifyOwners(__LINE__);
2618 
2619  // Use check cashing to automatically create the trust line.
2620  IOU const CK5 = gw2["CK5"];
2621  uint256 const chkId{getCheckIndex(gw2, env.seq(gw2))};
2622  env(check::create(gw2, alice, CK5(92)));
2623  ++gw2.owners;
2624  env.close();
2625  BEAST_EXPECT(
2626  env.le(keylet::line(gw2, alice, CK5.currency)) == nullptr);
2627  env(check::cash(alice, chkId, CK5(92)), ter(tecNO_AUTH));
2628  env.close();
2629 
2630  // gw2 should still own the check, but no one else's owner
2631  // count should have changed.
2632  gw2.verifyOwners(__LINE__);
2633  alice.verifyOwners(__LINE__);
2634  bob.verifyOwners(__LINE__);
2635 
2636  // Because gw2 has set lsfRequireAuth, neither trust line
2637  // is created.
2638  BEAST_EXPECT(
2639  env.le(keylet::line(gw2, alice, OF5.currency)) == nullptr);
2640  BEAST_EXPECT(
2641  env.le(keylet::line(gw2, alice, CK5.currency)) == nullptr);
2642 
2643  // Since we don't need it any more, remove gw2's check.
2644  env(check::cancel(gw2, chkId));
2645  --gw2.owners;
2646  env.close();
2647  gw2.verifyOwners(__LINE__);
2648  }
2649  //------------ lsfRequireAuth, check written by non-issuer -------------
2650  {
2651  // Since gw2 has the lsfRequireAuth flag set, there should be
2652  // no automatic trust line creation between non-issuers.
2653 
2654  // Use offers to automatically create the trust line.
2655  AccountOwns gw2{*this, env, "gw2", 0};
2656  IOU const OF5 = gw2["OF5"];
2657  env(offer(alice, XRP(91), OF5(91)), ter(tecUNFUNDED_OFFER));
2658  env.close();
2659  env(offer(bob, OF5(91), XRP(91)), ter(tecNO_LINE));
2660  BEAST_EXPECT(
2661  env.le(keylet::line(gw2, bob, OF5.currency)) == nullptr);
2662  env.close();
2663 
2664  gw2.verifyOwners(__LINE__);
2665  alice.verifyOwners(__LINE__);
2666  bob.verifyOwners(__LINE__);
2667 
2668  // Use check cashing to automatically create the trust line.
2669  IOU const CK5 = gw2["CK5"];
2670  uint256 const chkId{getCheckIndex(alice, env.seq(alice))};
2671  env(check::create(alice, bob, CK5(91)));
2672  env.close();
2673  BEAST_EXPECT(
2674  env.le(keylet::line(alice, bob, CK5.currency)) == nullptr);
2675  env(check::cash(bob, chkId, CK5(91)), ter(tecPATH_PARTIAL));
2676  env.close();
2677 
2678  // Delete alice's check since it is no longer needed.
2679  env(check::cancel(alice, chkId));
2680  env.close();
2681 
2682  // No one's owner count should have changed.
2683  gw2.verifyOwners(__LINE__);
2684  alice.verifyOwners(__LINE__);
2685  bob.verifyOwners(__LINE__);
2686 
2687  // Because gw2 has set lsfRequireAuth, neither trust line
2688  // is created.
2689  BEAST_EXPECT(
2690  env.le(keylet::line(gw2, bob, OF5.currency)) == nullptr);
2691  BEAST_EXPECT(
2692  env.le(keylet::line(gw2, bob, CK5.currency)) == nullptr);
2693  }
2694  }
2695 
2696  void
2698  {
2699  testEnabled(features);
2700  testCreateValid(features);
2701  testCreateDisallowIncoming(features);
2702  testCreateInvalid(features);
2703  testCashXRP(features);
2704  testCashIOU(features);
2705  testCashXferFee(features);
2706  testCashQuality(features);
2707  testCashInvalid(features);
2708  testCancelValid(features);
2709  testCancelInvalid(features);
2710  testFix1623Enable(features);
2711  testWithTickets(features);
2712  }
2713 
2714 public:
2715  void
2716  run() override
2717  {
2718  using namespace test::jtx;
2719  auto const sa = supported_amendments();
2722  testWithFeats(sa);
2723 
2724  testTrustLineCreation(sa); // Test with featureCheckCashMakesTrustLine
2725  }
2726 };
2727 
2728 BEAST_DEFINE_TESTSUITE(Check, tx, ripple);
2729 
2730 } // namespace ripple
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:135
ripple::tecUNFUNDED_OFFER
@ tecUNFUNDED_OFFER
Definition: TER.h:251
ripple::sfHighQualityIn
const SF_UINT32 sfHighQualityIn
ripple::sfOwnerCount
const SF_UINT32 sfOwnerCount
ripple::STAmount::negate
void negate()
Definition: STAmount.h:402
ripple::tecFROZEN
@ tecFROZEN
Definition: TER.h:270
ripple::Check_test::testCreateValid
void testCreateValid(FeatureBitset features)
Definition: Check_test.cpp:200
ripple::sfSourceTag
const SF_UINT32 sfSourceTag
ripple::test::jtx::XRP
const XRP_t XRP
Converts to XRP Issue or STAmount.
Definition: amount.cpp:105
ripple::Check_test::testWithFeats
void testWithFeats(FeatureBitset features)
Definition: Check_test.cpp:2697
ripple::Issue
A currency issued by an account.
Definition: Issue.h:34
ripple::asfDepositAuth
constexpr std::uint32_t asfDepositAuth
Definition: TxFlags.h:82
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:66
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:382
ripple::terNO_LINE
@ terNO_LINE
Definition: TER.h:200
ripple::Check_test::testCashInvalid
void testCashInvalid(FeatureBitset features)
Definition: Check_test.cpp:1363
ripple::sfAmount
const SF_AMOUNT sfAmount
ripple::Check_test::getCheckIndex
static uint256 getCheckIndex(AccountID const &account, std::uint32_t uSequence)
Definition: Check_test.cpp:91
std::vector
STL class.
ripple::Check_test::testCashIOU
void testCashIOU(FeatureBitset features)
Definition: Check_test.cpp:696
ripple::STAmount::getJson
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:655
ripple::test::jtx::dest_tag::dest_tag
dest_tag(std::uint32_t tag)
Definition: Check_test.cpp:72
ripple::test::jtx::offer_cancel
Json::Value offer_cancel(Account const &account, std::uint32_t offerSeq)
Cancel an offer.
Definition: offer.cpp:45
ripple::tecDST_TAG_NEEDED
@ tecDST_TAG_NEEDED
Definition: TER.h:276
ripple::keylet::offer
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
Definition: Indexes.cpp:222
ripple::test::jtx::expiration::operator()
void operator()(Env &, JTx &jt) const
Definition: Check_test.cpp:41
ripple::Check_test::testCashXRP
void testCashXRP(FeatureBitset features)
Definition: Check_test.cpp:577
ripple::featureMultiSignReserve
const uint256 featureMultiSignReserve
ripple::terNO_RIPPLE
@ terNO_RIPPLE
Definition: TER.h:205
ripple::test::jtx::source_tag::tag_
const std::uint32_t tag_
Definition: Check_test.cpp:51
ripple::Check_test::testEnabled
void testEnabled(FeatureBitset features)
Definition: Check_test.cpp:150
ripple::SField::jsonName
const Json::StaticString jsonName
Definition: SField.h:136
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:550
ripple::sfExpiration
const SF_UINT32 sfExpiration
ripple::asfDisallowIncomingCheck
constexpr std::uint32_t asfDisallowIncomingCheck
Definition: TxFlags.h:88
ripple::KeyType::ed25519
@ ed25519
ripple::test::jtx::expiration
Set Expiration on a JTx.
Definition: Check_test.cpp:29
ripple::sfLowNode
const SF_UINT64 sfLowNode
ripple::Keylet::key
uint256 key
Definition: Keylet.h:40
ripple::base_uint< 256 >
ripple::sfDeliverMin
const SF_AMOUNT sfDeliverMin
ripple::test::jtx::source_tag
Set SourceTag on a JTx.
Definition: Check_test.cpp:48
ripple::sfLowQualityOut
const SF_UINT32 sfLowQualityOut
ripple::temINVALID_FLAG
@ temINVALID_FLAG
Definition: TER.h:109
ripple::sfLowLimit
const SF_AMOUNT sfLowLimit
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:113
ripple::sfDeliveredAmount
const SF_AMOUNT sfDeliveredAmount
ripple::featureDisallowIncoming
const uint256 featureDisallowIncoming
ripple::Check_test::disallowIncoming
const FeatureBitset disallowIncoming
Definition: Check_test.cpp:88
ripple::JsonOptions::none
@ none
ripple::Check_test::run
void run() override
Definition: Check_test.cpp:2716
ripple::TERSubset< CanCvtToTER >
ripple::test::jtx::JTx
Execution context for applying a JSON transaction.
Definition: JTx.h:42
ripple::test::jtx::dest_tag::operator()
void operator()(Env &, JTx &jt) const
Definition: Check_test.cpp:77
ripple::sfLowQualityIn
const SF_UINT32 sfLowQualityIn
ripple::test::jtx::fset
Json::Value fset(Account const &account, std::uint32_t on, std::uint32_t off=0)
Add and/or remove flag.
Definition: flags.cpp:28
ripple::fix1623
const uint256 fix1623
ripple::test::jtx::Env::close
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
Definition: Env.cpp:121
ripple::STAmount
Definition: STAmount.h:45
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:932
std::uint32_t
ripple::sfHighLimit
const SF_AMOUNT sfHighLimit
ripple::STAmount::setIssue
void setIssue(Issue const &issue)
Set the Issue for this amount and update mIsNative.
Definition: STAmount.cpp:479
ripple::tecPATH_PARTIAL
@ tecPATH_PARTIAL
Definition: TER.h:249
ripple::keylet::line
Keylet line(AccountID const &id0, AccountID const &id1, Currency const &currency) noexcept
The index of a trust line for a given currency.
Definition: Indexes.cpp:193
ripple::featureChecks
const uint256 featureChecks
ripple::test::jtx::expiration::expry_
const std::uint32_t expry_
Definition: Check_test.cpp:32
ripple::temREDUNDANT
@ temREDUNDANT
Definition: TER.h:110
ripple::temBAD_FEE
@ temBAD_FEE
Definition: TER.h:90
ripple::Check_test::testCashXferFee
void testCashXferFee(FeatureBitset features)
Definition: Check_test.cpp:1086
ripple::KeyType::secp256k1
@ secp256k1
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::Check_test::testCancelInvalid
void testCancelInvalid(FeatureBitset features)
Definition: Check_test.cpp:1831
Json::Value::removeMember
Value removeMember(const char *key)
Remove and return the named member.
Definition: json_value.cpp:907
ripple::tecNO_LINE_INSUF_RESERVE
@ tecNO_LINE_INSUF_RESERVE
Definition: TER.h:259
ripple::tfSetFreeze
constexpr std::uint32_t tfSetFreeze
Definition: TxFlags.h:111
ripple::tecNO_LINE
@ tecNO_LINE
Definition: TER.h:268
ripple::tecEXPIRED
@ tecEXPIRED
Definition: TER.h:281
ripple::Check_test::testCashQuality
void testCashQuality(FeatureBitset features)
Definition: Check_test.cpp:1156
ripple::temDISABLED
@ temDISABLED
Definition: TER.h:112
ripple::tfSetfAuth
constexpr std::uint32_t tfSetfAuth
Definition: TxFlags.h:108
ripple::Check_test
Definition: Check_test.cpp:86
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::asfRequireAuth
constexpr std::uint32_t asfRequireAuth
Definition: TxFlags.h:75
ripple::test::jtx::Env::le
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Definition: Env.cpp:216
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:98
ripple::asfDefaultRipple
constexpr std::uint32_t asfDefaultRipple
Definition: TxFlags.h:81
ripple::sfDestinationTag
const SF_UINT32 sfDestinationTag
ripple::Check_test::testTrustLineCreation
void testTrustLineCreation(FeatureBitset features)
Definition: Check_test.cpp:2012
ripple::asfRequireDest
constexpr std::uint32_t asfRequireDest
Definition: TxFlags.h:74
ripple::tecNO_PERMISSION
@ tecNO_PERMISSION
Definition: TER.h:272
ripple::SF_AMOUNT
TypedField< STAmount > SF_AMOUNT
Definition: SField.h:320
ripple::sfBalance
const SF_AMOUNT sfBalance
ripple::lsfDisallowIncomingCheck
@ lsfDisallowIncomingCheck
Definition: LedgerFormats.h:240
ripple::FeatureBitset
Definition: Feature.h:113
ripple::tecPATH_DRY
@ tecPATH_DRY
Definition: TER.h:261
ripple::tecINSUFFICIENT_RESERVE
@ tecINSUFFICIENT_RESERVE
Definition: TER.h:274
ripple::Check_test::testCancelValid
void testCancelValid(FeatureBitset features)
Definition: Check_test.cpp:1661
ripple::asfGlobalFreeze
constexpr std::uint32_t asfGlobalFreeze
Definition: TxFlags.h:80
ripple::sfHighQualityOut
const SF_UINT32 sfHighQualityOut
ripple::Check_test::testCreateDisallowIncoming
void testCreateDisallowIncoming(FeatureBitset features)
Definition: Check_test.cpp:299
ripple::forEachItem
void forEachItem(ReadView const &view, Keylet const &root, std::function< void(std::shared_ptr< SLE const > const &)> const &f)
Iterate all items in the given directory.
Definition: View.cpp:367
std::size_t
ripple::tfClearFreeze
constexpr std::uint32_t tfClearFreeze
Definition: TxFlags.h:112
ripple::test::jtx::Account
Immutable cryptographic account descriptor.
Definition: Account.h:37
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:273
ripple::temMALFORMED
@ temMALFORMED
Definition: TER.h:85
ripple::featureCheckCashMakesTrustLine
const uint256 featureCheckCashMakesTrustLine
ripple::test::jtx::expiration::expiration
expiration(NetClock::time_point const &expiry)
Definition: Check_test.cpp:35
ripple::tecNO_AUTH
@ tecNO_AUTH
Definition: TER.h:267
ripple::temBAD_EXPIRATION
@ temBAD_EXPIRATION
Definition: TER.h:89
ripple::keylet::check
Keylet check(AccountID const &id, std::uint32_t seq) noexcept
A Check.
Definition: Indexes.cpp:281
ripple::Check_test::testWithTickets
void testWithTickets(FeatureBitset features)
Definition: Check_test.cpp:1910
ripple::tesSUCCESS
@ tesSUCCESS
Definition: TER.h:222
ripple::test::jtx::dest_tag::tag_
const std::uint32_t tag_
Definition: Check_test.cpp:69
ripple::tfImmediateOrCancel
constexpr std::uint32_t tfImmediateOrCancel
Definition: TxFlags.h:94
ripple::sfHighNode
const SF_UINT64 sfHighNode
ripple::test::jtx::Env::current
std::shared_ptr< OpenView const > current() const
Returns the current ledger.
Definition: Env.h:300
ripple::Check_test::verifyDeliveredAmount
void verifyDeliveredAmount(test::jtx::Env &env, STAmount const &amount)
Definition: Check_test.cpp:126
ripple::test::jtx::Env
A transaction testing environment.
Definition: Env.h:116
ripple::Check_test::testCreateInvalid
void testCreateInvalid(FeatureBitset features)
Definition: Check_test.cpp:393
ripple::tecNO_DST
@ tecNO_DST
Definition: TER.h:257
ripple::test::jtx::Env::rpc
Json::Value rpc(std::unordered_map< std::string, std::string > const &headers, std::string const &cmd, Args &&... args)
Execute an RPC command.
Definition: Env.h:687
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::Check_test::testFix1623Enable
void testFix1623Enable(FeatureBitset features)
Definition: Check_test.cpp:1864
ripple::XRPAmount
Definition: XRPAmount.h:46
ripple::test::jtx::source_tag::operator()
void operator()(Env &, JTx &jt) const
Definition: Check_test.cpp:59