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");
57 testcase(
"Direct Step");
60 auto const alice =
Account(
"alice");
61 auto const bob =
Account(
"bob");
62 auto const carol =
Account(
"carol");
63 auto const dan =
Account(
"dan");
64 auto const erin =
Account(
"erin");
65 auto const USDA = alice[
"USD"];
66 auto const USDB = bob[
"USD"];
67 auto const USDC = carol[
"USD"];
68 auto const USDD = dan[
"USD"];
70 auto const USD = gw[
"USD"];
73 Env env(*
this, features);
75 env.
fund(
XRP(10000), alice, bob, gw);
76 env.
trust(USD(1000), alice, bob);
77 env(pay(gw, alice, USD(100)));
78 env(pay(alice, bob, USD(10)),
paths(USD));
83 Env env(*
this, features);
85 env.
fund(
XRP(10000), alice, bob);
86 env(pay(alice, bob,
XRP(100)));
92 Env env(*
this, features);
94 env.
fund(
XRP(10000), alice, bob, gw);
95 env.
trust(USD(1000), alice, bob);
96 env(pay(gw, alice, USD(100)));
99 env(pay(alice, bob, USD(110)),
106 Env env(*
this, features);
108 env.
fund(
XRP(10000), alice, bob, carol, dan);
109 env.
trust(USDA(10), bob);
110 env.
trust(USDB(10), carol);
111 env.
trust(USDC(10), dan);
112 env(pay(alice, dan, USDC(10)),
paths(USDA));
121 Env env(*
this, features);
123 env.
fund(
XRP(10000), alice, bob, carol, dan);
124 env.
trust(USDA(10), bob);
125 env.
trust(USDB(10), alice, carol);
126 env.
trust(USDC(10), dan);
130 env(pay(bob, alice, USDB(6)));
131 env(pay(alice, dan, USDC(5)),
141 Env env(*
this, features);
143 env.
fund(
XRP(10000), alice, bob, carol, dan);
144 env.
trust(USDA(10), bob);
145 env.
trust(USDB(10), alice, carol);
146 env.
trust(USDC(10), dan);
149 env(pay(alice, dan, USDC(5)),
159 Env env(*
this, features);
161 env.
fund(
XRP(10000), alice, bob, carol, dan, erin);
162 env.
trust(USDA(10), bob, carol);
163 env.
trust(USDB(10), dan);
164 env.
trust(USDC(10), alice, dan);
165 env.
trust(USDD(20), erin);
167 env(
rate(carol, 1.1));
170 env(pay(carol, alice, USDC(10)));
171 env(pay(alice, erin, USDD(5)),
182 Env env(*
this, features);
184 env.
fund(
XRP(10000), alice, bob, carol);
185 env.
trust(USDA(10), bob);
186 env.
trust(USDB(10), carol);
188 env(pay(alice, carol, USDB(5)),
194 env(pay(alice, carol, USDB(5)),
204 testcase(
"Line Quality");
207 auto const alice =
Account(
"alice");
208 auto const bob =
Account(
"bob");
209 auto const carol =
Account(
"carol");
210 auto const dan =
Account(
"dan");
211 auto const USDA = alice[
"USD"];
212 auto const USDB = bob[
"USD"];
213 auto const USDC = carol[
"USD"];
214 auto const USDD = dan[
"USD"];
217 for (
auto bobDanQIn : {80, 100, 120})
218 for (
auto bobAliceQOut : {80, 100, 120})
220 Env env(*
this, features);
221 env.
fund(
XRP(10000), alice, bob, carol, dan);
224 env(trust(carol, USDA(100)));
226 env(pay(alice, bob, USDA(100)));
228 env(pay(dan, carol, USDA(10)),
233 if (bobAliceQOut > bobDanQIn)
236 USDD(10.0 *
double(bobAliceQOut) /
double(bobDanQIn))));
243 for (
auto carolAliceQIn : {80, 100, 120})
245 Env env(*
this, features);
246 env.
fund(
XRP(10000), alice, bob, carol);
247 env(trust(bob, USDA(10)));
250 env(pay(alice, bob, USDA(10)));
252 env(pay(bob, carol, USDA(5)),
sendmax(USDA(10)));
253 auto const effectiveQ =
254 carolAliceQIn > 100 ? 1.0 : carolAliceQIn / 100.0;
259 for (
auto bobAliceQOut : {80, 100, 120})
261 Env env(*
this, features);
262 env.
fund(
XRP(10000), alice, bob, carol);
264 env(trust(carol, USDA(10)));
266 env(pay(alice, bob, USDA(10)));
268 env(pay(bob, carol, USDA(5)),
sendmax(USDA(5)));
277 testcase(
"Book Step");
281 auto const gw =
Account(
"gateway");
282 auto const USD = gw[
"USD"];
283 auto const BTC = gw[
"BTC"];
284 auto const EUR = gw[
"EUR"];
291 Env env(*
this, features);
293 env.
fund(
XRP(10000), alice, bob, carol, gw);
294 env.
trust(USD(1000), alice, bob, carol);
295 env.
trust(BTC(1000), alice, bob, carol);
297 env(pay(gw, alice, BTC(50)));
298 env(pay(gw, bob, USD(50)));
300 env(offer(bob, BTC(50), USD(50)));
302 env(pay(alice, carol, USD(50)),
path(~USD),
sendmax(BTC(50)));
308 BEAST_EXPECT(!
isOffer(env, bob, BTC(50), USD(50)));
312 Env env(*
this, features);
314 env.
fund(
XRP(10000), alice, bob, carol, gw);
315 env.
trust(USD(1000), alice, bob, carol);
316 env.
trust(BTC(1000), alice, bob, carol);
318 env(pay(gw, alice, BTC(50)));
319 env(pay(gw, bob, USD(50)));
321 env(offer(bob, BTC(50),
XRP(50)));
322 env(offer(bob,
XRP(50), USD(50)));
324 env(pay(alice, carol, USD(50)),
path(~
XRP, ~USD),
sendmax(BTC(50)));
330 BEAST_EXPECT(!
isOffer(env, bob,
XRP(50), USD(50)));
331 BEAST_EXPECT(!
isOffer(env, bob, BTC(50),
XRP(50)));
335 Env env(*
this, features);
337 env.
fund(
XRP(10000), alice, bob, carol, gw);
338 env.
trust(USD(1000), alice, bob, carol);
339 env.
trust(BTC(1000), alice, bob, carol);
341 env(pay(gw, bob, USD(50)));
343 env(offer(bob,
XRP(50), USD(50)));
351 BEAST_EXPECT(!
isOffer(env, bob,
XRP(50), USD(50)));
355 Env env(*
this, features);
357 env.
fund(
XRP(10000), alice, bob, carol, gw);
358 env.
trust(USD(1000), alice, bob, carol);
359 env.
trust(BTC(1000), alice, bob, carol);
361 env(pay(gw, alice, USD(50)));
363 env(offer(bob, USD(50),
XRP(50)));
371 BEAST_EXPECT(!
isOffer(env, bob, USD(50),
XRP(50)));
375 Env env(*
this, features);
377 env.
fund(
XRP(10000), alice, bob, carol, gw);
378 env.
trust(USD(1000), alice, bob, carol);
379 env.
trust(BTC(1000), alice, bob, carol);
380 env.
trust(EUR(1000), alice, bob, carol);
382 env(pay(gw, alice, BTC(60)));
383 env(pay(gw, bob, USD(50)));
384 env(pay(gw, bob, EUR(50)));
386 env(offer(bob, BTC(50), USD(50)));
387 env(offer(bob, BTC(40), EUR(50)));
388 env(offer(bob, EUR(50), USD(50)));
391 env(pay(bob, gw, EUR(50)));
392 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
393 BEAST_EXPECT(
isOffer(env, bob, BTC(40), EUR(50)));
394 BEAST_EXPECT(
isOffer(env, bob, EUR(50), USD(50)));
396 env(pay(alice, carol, USD(50)),
407 BEAST_EXPECT(!
isOffer(env, bob, BTC(50), USD(50)));
409 BEAST_EXPECT(!
isOffer(env, bob, BTC(40), EUR(50)));
411 BEAST_EXPECT(
isOffer(env, bob, EUR(50), USD(50)));
422 Env env(*
this, features);
424 env.
fund(
XRP(10000), alice, bob, carol, gw);
425 env.
trust(USD(1000), alice, bob, carol);
426 env.
trust(BTC(1000), alice, bob, carol);
427 env.
trust(EUR(1000), alice, bob, carol);
429 env(pay(gw, alice, BTC(60)));
430 env(pay(gw, bob, USD(60)));
431 env(pay(gw, bob, EUR(50)));
432 env(pay(gw, carol, EUR(1)));
434 env(offer(bob, BTC(50), USD(50)));
435 env(offer(bob, BTC(60), EUR(50)));
436 env(offer(carol, BTC(1000), EUR(1)));
437 env(offer(bob, EUR(50), USD(50)));
440 env(pay(bob, gw, EUR(50)));
441 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
442 BEAST_EXPECT(
isOffer(env, bob, BTC(60), EUR(50)));
443 BEAST_EXPECT(
isOffer(env, carol, BTC(1000), EUR(1)));
446 auto const flowResult = [&] {
482 BEAST_EXPECT(flowResult.removableOffers.size() == 1);
485 if (flowResult.removableOffers.empty())
488 for (
auto const& o : flowResult.removableOffers)
496 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
497 BEAST_EXPECT(
isOffer(env, carol, BTC(1000), EUR(1)));
499 BEAST_EXPECT(!
isOffer(env, bob, BTC(60), EUR(50)));
510 Env env(*
this, features);
511 env.
fund(
XRP(10000), alice, bob, carol, gw);
512 env.
trust(USD(1000), alice, bob, carol);
513 env.
trust(EUR(1000), alice, bob, carol);
515 env(pay(gw, alice, USD(1000)));
516 env(pay(gw, bob, EUR(1000)));
521 env(pay(alice, carol, EUR(1)),
535 testcase(
"Transfer Rate");
539 auto const gw =
Account(
"gateway");
540 auto const USD = gw[
"USD"];
541 auto const BTC = gw[
"BTC"];
542 auto const EUR = gw[
"EUR"];
550 Env env(*
this, features);
552 env.
fund(
XRP(10000), alice, bob, carol, gw);
554 env.
trust(USD(1000), alice, bob, carol);
555 env(pay(gw, alice, USD(50)));
557 env(pay(alice, bob, USD(40)),
sendmax(USD(50)));
562 Env env(*
this, features);
564 env.
fund(
XRP(10000), alice, bob, carol, gw);
566 env.
trust(USD(1000), alice, bob, carol);
567 env(pay(gw, alice, USD(50)));
569 env(pay(alice, gw, USD(40)),
sendmax(USD(40)));
574 Env env(*
this, features);
576 env.
fund(
XRP(10000), alice, bob, carol, gw);
578 env.
trust(USD(1000), alice, bob, carol);
579 env(pay(gw, bob, USD(65)));
581 env(offer(bob,
XRP(50), USD(50)));
592 Env env(*
this, features);
594 env.
fund(
XRP(10000), alice, bob, carol, gw);
596 env.
trust(USD(1000), alice, bob, carol);
597 env.
trust(EUR(1000), alice, bob, carol);
598 env(pay(gw, bob, USD(50)));
599 env(pay(gw, bob, EUR(50)));
601 env(offer(bob,
XRP(50), USD(50)));
602 env(offer(bob, USD(50), EUR(50)));
604 env(pay(alice, carol, EUR(40)),
path(~USD, ~EUR),
sendmax(
XRP(40)));
615 Env env(*
this, features);
616 auto const USDA = alice[
"USD"];
617 auto const USDB = bob[
"USD"];
619 env.
fund(
XRP(10000), alice, bob, carol, gw);
621 env.
trust(USD(1000), alice, bob, carol);
622 env.
trust(USDA(1000), bob);
623 env.
trust(USDB(1000), gw);
624 env(pay(gw, bob, USD(50)));
627 env(pay(alice, carol, USD(50)),
path(bob),
sendmax(USDA(60)));
636 Env env(*
this, features);
637 auto const USDA = alice[
"USD"];
638 auto const USDB = bob[
"USD"];
641 env.
fund(
XRP(10000), alice, bob, carol, dan, gw);
643 env.
trust(USD(1000), alice, bob, carol, dan);
644 env.
trust(EUR(1000), carol, dan);
645 env.
trust(USDA(1000), bob);
646 env.
trust(USDB(1000), gw);
647 env(pay(gw, bob, USD(50)));
648 env(pay(gw, dan, EUR(100)));
649 env(offer(dan, USD(100), EUR(100)));
652 env(pay(alice, carol, EUR(50)),
666 Env env(*
this, features);
668 env.
fund(
XRP(10000), alice, bob, gw);
670 env.
trust(USD(1000), alice, bob);
671 env(offer(gw,
XRP(100), USD(100)));
672 env(pay(alice, bob, USD(100)),
sendmax(
XRP(100)));
680 Env env(*
this, features);
682 env.
fund(
XRP(10000), alice, bob, gw);
684 env.
trust(USD(1000), alice, bob);
685 env(offer(gw,
XRP(125), USD(125)));
686 env(pay(alice, bob, USD(100)),
sendmax(
XRP(200)));
696 testcase(
"falseDryChanges");
700 auto const gw =
Account(
"gateway");
701 auto const USD = gw[
"USD"];
702 auto const EUR = gw[
"EUR"];
707 Env env(*
this, features);
709 env.
fund(
XRP(10000), alice, carol, gw);
711 env.
trust(USD(1000), alice, bob, carol);
712 env.
trust(EUR(1000), alice, bob, carol);
714 env(pay(gw, alice, EUR(50)));
715 env(pay(gw, bob, USD(50)));
724 env(offer(bob, EUR(50),
XRP(50)));
725 env(offer(bob,
XRP(50), USD(50)));
727 env(pay(alice, carol, USD(1000000)),
733 BEAST_EXPECT(carolUSD > USD(0) && carolUSD < USD(50));
743 testcase(
"limitQuality");
746 auto const gw =
Account(
"gateway");
747 auto const USD = gw[
"USD"];
755 env.
fund(
XRP(10000), alice, bob, carol, gw);
757 env.
trust(USD(100), alice, bob, carol);
758 env(pay(gw, bob, USD(100)));
759 env(offer(bob,
XRP(50), USD(50)));
760 env(offer(bob,
XRP(100), USD(50)));
762 env(pay(alice, carol, USD(100)),
776 return env.
current()->fees().accountReserve(count);
788 if (sle->getType() == ltOFFER)
789 result.push_back(sle);
797 testcase(
"Self-payment 1");
806 auto const gw1 =
Account(
"gw1");
807 auto const gw2 =
Account(
"gw2");
808 auto const alice =
Account(
"alice");
809 auto const USD = gw1[
"USD"];
810 auto const EUR = gw2[
"EUR"];
812 Env env(*
this, features);
814 env.
fund(
XRP(1000000), gw1, gw2);
818 auto const f = env.
current()->fees().base;
823 env(trust(alice, USD(2000)));
824 env(trust(alice, EUR(2000)));
827 env(pay(gw1, alice, USD(1)));
828 env(pay(gw2, alice, EUR(1000)));
831 env(offer(alice, USD(500), EUR(600)));
839 BEAST_EXPECT(aliceOffers.size() == 1);
840 for (
auto const& offerPtr : aliceOffers)
842 auto const offer = *offerPtr;
848 env(pay(alice, alice, EUR(600)),
857 BEAST_EXPECT(aliceOffers.size() == 1);
858 for (
auto const& offerPtr : aliceOffers)
860 auto const offer = *offerPtr;
870 testcase(
"Self-payment 2");
877 auto const gw1 =
Account(
"gw1");
878 auto const gw2 =
Account(
"gw2");
879 auto const alice =
Account(
"alice");
880 auto const USD = gw1[
"USD"];
881 auto const EUR = gw2[
"EUR"];
883 Env env(*
this, features);
885 env.
fund(
XRP(1000000), gw1, gw2);
889 auto const f = env.
current()->fees().base;
894 env(trust(alice, USD(506)));
895 env(trust(alice, EUR(606)));
898 env(pay(gw1, alice, USD(500)));
899 env(pay(gw2, alice, EUR(600)));
902 env(offer(alice, USD(500), EUR(600)));
910 BEAST_EXPECT(aliceOffers.size() == 1);
911 for (
auto const& offerPtr : aliceOffers)
913 auto const offer = *offerPtr;
919 env(pay(alice, alice, EUR(60)),
928 BEAST_EXPECT(aliceOffers.size() == 1);
929 for (
auto const& offerPtr : aliceOffers)
931 auto const offer = *offerPtr;
945 testcase(
"Self funded XRPEndpoint");
949 Env env(*
this, features);
951 auto const alice =
Account(
"alice");
953 auto const USD = gw[
"USD"];
955 env.
fund(
XRP(10000), alice, gw);
956 env(trust(alice, USD(20)));
957 env(pay(gw, alice, USD(10)));
958 env(offer(alice,
XRP(50000), USD(10)));
962 auto const toSend = consumeOffer ? USD(10) : USD(9);
963 env(pay(alice, alice, toSend),
972 testcase(
"Unfunded Offer");
977 Env env(*
this, features);
979 auto const alice =
Account(
"alice");
980 auto const bob =
Account(
"bob");
982 auto const USD = gw[
"USD"];
984 env.
fund(
XRP(100000), alice, bob, gw);
985 env(trust(bob, USD(20)));
1002 env(offer(gw,
drops(9000000000), tinyAmt3));
1003 env(pay(alice, bob, tinyAmt1),
1008 BEAST_EXPECT(!
isOffer(env, gw,
XRP(0), USD(0)));
1012 Env env(*
this, features);
1014 auto const alice =
Account(
"alice");
1015 auto const bob =
Account(
"bob");
1016 auto const gw =
Account(
"gw");
1017 auto const USD = gw[
"USD"];
1019 env.
fund(
XRP(100000), alice, bob, gw);
1020 env(trust(alice, USD(20)));
1037 env(pay(gw, alice, tinyAmt1));
1039 env(offer(gw, tinyAmt3,
drops(9000000000)));
1040 env(pay(alice, bob,
drops(9000000000)),
1045 BEAST_EXPECT(!
isOffer(env, gw, USD(0),
XRP(0)));
1052 testcase(
"ReexecuteDirectStep");
1054 using namespace jtx;
1055 Env env(*
this, features);
1057 auto const alice =
Account(
"alice");
1058 auto const bob =
Account(
"bob");
1059 auto const gw =
Account(
"gw");
1060 auto const USD = gw[
"USD"];
1061 auto const usdC = USD.currency;
1063 env.
fund(
XRP(10000), alice, bob, gw);
1065 env(trust(alice, USD(100)));
1105 env(pay(alice, bob,
XRP(10000)),
1114 testcase(
"ripd1443");
1116 using namespace jtx;
1118 auto const alice =
Account(
"alice");
1119 auto const bob =
Account(
"bob");
1120 auto const carol =
Account(
"carol");
1121 auto const gw =
Account(
"gw");
1124 env.
trust(gw[
"USD"](10000), alice, carol);
1126 env.
trust(gw[
"USD"](10000), bob);
1131 env(pay(gw, alice, gw[
"USD"](1000)));
1134 env(offer(alice, bob[
"USD"](1000),
XRP(1)));
1137 env(pay(alice, alice,
XRP(1)),
1144 env.
trust(bob[
"USD"](10000), alice);
1145 env(pay(bob, alice, bob[
"USD"](1000)));
1147 env(offer(alice,
XRP(1000), bob[
"USD"](1000)));
1150 env(pay(carol, carol, gw[
"USD"](1000)),
1151 path(~bob[
"USD"], gw),
1163 testcase(
"ripd1449");
1165 using namespace jtx;
1172 auto const alice =
Account(
"alice");
1173 auto const bob =
Account(
"bob");
1174 auto const carol =
Account(
"carol");
1175 auto const gw =
Account(
"gw");
1176 auto const USD = gw[
"USD"];
1178 env.
fund(
XRP(100000000), alice, bob, carol, gw);
1180 env.
trust(USD(10000), alice, carol);
1182 env.
trust(USD(10000), bob);
1183 env.
trust(bob[
"USD"](10000), carol);
1186 env(pay(bob, carol, bob[
"USD"](1000)));
1187 env(pay(gw, bob, USD(1000)));
1190 env(offer(carol,
XRP(1), bob[
"USD"](1000)));
1193 env(pay(alice, alice, USD(1000)),
1194 path(~bob[
"USD"], bob, gw),
1207 testcase(
"Self crossing low quality offer");
1209 using namespace jtx;
1211 Env env(*
this, features);
1213 auto const ann =
Account(
"ann");
1214 auto const gw =
Account(
"gateway");
1215 auto const CTB = gw[
"CTB"];
1222 env(
rate(gw, 1.002));
1223 env(trust(ann, CTB(10)));
1226 env(pay(gw, ann, CTB(2.856)));
1229 env(offer(ann,
drops(365611702030), CTB(5.713)));
1233 env(pay(ann, ann, CTB(0.687)),
1241 testcase(
"Empty Strand");
1242 using namespace jtx;
1244 auto const alice =
Account(
"alice");
1246 Env env(*
this, features);
1250 env(pay(alice, alice, alice[
"USD"](100)),
1251 path(~alice[
"USD"]),
1258 testcase(
"Circular XRP");
1260 using namespace jtx;
1261 auto const alice =
Account(
"alice");
1262 auto const bob =
Account(
"bob");
1263 auto const gw =
Account(
"gw");
1264 auto const USD = gw[
"USD"];
1265 auto const EUR = gw[
"EUR"];
1267 for (
auto const withFix : {
true,
false})
1276 Env env(*
this, feats);
1277 env.
fund(
XRP(10000), alice, bob, gw);
1278 env.
trust(USD(1000), alice, bob);
1279 env.
trust(EUR(1000), alice, bob);
1280 env(pay(gw, alice, USD(100)));
1281 env(pay(gw, alice, EUR(100)));
1289 TER const expectedTer =
1291 env(pay(alice, bob, EUR(1)),
1302 env.
fund(
XRP(10000), alice, bob, gw);
1303 env.
trust(USD(1000), alice, bob);
1304 env.
trust(EUR(1000), alice, bob);
1305 env(pay(gw, alice, USD(100)));
1306 env(pay(gw, alice, EUR(100)));
1313 env(pay(alice, bob,
XRP(1)),
1322 auto const JPY = gw[
"JPY"];
1324 env.
fund(
XRP(10000), alice, bob, gw);
1326 env.
trust(USD(1000), alice, bob);
1327 env.
trust(EUR(1000), alice, bob);
1328 env.
trust(JPY(1000), alice, bob);
1330 env(pay(gw, alice, USD(100)));
1331 env(pay(gw, alice, EUR(100)));
1332 env(pay(gw, alice, JPY(100)));
1341 env(pay(alice, bob, JPY(1)),
1352 testcase(
"Payment with ticket");
1353 using namespace jtx;
1355 auto const alice =
Account(
"alice");
1356 auto const bob =
Account(
"bob");
1358 Env env(*
this, features);
1364 env(ticket::create(alice, 1));
1376 using namespace jtx;
1404 using namespace jtx;
1417 using namespace jtx;