20 #include <ripple/app/paths/Flow.h>
21 #include <ripple/app/paths/impl/Steps.h>
22 #include <ripple/basics/contract.h>
23 #include <ripple/core/Config.h>
24 #include <ripple/ledger/ApplyViewImpl.h>
25 #include <ripple/ledger/PaymentSandbox.h>
26 #include <ripple/ledger/Sandbox.h>
27 #include <ripple/protocol/Feature.h>
28 #include <ripple/protocol/jss.h>
30 #include <test/jtx/PathSet.h>
46 return sle->isFlag(flag);
48 Throw<std::runtime_error>(
"No line in getTrustFlag");
56 auto feeDrops = env.
current()->fees().base;
65 testcase(
"Direct Step");
68 auto const alice =
Account(
"alice");
69 auto const bob =
Account(
"bob");
70 auto const carol =
Account(
"carol");
71 auto const dan =
Account(
"dan");
72 auto const erin =
Account(
"erin");
73 auto const USDA = alice[
"USD"];
74 auto const USDB = bob[
"USD"];
75 auto const USDC = carol[
"USD"];
76 auto const USDD = dan[
"USD"];
78 auto const USD = gw[
"USD"];
81 Env env(*
this, features);
83 env.
fund(
XRP(10000), alice, bob, gw);
84 env.
trust(USD(1000), alice, bob);
85 env(
pay(gw, alice, USD(100)));
86 env(
pay(alice, bob, USD(10)),
paths(USD));
91 Env env(*
this, features);
93 env.
fund(
XRP(10000), alice, bob);
94 env(
pay(alice, bob,
XRP(100)));
100 Env env(*
this, features);
102 env.
fund(
XRP(10000), alice, bob, gw);
103 env.
trust(USD(1000), alice, bob);
104 env(
pay(gw, alice, USD(100)));
107 env(
pay(alice, bob, USD(110)),
114 Env env(*
this, features);
116 env.
fund(
XRP(10000), alice, bob, carol, dan);
117 env.
trust(USDA(10), bob);
118 env.
trust(USDB(10), carol);
119 env.
trust(USDC(10), dan);
120 env(
pay(alice, dan, USDC(10)),
paths(USDA));
129 Env env(*
this, features);
131 env.
fund(
XRP(10000), alice, bob, carol, dan);
132 env.
trust(USDA(10), bob);
133 env.
trust(USDB(10), alice, carol);
134 env.
trust(USDC(10), dan);
138 env(
pay(bob, alice, USDB(6)));
139 env(
pay(alice, dan, USDC(5)),
149 Env env(*
this, features);
151 env.
fund(
XRP(10000), alice, bob, carol, dan);
152 env.
trust(USDA(10), bob);
153 env.
trust(USDB(10), alice, carol);
154 env.
trust(USDC(10), dan);
157 env(
pay(alice, dan, USDC(5)),
167 Env env(*
this, features);
169 env.
fund(
XRP(10000), alice, bob, carol, dan, erin);
170 env.
trust(USDA(10), bob, carol);
171 env.
trust(USDB(10), dan);
172 env.
trust(USDC(10), alice, dan);
173 env.
trust(USDD(20), erin);
175 env(
rate(carol, 1.1));
178 env(
pay(carol, alice, USDC(10)));
179 env(
pay(alice, erin, USDD(5)),
190 Env env(*
this, features);
192 env.
fund(
XRP(10000), alice, bob, carol);
193 env.
trust(USDA(10), bob);
194 env.
trust(USDB(10), carol);
196 env(
pay(alice, carol, USDB(5)),
202 env(
pay(alice, carol, USDB(5)),
212 testcase(
"Line Quality");
215 auto const alice =
Account(
"alice");
216 auto const bob =
Account(
"bob");
217 auto const carol =
Account(
"carol");
218 auto const dan =
Account(
"dan");
219 auto const USDA = alice[
"USD"];
220 auto const USDB = bob[
"USD"];
221 auto const USDC = carol[
"USD"];
222 auto const USDD = dan[
"USD"];
225 for (
auto bobDanQIn : {80, 100, 120})
226 for (
auto bobAliceQOut : {80, 100, 120})
228 Env env(*
this, features);
229 env.
fund(
XRP(10000), alice, bob, carol, dan);
232 env(
trust(carol, USDA(100)));
234 env(
pay(alice, bob, USDA(100)));
236 env(
pay(dan, carol, USDA(10)),
241 if (bobAliceQOut > bobDanQIn)
244 USDD(10.0 *
double(bobAliceQOut) /
double(bobDanQIn))));
251 for (
auto carolAliceQIn : {80, 100, 120})
253 Env env(*
this, features);
254 env.
fund(
XRP(10000), alice, bob, carol);
255 env(
trust(bob, USDA(10)));
258 env(
pay(alice, bob, USDA(10)));
260 env(
pay(bob, carol, USDA(5)),
sendmax(USDA(10)));
261 auto const effectiveQ =
262 carolAliceQIn > 100 ? 1.0 : carolAliceQIn / 100.0;
267 for (
auto bobAliceQOut : {80, 100, 120})
269 Env env(*
this, features);
270 env.
fund(
XRP(10000), alice, bob, carol);
272 env(
trust(carol, USDA(10)));
274 env(
pay(alice, bob, USDA(10)));
276 env(
pay(bob, carol, USDA(5)),
sendmax(USDA(5)));
285 testcase(
"Book Step");
289 auto const gw =
Account(
"gateway");
290 auto const USD = gw[
"USD"];
291 auto const BTC = gw[
"BTC"];
292 auto const EUR = gw[
"EUR"];
299 Env env(*
this, features);
301 env.
fund(
XRP(10000), alice, bob, carol, gw);
302 env.
trust(USD(1000), alice, bob, carol);
303 env.
trust(BTC(1000), alice, bob, carol);
305 env(
pay(gw, alice, BTC(50)));
306 env(
pay(gw, bob, USD(50)));
308 env(offer(bob, BTC(50), USD(50)));
316 BEAST_EXPECT(!
isOffer(env, bob, BTC(50), USD(50)));
320 Env env(*
this, features);
322 env.
fund(
XRP(10000), alice, bob, carol, gw);
323 env.
trust(USD(1000), alice, bob, carol);
324 env.
trust(BTC(1000), alice, bob, carol);
326 env(
pay(gw, alice, BTC(50)));
327 env(
pay(gw, bob, USD(50)));
329 env(offer(bob, BTC(50),
XRP(50)));
330 env(offer(bob,
XRP(50), USD(50)));
338 BEAST_EXPECT(!
isOffer(env, bob,
XRP(50), USD(50)));
339 BEAST_EXPECT(!
isOffer(env, bob, BTC(50),
XRP(50)));
343 Env env(*
this, features);
345 env.
fund(
XRP(10000), alice, bob, carol, gw);
346 env.
trust(USD(1000), alice, bob, carol);
347 env.
trust(BTC(1000), alice, bob, carol);
349 env(
pay(gw, bob, USD(50)));
351 env(offer(bob,
XRP(50), USD(50)));
359 BEAST_EXPECT(!
isOffer(env, bob,
XRP(50), USD(50)));
363 Env env(*
this, features);
365 env.
fund(
XRP(10000), alice, bob, carol, gw);
366 env.
trust(USD(1000), alice, bob, carol);
367 env.
trust(BTC(1000), alice, bob, carol);
369 env(
pay(gw, alice, USD(50)));
371 env(offer(bob, USD(50),
XRP(50)));
379 BEAST_EXPECT(!
isOffer(env, bob, USD(50),
XRP(50)));
383 Env env(*
this, features);
385 env.
fund(
XRP(10000), alice, bob, carol, gw);
386 env.
trust(USD(1000), alice, bob, carol);
387 env.
trust(BTC(1000), alice, bob, carol);
388 env.
trust(EUR(1000), alice, bob, carol);
390 env(
pay(gw, alice, BTC(60)));
391 env(
pay(gw, bob, USD(50)));
392 env(
pay(gw, bob, EUR(50)));
394 env(offer(bob, BTC(50), USD(50)));
395 env(offer(bob, BTC(60), EUR(50)));
396 env(offer(bob, EUR(50), USD(50)));
399 env(
pay(bob, gw, EUR(50)));
400 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
401 BEAST_EXPECT(
isOffer(env, bob, BTC(60), EUR(50)));
402 BEAST_EXPECT(
isOffer(env, bob, EUR(50), USD(50)));
404 env(
pay(alice, carol, USD(50)),
415 BEAST_EXPECT(!
isOffer(env, bob, BTC(50), USD(50)));
417 BEAST_EXPECT(!
isOffer(env, bob, BTC(60), EUR(50)));
419 BEAST_EXPECT(
isOffer(env, bob, EUR(50), USD(50)));
430 Env env(*
this, features);
432 env.
fund(
XRP(10000), alice, bob, carol, gw);
433 env.
trust(USD(1000), alice, bob, carol);
434 env.
trust(BTC(1000), alice, bob, carol);
435 env.
trust(EUR(1000), alice, bob, carol);
437 env(
pay(gw, alice, BTC(60)));
438 env(
pay(gw, bob, USD(50)));
439 env(
pay(gw, bob, EUR(50)));
441 env(offer(bob, BTC(50), USD(50)));
442 env(offer(bob, BTC(60), EUR(50)));
443 env(offer(bob, EUR(50), USD(50)));
446 env(
pay(bob, gw, EUR(50)));
447 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
448 BEAST_EXPECT(
isOffer(env, bob, BTC(60), EUR(50)));
451 auto const flowResult = [&] {
487 BEAST_EXPECT(flowResult.removableOffers.size() == 1);
490 if (flowResult.removableOffers.empty())
493 for (
auto const& o : flowResult.removableOffers)
501 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
503 BEAST_EXPECT(!
isOffer(env, bob, BTC(60), EUR(50)));
514 Env env(*
this, features);
515 env.
fund(
XRP(10000), alice, bob, carol, gw);
516 env.
trust(USD(1000), alice, bob, carol);
517 env.
trust(EUR(1000), alice, bob, carol);
519 env(
pay(gw, alice, USD(1000)));
520 env(
pay(gw, bob, EUR(1000)));
525 env(
pay(alice, carol, EUR(1)),
539 testcase(
"Transfer Rate");
543 auto const gw =
Account(
"gateway");
544 auto const USD = gw[
"USD"];
545 auto const BTC = gw[
"BTC"];
546 auto const EUR = gw[
"EUR"];
554 Env env(*
this, features);
556 env.
fund(
XRP(10000), alice, bob, carol, gw);
558 env.
trust(USD(1000), alice, bob, carol);
559 env(
pay(gw, alice, USD(50)));
561 env(
pay(alice, bob, USD(40)),
sendmax(USD(50)));
566 Env env(*
this, features);
568 env.
fund(
XRP(10000), alice, bob, carol, gw);
570 env.
trust(USD(1000), alice, bob, carol);
571 env(
pay(gw, alice, USD(50)));
573 env(
pay(alice, gw, USD(40)),
sendmax(USD(40)));
578 Env env(*
this, features);
580 env.
fund(
XRP(10000), alice, bob, carol, gw);
582 env.
trust(USD(1000), alice, bob, carol);
583 env(
pay(gw, bob, USD(65)));
585 env(offer(bob,
XRP(50), USD(50)));
596 Env env(*
this, features);
598 env.
fund(
XRP(10000), alice, bob, carol, gw);
600 env.
trust(USD(1000), alice, bob, carol);
601 env.
trust(EUR(1000), alice, bob, carol);
602 env(
pay(gw, bob, USD(50)));
603 env(
pay(gw, bob, EUR(50)));
605 env(offer(bob,
XRP(50), USD(50)));
606 env(offer(bob, USD(50), EUR(50)));
619 Env env(*
this, features);
620 auto const USDA = alice[
"USD"];
621 auto const USDB = bob[
"USD"];
623 env.
fund(
XRP(10000), alice, bob, carol, gw);
625 env.
trust(USD(1000), alice, bob, carol);
626 env.
trust(USDA(1000), bob);
627 env.
trust(USDB(1000), gw);
628 env(
pay(gw, bob, USD(50)));
640 Env env(*
this, features);
641 auto const USDA = alice[
"USD"];
642 auto const USDB = bob[
"USD"];
645 env.
fund(
XRP(10000), alice, bob, carol, dan, gw);
647 env.
trust(USD(1000), alice, bob, carol, dan);
648 env.
trust(EUR(1000), carol, dan);
649 env.
trust(USDA(1000), bob);
650 env.
trust(USDB(1000), gw);
651 env(
pay(gw, bob, USD(50)));
652 env(
pay(gw, dan, EUR(100)));
653 env(offer(dan, USD(100), EUR(100)));
656 env(
pay(alice, carol, EUR(50)),
670 Env env(*
this, features);
672 env.
fund(
XRP(10000), alice, bob, gw);
674 env.
trust(USD(1000), alice, bob);
675 env(offer(gw,
XRP(100), USD(100)));
684 Env env(*
this, features);
686 env.
fund(
XRP(10000), alice, bob, gw);
688 env.
trust(USD(1000), alice, bob);
689 env(offer(gw,
XRP(125), USD(125)));
700 testcase(
"falseDryChanges");
704 auto const gw =
Account(
"gateway");
705 auto const USD = gw[
"USD"];
706 auto const EUR = gw[
"EUR"];
711 Env env(*
this, features);
713 env.
fund(
XRP(10000), alice, carol, gw);
715 env.
trust(USD(1000), alice, bob, carol);
716 env.
trust(EUR(1000), alice, bob, carol);
718 env(
pay(gw, alice, EUR(50)));
719 env(
pay(gw, bob, USD(50)));
728 env(offer(bob, EUR(50),
XRP(50)));
729 env(offer(bob,
XRP(50), USD(50)));
731 env(
pay(alice, carol, USD(1000000)),
737 BEAST_EXPECT(carolUSD > USD(0) && carolUSD < USD(50));
747 testcase(
"limitQuality");
750 auto const gw =
Account(
"gateway");
751 auto const USD = gw[
"USD"];
759 env.
fund(
XRP(10000), alice, bob, carol, gw);
761 env.
trust(USD(100), alice, bob, carol);
762 env(
pay(gw, bob, USD(100)));
763 env(offer(bob,
XRP(50), USD(50)));
764 env(offer(bob,
XRP(100), USD(50)));
766 env(
pay(alice, carol, USD(100)),
780 return env.
current()->fees().accountReserve(count);
792 if (sle->getType() == ltOFFER)
793 result.push_back(sle);
801 testcase(
"Self-payment 1");
810 auto const gw1 =
Account(
"gw1");
811 auto const gw2 =
Account(
"gw2");
812 auto const alice =
Account(
"alice");
813 auto const USD = gw1[
"USD"];
814 auto const EUR = gw2[
"EUR"];
816 Env env(*
this, features);
818 env.
fund(
XRP(1000000), gw1, gw2);
822 auto const f = env.
current()->fees().base;
827 env(
trust(alice, USD(2000)));
828 env(
trust(alice, EUR(2000)));
831 env(
pay(gw1, alice, USD(1)));
832 env(
pay(gw2, alice, EUR(1000)));
835 env(offer(alice, USD(500), EUR(600)));
843 BEAST_EXPECT(aliceOffers.size() == 1);
844 for (
auto const& offerPtr : aliceOffers)
846 auto const offer = *offerPtr;
852 env(
pay(alice, alice, EUR(600)),
861 BEAST_EXPECT(aliceOffers.size() == 1);
862 for (
auto const& offerPtr : aliceOffers)
864 auto const offer = *offerPtr;
874 testcase(
"Self-payment 2");
881 auto const gw1 =
Account(
"gw1");
882 auto const gw2 =
Account(
"gw2");
883 auto const alice =
Account(
"alice");
884 auto const USD = gw1[
"USD"];
885 auto const EUR = gw2[
"EUR"];
887 Env env(*
this, features);
889 env.
fund(
XRP(1000000), gw1, gw2);
893 auto const f = env.
current()->fees().base;
898 env(
trust(alice, USD(506)));
899 env(
trust(alice, EUR(606)));
902 env(
pay(gw1, alice, USD(500)));
903 env(
pay(gw2, alice, EUR(600)));
906 env(offer(alice, USD(500), EUR(600)));
914 BEAST_EXPECT(aliceOffers.size() == 1);
915 for (
auto const& offerPtr : aliceOffers)
917 auto const offer = *offerPtr;
923 env(
pay(alice, alice, EUR(60)),
932 BEAST_EXPECT(aliceOffers.size() == 1);
933 for (
auto const& offerPtr : aliceOffers)
935 auto const offer = *offerPtr;
949 testcase(
"Self funded XRPEndpoint");
953 Env env(*
this, features);
955 auto const alice =
Account(
"alice");
957 auto const USD = gw[
"USD"];
959 env.
fund(
XRP(10000), alice, gw);
960 env(
trust(alice, USD(20)));
961 env(
pay(gw, alice, USD(10)));
962 env(offer(alice,
XRP(50000), USD(10)));
966 auto const toSend = consumeOffer ? USD(10) : USD(9);
967 env(
pay(alice, alice, toSend),
976 testcase(
"Unfunded Offer");
981 Env env(*
this, features);
983 auto const alice =
Account(
"alice");
984 auto const bob =
Account(
"bob");
986 auto const USD = gw[
"USD"];
988 env.
fund(
XRP(100000), alice, bob, gw);
989 env(
trust(bob, USD(20)));
1006 env(offer(gw,
drops(9000000000), tinyAmt3));
1007 env(
pay(alice, bob, tinyAmt1),
1012 BEAST_EXPECT(!
isOffer(env, gw,
XRP(0), USD(0)));
1016 Env env(*
this, features);
1018 auto const alice =
Account(
"alice");
1019 auto const bob =
Account(
"bob");
1020 auto const gw =
Account(
"gw");
1021 auto const USD = gw[
"USD"];
1023 env.
fund(
XRP(100000), alice, bob, gw);
1024 env(
trust(alice, USD(20)));
1041 env(
pay(gw, alice, tinyAmt1));
1043 env(offer(gw, tinyAmt3,
drops(9000000000)));
1044 env(
pay(alice, bob,
drops(9000000000)),
1049 BEAST_EXPECT(!
isOffer(env, gw, USD(0),
XRP(0)));
1056 testcase(
"ReexecuteDirectStep");
1058 using namespace jtx;
1059 Env env(*
this, features);
1061 auto const alice =
Account(
"alice");
1062 auto const bob =
Account(
"bob");
1063 auto const gw =
Account(
"gw");
1064 auto const USD = gw[
"USD"];
1065 auto const usdC = USD.currency;
1067 env.
fund(
XRP(10000), alice, bob, gw);
1069 env(
trust(alice, USD(100)));
1109 env(
pay(alice, bob,
XRP(10000)),
1118 testcase(
"ripd1443");
1120 using namespace jtx;
1122 auto const alice =
Account(
"alice");
1123 auto const bob =
Account(
"bob");
1124 auto const carol =
Account(
"carol");
1125 auto const gw =
Account(
"gw");
1128 env.
trust(gw[
"USD"](10000), alice, carol);
1130 env.
trust(gw[
"USD"](10000), bob);
1135 env(
pay(gw, alice, gw[
"USD"](1000)));
1138 env(offer(alice, bob[
"USD"](1000),
XRP(1)));
1141 env(
pay(alice, alice,
XRP(1)),
1148 env.
trust(bob[
"USD"](10000), alice);
1149 env(
pay(bob, alice, bob[
"USD"](1000)));
1151 env(offer(alice,
XRP(1000), bob[
"USD"](1000)));
1154 env(
pay(carol, carol, gw[
"USD"](1000)),
1155 path(~bob[
"USD"], gw),
1167 testcase(
"ripd1449");
1169 using namespace jtx;
1176 auto const alice =
Account(
"alice");
1177 auto const bob =
Account(
"bob");
1178 auto const carol =
Account(
"carol");
1179 auto const gw =
Account(
"gw");
1180 auto const USD = gw[
"USD"];
1182 env.
fund(
XRP(100000000), alice, bob, carol, gw);
1184 env.
trust(USD(10000), alice, carol);
1186 env.
trust(USD(10000), bob);
1187 env.
trust(bob[
"USD"](10000), carol);
1190 env(
pay(bob, carol, bob[
"USD"](1000)));
1191 env(
pay(gw, bob, USD(1000)));
1194 env(offer(carol,
XRP(1), bob[
"USD"](1000)));
1197 env(
pay(alice, alice, USD(1000)),
1198 path(~bob[
"USD"], bob, gw),
1211 testcase(
"Self crossing low quality offer");
1213 using namespace jtx;
1215 Env env(*
this, features);
1217 auto const ann =
Account(
"ann");
1218 auto const gw =
Account(
"gateway");
1219 auto const CTB = gw[
"CTB"];
1226 env(
rate(gw, 1.002));
1227 env(
trust(ann, CTB(10)));
1230 env(
pay(gw, ann, CTB(2.856)));
1233 env(offer(ann,
drops(365611702030), CTB(5.713)));
1237 env(
pay(ann, ann, CTB(0.687)),
1245 testcase(
"Empty Strand");
1246 using namespace jtx;
1248 auto const alice =
Account(
"alice");
1250 Env env(*
this, features);
1254 env(
pay(alice, alice, alice[
"USD"](100)),
1255 path(~alice[
"USD"]),
1262 testcase(
"Circular XRP");
1264 using namespace jtx;
1265 auto const alice =
Account(
"alice");
1266 auto const bob =
Account(
"bob");
1267 auto const gw =
Account(
"gw");
1268 auto const USD = gw[
"USD"];
1269 auto const EUR = gw[
"EUR"];
1271 for (
auto const withFix : {
true,
false})
1280 Env env(*
this, feats);
1281 env.
fund(
XRP(10000), alice, bob, gw);
1282 env.
trust(USD(1000), alice, bob);
1283 env.
trust(EUR(1000), alice, bob);
1284 env(
pay(gw, alice, USD(100)));
1285 env(
pay(gw, alice, EUR(100)));
1293 TER const expectedTer =
1295 env(
pay(alice, bob, EUR(1)),
1306 env.
fund(
XRP(10000), alice, bob, gw);
1307 env.
trust(USD(1000), alice, bob);
1308 env.
trust(EUR(1000), alice, bob);
1309 env(
pay(gw, alice, USD(100)));
1310 env(
pay(gw, alice, EUR(100)));
1317 env(
pay(alice, bob,
XRP(1)),
1326 auto const JPY = gw[
"JPY"];
1328 env.
fund(
XRP(10000), alice, bob, gw);
1330 env.
trust(USD(1000), alice, bob);
1331 env.
trust(EUR(1000), alice, bob);
1332 env.
trust(JPY(1000), alice, bob);
1334 env(
pay(gw, alice, USD(100)));
1335 env(
pay(gw, alice, EUR(100)));
1336 env(
pay(gw, alice, JPY(100)));
1345 env(
pay(alice, bob, JPY(1)),
1356 testcase(
"Payment with ticket");
1357 using namespace jtx;
1359 auto const alice =
Account(
"alice");
1360 auto const bob =
Account(
"bob");
1362 Env env(*
this, features);
1369 env(ticket::create(alice, 1));
1381 using namespace jtx;
1409 using namespace jtx;
1422 using namespace jtx;