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(40), 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(40), 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(40), 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(60)));
439 env(
pay(gw, bob, EUR(50)));
440 env(
pay(gw, carol, EUR(1)));
442 env(offer(bob, BTC(50), USD(50)));
443 env(offer(bob, BTC(60), EUR(50)));
444 env(offer(carol, BTC(1000), EUR(1)));
445 env(offer(bob, EUR(50), USD(50)));
448 env(
pay(bob, gw, EUR(50)));
449 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
450 BEAST_EXPECT(
isOffer(env, bob, BTC(60), EUR(50)));
451 BEAST_EXPECT(
isOffer(env, carol, BTC(1000), EUR(1)));
454 auto const flowResult = [&] {
490 BEAST_EXPECT(flowResult.removableOffers.size() == 1);
493 if (flowResult.removableOffers.empty())
496 for (
auto const& o : flowResult.removableOffers)
504 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
505 BEAST_EXPECT(
isOffer(env, carol, BTC(1000), EUR(1)));
507 BEAST_EXPECT(!
isOffer(env, bob, BTC(60), EUR(50)));
518 Env env(*
this, features);
519 env.
fund(
XRP(10000), alice, bob, carol, gw);
520 env.
trust(USD(1000), alice, bob, carol);
521 env.
trust(EUR(1000), alice, bob, carol);
523 env(
pay(gw, alice, USD(1000)));
524 env(
pay(gw, bob, EUR(1000)));
529 env(
pay(alice, carol, EUR(1)),
543 testcase(
"Transfer Rate");
547 auto const gw =
Account(
"gateway");
548 auto const USD = gw[
"USD"];
549 auto const BTC = gw[
"BTC"];
550 auto const EUR = gw[
"EUR"];
558 Env env(*
this, features);
560 env.
fund(
XRP(10000), alice, bob, carol, gw);
562 env.
trust(USD(1000), alice, bob, carol);
563 env(
pay(gw, alice, USD(50)));
565 env(
pay(alice, bob, USD(40)),
sendmax(USD(50)));
570 Env env(*
this, features);
572 env.
fund(
XRP(10000), alice, bob, carol, gw);
574 env.
trust(USD(1000), alice, bob, carol);
575 env(
pay(gw, alice, USD(50)));
577 env(
pay(alice, gw, USD(40)),
sendmax(USD(40)));
582 Env env(*
this, features);
584 env.
fund(
XRP(10000), alice, bob, carol, gw);
586 env.
trust(USD(1000), alice, bob, carol);
587 env(
pay(gw, bob, USD(65)));
589 env(offer(bob,
XRP(50), USD(50)));
600 Env env(*
this, features);
602 env.
fund(
XRP(10000), alice, bob, carol, gw);
604 env.
trust(USD(1000), alice, bob, carol);
605 env.
trust(EUR(1000), alice, bob, carol);
606 env(
pay(gw, bob, USD(50)));
607 env(
pay(gw, bob, EUR(50)));
609 env(offer(bob,
XRP(50), USD(50)));
610 env(offer(bob, USD(50), EUR(50)));
623 Env env(*
this, features);
624 auto const USDA = alice[
"USD"];
625 auto const USDB = bob[
"USD"];
627 env.
fund(
XRP(10000), alice, bob, carol, gw);
629 env.
trust(USD(1000), alice, bob, carol);
630 env.
trust(USDA(1000), bob);
631 env.
trust(USDB(1000), gw);
632 env(
pay(gw, bob, USD(50)));
644 Env env(*
this, features);
645 auto const USDA = alice[
"USD"];
646 auto const USDB = bob[
"USD"];
649 env.
fund(
XRP(10000), alice, bob, carol, dan, gw);
651 env.
trust(USD(1000), alice, bob, carol, dan);
652 env.
trust(EUR(1000), carol, dan);
653 env.
trust(USDA(1000), bob);
654 env.
trust(USDB(1000), gw);
655 env(
pay(gw, bob, USD(50)));
656 env(
pay(gw, dan, EUR(100)));
657 env(offer(dan, USD(100), EUR(100)));
660 env(
pay(alice, carol, EUR(50)),
674 Env env(*
this, features);
676 env.
fund(
XRP(10000), alice, bob, gw);
678 env.
trust(USD(1000), alice, bob);
679 env(offer(gw,
XRP(100), USD(100)));
688 Env env(*
this, features);
690 env.
fund(
XRP(10000), alice, bob, gw);
692 env.
trust(USD(1000), alice, bob);
693 env(offer(gw,
XRP(125), USD(125)));
704 testcase(
"falseDryChanges");
708 auto const gw =
Account(
"gateway");
709 auto const USD = gw[
"USD"];
710 auto const EUR = gw[
"EUR"];
715 Env env(*
this, features);
717 env.
fund(
XRP(10000), alice, carol, gw);
719 env.
trust(USD(1000), alice, bob, carol);
720 env.
trust(EUR(1000), alice, bob, carol);
722 env(
pay(gw, alice, EUR(50)));
723 env(
pay(gw, bob, USD(50)));
732 env(offer(bob, EUR(50),
XRP(50)));
733 env(offer(bob,
XRP(50), USD(50)));
735 env(
pay(alice, carol, USD(1000000)),
741 BEAST_EXPECT(carolUSD > USD(0) && carolUSD < USD(50));
751 testcase(
"limitQuality");
754 auto const gw =
Account(
"gateway");
755 auto const USD = gw[
"USD"];
763 env.
fund(
XRP(10000), alice, bob, carol, gw);
765 env.
trust(USD(100), alice, bob, carol);
766 env(
pay(gw, bob, USD(100)));
767 env(offer(bob,
XRP(50), USD(50)));
768 env(offer(bob,
XRP(100), USD(50)));
770 env(
pay(alice, carol, USD(100)),
784 return env.
current()->fees().accountReserve(count);
796 if (sle->getType() == ltOFFER)
797 result.push_back(sle);
805 testcase(
"Self-payment 1");
814 auto const gw1 =
Account(
"gw1");
815 auto const gw2 =
Account(
"gw2");
816 auto const alice =
Account(
"alice");
817 auto const USD = gw1[
"USD"];
818 auto const EUR = gw2[
"EUR"];
820 Env env(*
this, features);
822 env.
fund(
XRP(1000000), gw1, gw2);
826 auto const f = env.
current()->fees().base;
831 env(
trust(alice, USD(2000)));
832 env(
trust(alice, EUR(2000)));
835 env(
pay(gw1, alice, USD(1)));
836 env(
pay(gw2, alice, EUR(1000)));
839 env(offer(alice, USD(500), EUR(600)));
847 BEAST_EXPECT(aliceOffers.size() == 1);
848 for (
auto const& offerPtr : aliceOffers)
850 auto const offer = *offerPtr;
856 env(
pay(alice, alice, EUR(600)),
865 BEAST_EXPECT(aliceOffers.size() == 1);
866 for (
auto const& offerPtr : aliceOffers)
868 auto const offer = *offerPtr;
878 testcase(
"Self-payment 2");
885 auto const gw1 =
Account(
"gw1");
886 auto const gw2 =
Account(
"gw2");
887 auto const alice =
Account(
"alice");
888 auto const USD = gw1[
"USD"];
889 auto const EUR = gw2[
"EUR"];
891 Env env(*
this, features);
893 env.
fund(
XRP(1000000), gw1, gw2);
897 auto const f = env.
current()->fees().base;
902 env(
trust(alice, USD(506)));
903 env(
trust(alice, EUR(606)));
906 env(
pay(gw1, alice, USD(500)));
907 env(
pay(gw2, alice, EUR(600)));
910 env(offer(alice, USD(500), EUR(600)));
918 BEAST_EXPECT(aliceOffers.size() == 1);
919 for (
auto const& offerPtr : aliceOffers)
921 auto const offer = *offerPtr;
927 env(
pay(alice, alice, EUR(60)),
936 BEAST_EXPECT(aliceOffers.size() == 1);
937 for (
auto const& offerPtr : aliceOffers)
939 auto const offer = *offerPtr;
953 testcase(
"Self funded XRPEndpoint");
957 Env env(*
this, features);
959 auto const alice =
Account(
"alice");
961 auto const USD = gw[
"USD"];
963 env.
fund(
XRP(10000), alice, gw);
964 env(
trust(alice, USD(20)));
965 env(
pay(gw, alice, USD(10)));
966 env(offer(alice,
XRP(50000), USD(10)));
970 auto const toSend = consumeOffer ? USD(10) : USD(9);
971 env(
pay(alice, alice, toSend),
980 testcase(
"Unfunded Offer");
985 Env env(*
this, features);
987 auto const alice =
Account(
"alice");
988 auto const bob =
Account(
"bob");
990 auto const USD = gw[
"USD"];
992 env.
fund(
XRP(100000), alice, bob, gw);
993 env(
trust(bob, USD(20)));
1010 env(offer(gw,
drops(9000000000), tinyAmt3));
1011 env(
pay(alice, bob, tinyAmt1),
1016 BEAST_EXPECT(!
isOffer(env, gw,
XRP(0), USD(0)));
1020 Env env(*
this, features);
1022 auto const alice =
Account(
"alice");
1023 auto const bob =
Account(
"bob");
1024 auto const gw =
Account(
"gw");
1025 auto const USD = gw[
"USD"];
1027 env.
fund(
XRP(100000), alice, bob, gw);
1028 env(
trust(alice, USD(20)));
1045 env(
pay(gw, alice, tinyAmt1));
1047 env(offer(gw, tinyAmt3,
drops(9000000000)));
1048 env(
pay(alice, bob,
drops(9000000000)),
1053 BEAST_EXPECT(!
isOffer(env, gw, USD(0),
XRP(0)));
1060 testcase(
"ReexecuteDirectStep");
1062 using namespace jtx;
1063 Env env(*
this, features);
1065 auto const alice =
Account(
"alice");
1066 auto const bob =
Account(
"bob");
1067 auto const gw =
Account(
"gw");
1068 auto const USD = gw[
"USD"];
1069 auto const usdC = USD.currency;
1071 env.
fund(
XRP(10000), alice, bob, gw);
1073 env(
trust(alice, USD(100)));
1113 env(
pay(alice, bob,
XRP(10000)),
1122 testcase(
"ripd1443");
1124 using namespace jtx;
1126 auto const alice =
Account(
"alice");
1127 auto const bob =
Account(
"bob");
1128 auto const carol =
Account(
"carol");
1129 auto const gw =
Account(
"gw");
1132 env.
trust(gw[
"USD"](10000), alice, carol);
1134 env.
trust(gw[
"USD"](10000), bob);
1139 env(
pay(gw, alice, gw[
"USD"](1000)));
1142 env(offer(alice, bob[
"USD"](1000),
XRP(1)));
1145 env(
pay(alice, alice,
XRP(1)),
1152 env.
trust(bob[
"USD"](10000), alice);
1153 env(
pay(bob, alice, bob[
"USD"](1000)));
1155 env(offer(alice,
XRP(1000), bob[
"USD"](1000)));
1158 env(
pay(carol, carol, gw[
"USD"](1000)),
1159 path(~bob[
"USD"], gw),
1171 testcase(
"ripd1449");
1173 using namespace jtx;
1180 auto const alice =
Account(
"alice");
1181 auto const bob =
Account(
"bob");
1182 auto const carol =
Account(
"carol");
1183 auto const gw =
Account(
"gw");
1184 auto const USD = gw[
"USD"];
1186 env.
fund(
XRP(100000000), alice, bob, carol, gw);
1188 env.
trust(USD(10000), alice, carol);
1190 env.
trust(USD(10000), bob);
1191 env.
trust(bob[
"USD"](10000), carol);
1194 env(
pay(bob, carol, bob[
"USD"](1000)));
1195 env(
pay(gw, bob, USD(1000)));
1198 env(offer(carol,
XRP(1), bob[
"USD"](1000)));
1201 env(
pay(alice, alice, USD(1000)),
1202 path(~bob[
"USD"], bob, gw),
1215 testcase(
"Self crossing low quality offer");
1217 using namespace jtx;
1219 Env env(*
this, features);
1221 auto const ann =
Account(
"ann");
1222 auto const gw =
Account(
"gateway");
1223 auto const CTB = gw[
"CTB"];
1230 env(
rate(gw, 1.002));
1231 env(
trust(ann, CTB(10)));
1234 env(
pay(gw, ann, CTB(2.856)));
1237 env(offer(ann,
drops(365611702030), CTB(5.713)));
1241 env(
pay(ann, ann, CTB(0.687)),
1249 testcase(
"Empty Strand");
1250 using namespace jtx;
1252 auto const alice =
Account(
"alice");
1254 Env env(*
this, features);
1258 env(
pay(alice, alice, alice[
"USD"](100)),
1259 path(~alice[
"USD"]),
1266 testcase(
"Circular XRP");
1268 using namespace jtx;
1269 auto const alice =
Account(
"alice");
1270 auto const bob =
Account(
"bob");
1271 auto const gw =
Account(
"gw");
1272 auto const USD = gw[
"USD"];
1273 auto const EUR = gw[
"EUR"];
1275 for (
auto const withFix : {
true,
false})
1284 Env env(*
this, feats);
1285 env.
fund(
XRP(10000), alice, bob, gw);
1286 env.
trust(USD(1000), alice, bob);
1287 env.
trust(EUR(1000), alice, bob);
1288 env(
pay(gw, alice, USD(100)));
1289 env(
pay(gw, alice, EUR(100)));
1297 TER const expectedTer =
1299 env(
pay(alice, bob, EUR(1)),
1310 env.
fund(
XRP(10000), alice, bob, gw);
1311 env.
trust(USD(1000), alice, bob);
1312 env.
trust(EUR(1000), alice, bob);
1313 env(
pay(gw, alice, USD(100)));
1314 env(
pay(gw, alice, EUR(100)));
1321 env(
pay(alice, bob,
XRP(1)),
1330 auto const JPY = gw[
"JPY"];
1332 env.
fund(
XRP(10000), alice, bob, gw);
1334 env.
trust(USD(1000), alice, bob);
1335 env.
trust(EUR(1000), alice, bob);
1336 env.
trust(JPY(1000), alice, bob);
1338 env(
pay(gw, alice, USD(100)));
1339 env(
pay(gw, alice, EUR(100)));
1340 env(
pay(gw, alice, JPY(100)));
1349 env(
pay(alice, bob, JPY(1)),
1360 testcase(
"Payment with ticket");
1361 using namespace jtx;
1363 auto const alice =
Account(
"alice");
1364 auto const bob =
Account(
"bob");
1366 Env env(*
this, features);
1372 env(ticket::create(alice, 1));
1384 using namespace jtx;
1412 using namespace jtx;
1425 using namespace jtx;