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>
31 #include <test/jtx/TestHelpers.h>
47 return sle->isFlag(flag);
49 Throw<std::runtime_error>(
"No line in getTrustFlag");
58 testcase(
"Direct Step");
61 auto const alice =
Account(
"alice");
62 auto const bob =
Account(
"bob");
63 auto const carol =
Account(
"carol");
64 auto const dan =
Account(
"dan");
65 auto const erin =
Account(
"erin");
66 auto const USDA = alice[
"USD"];
67 auto const USDB = bob[
"USD"];
68 auto const USDC = carol[
"USD"];
69 auto const USDD = dan[
"USD"];
71 auto const USD = gw[
"USD"];
74 Env env(*
this, features);
76 env.
fund(
XRP(10000), alice, bob, gw);
77 env.
trust(USD(1000), alice, bob);
78 env(pay(gw, alice, USD(100)));
79 env(pay(alice, bob, USD(10)),
paths(USD));
84 Env env(*
this, features);
86 env.
fund(
XRP(10000), alice, bob);
87 env(pay(alice, bob,
XRP(100)));
93 Env env(*
this, features);
95 env.
fund(
XRP(10000), alice, bob, gw);
96 env.
trust(USD(1000), alice, bob);
97 env(pay(gw, alice, USD(100)));
100 env(pay(alice, bob, USD(110)),
107 Env env(*
this, features);
109 env.
fund(
XRP(10000), alice, bob, carol, dan);
110 env.
trust(USDA(10), bob);
111 env.
trust(USDB(10), carol);
112 env.
trust(USDC(10), dan);
113 env(pay(alice, dan, USDC(10)),
paths(USDA));
122 Env env(*
this, features);
124 env.
fund(
XRP(10000), alice, bob, carol, dan);
125 env.
trust(USDA(10), bob);
126 env.
trust(USDB(10), alice, carol);
127 env.
trust(USDC(10), dan);
131 env(pay(bob, alice, USDB(6)));
132 env(pay(alice, dan, USDC(5)),
142 Env env(*
this, features);
144 env.
fund(
XRP(10000), alice, bob, carol, dan);
145 env.
trust(USDA(10), bob);
146 env.
trust(USDB(10), alice, carol);
147 env.
trust(USDC(10), dan);
150 env(pay(alice, dan, USDC(5)),
160 Env env(*
this, features);
162 env.
fund(
XRP(10000), alice, bob, carol, dan, erin);
163 env.
trust(USDA(10), bob, carol);
164 env.
trust(USDB(10), dan);
165 env.
trust(USDC(10), alice, dan);
166 env.
trust(USDD(20), erin);
168 env(
rate(carol, 1.1));
171 env(pay(carol, alice, USDC(10)));
172 env(pay(alice, erin, USDD(5)),
183 Env env(*
this, features);
185 env.
fund(
XRP(10000), alice, bob, carol);
186 env.
trust(USDA(10), bob);
187 env.
trust(USDB(10), carol);
189 env(pay(alice, carol, USDB(5)),
195 env(pay(alice, carol, USDB(5)),
205 testcase(
"Line Quality");
208 auto const alice =
Account(
"alice");
209 auto const bob =
Account(
"bob");
210 auto const carol =
Account(
"carol");
211 auto const dan =
Account(
"dan");
212 auto const USDA = alice[
"USD"];
213 auto const USDB = bob[
"USD"];
214 auto const USDC = carol[
"USD"];
215 auto const USDD = dan[
"USD"];
218 for (
auto bobDanQIn : {80, 100, 120})
219 for (
auto bobAliceQOut : {80, 100, 120})
221 Env env(*
this, features);
222 env.
fund(
XRP(10000), alice, bob, carol, dan);
225 env(trust(carol, USDA(100)));
227 env(pay(alice, bob, USDA(100)));
229 env(pay(dan, carol, USDA(10)),
234 if (bobAliceQOut > bobDanQIn)
237 USDD(10.0 *
double(bobAliceQOut) /
double(bobDanQIn))));
244 for (
auto carolAliceQIn : {80, 100, 120})
246 Env env(*
this, features);
247 env.
fund(
XRP(10000), alice, bob, carol);
248 env(trust(bob, USDA(10)));
251 env(pay(alice, bob, USDA(10)));
253 env(pay(bob, carol, USDA(5)),
sendmax(USDA(10)));
254 auto const effectiveQ =
255 carolAliceQIn > 100 ? 1.0 : carolAliceQIn / 100.0;
260 for (
auto bobAliceQOut : {80, 100, 120})
262 Env env(*
this, features);
263 env.
fund(
XRP(10000), alice, bob, carol);
265 env(trust(carol, USDA(10)));
267 env(pay(alice, bob, USDA(10)));
269 env(pay(bob, carol, USDA(5)),
sendmax(USDA(5)));
278 testcase(
"Book Step");
282 auto const gw =
Account(
"gateway");
283 auto const USD = gw[
"USD"];
284 auto const BTC = gw[
"BTC"];
285 auto const EUR = gw[
"EUR"];
292 Env env(*
this, features);
294 env.
fund(
XRP(10000), alice, bob, carol, gw);
295 env.
trust(USD(1000), alice, bob, carol);
296 env.
trust(BTC(1000), alice, bob, carol);
298 env(pay(gw, alice, BTC(50)));
299 env(pay(gw, bob, USD(50)));
301 env(offer(bob, BTC(50), USD(50)));
303 env(pay(alice, carol, USD(50)),
path(~USD),
sendmax(BTC(50)));
309 BEAST_EXPECT(!
isOffer(env, bob, BTC(50), USD(50)));
313 Env env(*
this, features);
315 env.
fund(
XRP(10000), alice, bob, carol, gw);
316 env.
trust(USD(1000), alice, bob, carol);
317 env.
trust(BTC(1000), alice, bob, carol);
319 env(pay(gw, alice, BTC(50)));
320 env(pay(gw, bob, USD(50)));
322 env(offer(bob, BTC(50),
XRP(50)));
323 env(offer(bob,
XRP(50), USD(50)));
325 env(pay(alice, carol, USD(50)),
path(~
XRP, ~USD),
sendmax(BTC(50)));
331 BEAST_EXPECT(!
isOffer(env, bob,
XRP(50), USD(50)));
332 BEAST_EXPECT(!
isOffer(env, bob, BTC(50),
XRP(50)));
336 Env env(*
this, features);
338 env.
fund(
XRP(10000), alice, bob, carol, gw);
339 env.
trust(USD(1000), alice, bob, carol);
340 env.
trust(BTC(1000), alice, bob, carol);
342 env(pay(gw, bob, USD(50)));
344 env(offer(bob,
XRP(50), USD(50)));
352 BEAST_EXPECT(!
isOffer(env, bob,
XRP(50), USD(50)));
356 Env env(*
this, features);
358 env.
fund(
XRP(10000), alice, bob, carol, gw);
359 env.
trust(USD(1000), alice, bob, carol);
360 env.
trust(BTC(1000), alice, bob, carol);
362 env(pay(gw, alice, USD(50)));
364 env(offer(bob, USD(50),
XRP(50)));
372 BEAST_EXPECT(!
isOffer(env, bob, USD(50),
XRP(50)));
376 Env env(*
this, features);
378 env.
fund(
XRP(10000), alice, bob, carol, gw);
379 env.
trust(USD(1000), alice, bob, carol);
380 env.
trust(BTC(1000), alice, bob, carol);
381 env.
trust(EUR(1000), alice, bob, carol);
383 env(pay(gw, alice, BTC(60)));
384 env(pay(gw, bob, USD(50)));
385 env(pay(gw, bob, EUR(50)));
387 env(offer(bob, BTC(50), USD(50)));
388 env(offer(bob, BTC(40), EUR(50)));
389 env(offer(bob, EUR(50), USD(50)));
392 env(pay(bob, gw, EUR(50)));
393 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
394 BEAST_EXPECT(
isOffer(env, bob, BTC(40), EUR(50)));
395 BEAST_EXPECT(
isOffer(env, bob, EUR(50), USD(50)));
397 env(pay(alice, carol, USD(50)),
408 BEAST_EXPECT(!
isOffer(env, bob, BTC(50), USD(50)));
410 BEAST_EXPECT(!
isOffer(env, bob, BTC(40), EUR(50)));
412 BEAST_EXPECT(
isOffer(env, bob, EUR(50), USD(50)));
423 Env env(*
this, features);
425 env.
fund(
XRP(10000), alice, bob, carol, gw);
426 env.
trust(USD(1000), alice, bob, carol);
427 env.
trust(BTC(1000), alice, bob, carol);
428 env.
trust(EUR(1000), alice, bob, carol);
430 env(pay(gw, alice, BTC(60)));
431 env(pay(gw, bob, USD(60)));
432 env(pay(gw, bob, EUR(50)));
433 env(pay(gw, carol, EUR(1)));
435 env(offer(bob, BTC(50), USD(50)));
436 env(offer(bob, BTC(60), EUR(50)));
437 env(offer(carol, BTC(1000), EUR(1)));
438 env(offer(bob, EUR(50), USD(50)));
441 env(pay(bob, gw, EUR(50)));
442 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
443 BEAST_EXPECT(
isOffer(env, bob, BTC(60), EUR(50)));
444 BEAST_EXPECT(
isOffer(env, carol, BTC(1000), EUR(1)));
447 auto const flowResult = [&] {
483 BEAST_EXPECT(flowResult.removableOffers.size() == 1);
486 if (flowResult.removableOffers.empty())
489 for (
auto const& o : flowResult.removableOffers)
497 BEAST_EXPECT(
isOffer(env, bob, BTC(50), USD(50)));
498 BEAST_EXPECT(
isOffer(env, carol, BTC(1000), EUR(1)));
500 BEAST_EXPECT(!
isOffer(env, bob, BTC(60), EUR(50)));
511 Env env(*
this, features);
512 env.
fund(
XRP(10000), alice, bob, carol, gw);
513 env.
trust(USD(1000), alice, bob, carol);
514 env.
trust(EUR(1000), alice, bob, carol);
516 env(pay(gw, alice, USD(1000)));
517 env(pay(gw, bob, EUR(1000)));
522 env(pay(alice, carol, EUR(1)),
536 testcase(
"Transfer Rate");
540 auto const gw =
Account(
"gateway");
541 auto const USD = gw[
"USD"];
542 auto const BTC = gw[
"BTC"];
543 auto const EUR = gw[
"EUR"];
551 Env env(*
this, features);
553 env.
fund(
XRP(10000), alice, bob, carol, gw);
555 env.
trust(USD(1000), alice, bob, carol);
556 env(pay(gw, alice, USD(50)));
558 env(pay(alice, bob, USD(40)),
sendmax(USD(50)));
563 Env env(*
this, features);
565 env.
fund(
XRP(10000), alice, bob, carol, gw);
567 env.
trust(USD(1000), alice, bob, carol);
568 env(pay(gw, alice, USD(50)));
570 env(pay(alice, gw, USD(40)),
sendmax(USD(40)));
575 Env env(*
this, features);
577 env.
fund(
XRP(10000), alice, bob, carol, gw);
579 env.
trust(USD(1000), alice, bob, carol);
580 env(pay(gw, bob, USD(65)));
582 env(offer(bob,
XRP(50), USD(50)));
593 Env env(*
this, features);
595 env.
fund(
XRP(10000), alice, bob, carol, gw);
597 env.
trust(USD(1000), alice, bob, carol);
598 env.
trust(EUR(1000), alice, bob, carol);
599 env(pay(gw, bob, USD(50)));
600 env(pay(gw, bob, EUR(50)));
602 env(offer(bob,
XRP(50), USD(50)));
603 env(offer(bob, USD(50), EUR(50)));
605 env(pay(alice, carol, EUR(40)),
path(~USD, ~EUR),
sendmax(
XRP(40)));
616 Env env(*
this, features);
617 auto const USDA = alice[
"USD"];
618 auto const USDB = bob[
"USD"];
620 env.
fund(
XRP(10000), alice, bob, carol, gw);
622 env.
trust(USD(1000), alice, bob, carol);
623 env.
trust(USDA(1000), bob);
624 env.
trust(USDB(1000), gw);
625 env(pay(gw, bob, USD(50)));
628 env(pay(alice, carol, USD(50)),
path(bob),
sendmax(USDA(60)));
637 Env env(*
this, features);
638 auto const USDA = alice[
"USD"];
639 auto const USDB = bob[
"USD"];
642 env.
fund(
XRP(10000), alice, bob, carol, dan, gw);
644 env.
trust(USD(1000), alice, bob, carol, dan);
645 env.
trust(EUR(1000), carol, dan);
646 env.
trust(USDA(1000), bob);
647 env.
trust(USDB(1000), gw);
648 env(pay(gw, bob, USD(50)));
649 env(pay(gw, dan, EUR(100)));
650 env(offer(dan, USD(100), EUR(100)));
653 env(pay(alice, carol, EUR(50)),
667 Env env(*
this, features);
669 env.
fund(
XRP(10000), alice, bob, gw);
671 env.
trust(USD(1000), alice, bob);
672 env(offer(gw,
XRP(100), USD(100)));
673 env(pay(alice, bob, USD(100)),
sendmax(
XRP(100)));
681 Env env(*
this, features);
683 env.
fund(
XRP(10000), alice, bob, gw);
685 env.
trust(USD(1000), alice, bob);
686 env(offer(gw,
XRP(125), USD(125)));
687 env(pay(alice, bob, USD(100)),
sendmax(
XRP(200)));
697 testcase(
"falseDryChanges");
701 auto const gw =
Account(
"gateway");
702 auto const USD = gw[
"USD"];
703 auto const EUR = gw[
"EUR"];
708 Env env(*
this, features);
710 env.
fund(
XRP(10000), alice, carol, gw);
712 env.
trust(USD(1000), alice, bob, carol);
713 env.
trust(EUR(1000), alice, bob, carol);
715 env(pay(gw, alice, EUR(50)));
716 env(pay(gw, bob, USD(50)));
725 env(offer(bob, EUR(50),
XRP(50)));
726 env(offer(bob,
XRP(50), USD(50)));
728 env(pay(alice, carol, USD(1000000)),
734 BEAST_EXPECT(carolUSD > USD(0) && carolUSD < USD(50));
744 testcase(
"limitQuality");
747 auto const gw =
Account(
"gateway");
748 auto const USD = gw[
"USD"];
756 env.
fund(
XRP(10000), alice, bob, carol, gw);
758 env.
trust(USD(100), alice, bob, carol);
759 env(pay(gw, bob, USD(100)));
760 env(offer(bob,
XRP(50), USD(50)));
761 env(offer(bob,
XRP(100), USD(50)));
763 env(pay(alice, carol, USD(100)),
777 return env.
current()->fees().accountReserve(count);
789 if (sle->getType() == ltOFFER)
790 result.push_back(sle);
798 testcase(
"Self-payment 1");
807 auto const gw1 =
Account(
"gw1");
808 auto const gw2 =
Account(
"gw2");
809 auto const alice =
Account(
"alice");
810 auto const USD = gw1[
"USD"];
811 auto const EUR = gw2[
"EUR"];
813 Env env(*
this, features);
815 env.
fund(
XRP(1000000), gw1, gw2);
819 auto const f = env.
current()->fees().base;
824 env(trust(alice, USD(2000)));
825 env(trust(alice, EUR(2000)));
828 env(pay(gw1, alice, USD(1)));
829 env(pay(gw2, alice, EUR(1000)));
832 env(offer(alice, USD(500), EUR(600)));
840 BEAST_EXPECT(aliceOffers.size() == 1);
841 for (
auto const& offerPtr : aliceOffers)
843 auto const offer = *offerPtr;
849 env(pay(alice, alice, EUR(600)),
858 BEAST_EXPECT(aliceOffers.size() == 1);
859 for (
auto const& offerPtr : aliceOffers)
861 auto const offer = *offerPtr;
871 testcase(
"Self-payment 2");
878 auto const gw1 =
Account(
"gw1");
879 auto const gw2 =
Account(
"gw2");
880 auto const alice =
Account(
"alice");
881 auto const USD = gw1[
"USD"];
882 auto const EUR = gw2[
"EUR"];
884 Env env(*
this, features);
886 env.
fund(
XRP(1000000), gw1, gw2);
890 auto const f = env.
current()->fees().base;
895 env(trust(alice, USD(506)));
896 env(trust(alice, EUR(606)));
899 env(pay(gw1, alice, USD(500)));
900 env(pay(gw2, alice, EUR(600)));
903 env(offer(alice, USD(500), EUR(600)));
911 BEAST_EXPECT(aliceOffers.size() == 1);
912 for (
auto const& offerPtr : aliceOffers)
914 auto const offer = *offerPtr;
920 env(pay(alice, alice, EUR(60)),
929 BEAST_EXPECT(aliceOffers.size() == 1);
930 for (
auto const& offerPtr : aliceOffers)
932 auto const offer = *offerPtr;
946 testcase(
"Self funded XRPEndpoint");
950 Env env(*
this, features);
952 auto const alice =
Account(
"alice");
954 auto const USD = gw[
"USD"];
956 env.
fund(
XRP(10000), alice, gw);
957 env(trust(alice, USD(20)));
958 env(pay(gw, alice, USD(10)));
959 env(offer(alice,
XRP(50000), USD(10)));
963 auto const toSend = consumeOffer ? USD(10) : USD(9);
964 env(pay(alice, alice, toSend),
973 testcase(
"Unfunded Offer");
978 Env env(*
this, features);
980 auto const alice =
Account(
"alice");
981 auto const bob =
Account(
"bob");
983 auto const USD = gw[
"USD"];
985 env.
fund(
XRP(100000), alice, bob, gw);
986 env(trust(bob, USD(20)));
1003 env(offer(gw,
drops(9000000000), tinyAmt3));
1004 env(pay(alice, bob, tinyAmt1),
1009 BEAST_EXPECT(!
isOffer(env, gw,
XRP(0), USD(0)));
1013 Env env(*
this, features);
1015 auto const alice =
Account(
"alice");
1016 auto const bob =
Account(
"bob");
1017 auto const gw =
Account(
"gw");
1018 auto const USD = gw[
"USD"];
1020 env.
fund(
XRP(100000), alice, bob, gw);
1021 env(trust(alice, USD(20)));
1038 env(pay(gw, alice, tinyAmt1));
1040 env(offer(gw, tinyAmt3,
drops(9000000000)));
1041 env(pay(alice, bob,
drops(9000000000)),
1046 BEAST_EXPECT(!
isOffer(env, gw, USD(0),
XRP(0)));
1053 testcase(
"ReexecuteDirectStep");
1055 using namespace jtx;
1056 Env env(*
this, features);
1058 auto const alice =
Account(
"alice");
1059 auto const bob =
Account(
"bob");
1060 auto const gw =
Account(
"gw");
1061 auto const USD = gw[
"USD"];
1062 auto const usdC = USD.currency;
1064 env.
fund(
XRP(10000), alice, bob, gw);
1066 env(trust(alice, USD(100)));
1106 env(pay(alice, bob,
XRP(10000)),
1115 testcase(
"ripd1443");
1117 using namespace jtx;
1119 auto const alice =
Account(
"alice");
1120 auto const bob =
Account(
"bob");
1121 auto const carol =
Account(
"carol");
1122 auto const gw =
Account(
"gw");
1125 env.
trust(gw[
"USD"](10000), alice, carol);
1127 env.
trust(gw[
"USD"](10000), bob);
1132 env(pay(gw, alice, gw[
"USD"](1000)));
1135 env(offer(alice, bob[
"USD"](1000),
XRP(1)));
1138 env(pay(alice, alice,
XRP(1)),
1145 env.
trust(bob[
"USD"](10000), alice);
1146 env(pay(bob, alice, bob[
"USD"](1000)));
1148 env(offer(alice,
XRP(1000), bob[
"USD"](1000)));
1151 env(pay(carol, carol, gw[
"USD"](1000)),
1152 path(~bob[
"USD"], gw),
1164 testcase(
"ripd1449");
1166 using namespace jtx;
1173 auto const alice =
Account(
"alice");
1174 auto const bob =
Account(
"bob");
1175 auto const carol =
Account(
"carol");
1176 auto const gw =
Account(
"gw");
1177 auto const USD = gw[
"USD"];
1179 env.
fund(
XRP(100000000), alice, bob, carol, gw);
1181 env.
trust(USD(10000), alice, carol);
1183 env.
trust(USD(10000), bob);
1184 env.
trust(bob[
"USD"](10000), carol);
1187 env(pay(bob, carol, bob[
"USD"](1000)));
1188 env(pay(gw, bob, USD(1000)));
1191 env(offer(carol,
XRP(1), bob[
"USD"](1000)));
1194 env(pay(alice, alice, USD(1000)),
1195 path(~bob[
"USD"], bob, gw),
1208 testcase(
"Self crossing low quality offer");
1210 using namespace jtx;
1212 Env env(*
this, features);
1214 auto const ann =
Account(
"ann");
1215 auto const gw =
Account(
"gateway");
1216 auto const CTB = gw[
"CTB"];
1223 env(
rate(gw, 1.002));
1224 env(trust(ann, CTB(10)));
1227 env(pay(gw, ann, CTB(2.856)));
1230 env(offer(ann,
drops(365611702030), CTB(5.713)));
1234 env(pay(ann, ann, CTB(0.687)),
1242 testcase(
"Empty Strand");
1243 using namespace jtx;
1245 auto const alice =
Account(
"alice");
1247 Env env(*
this, features);
1251 env(pay(alice, alice, alice[
"USD"](100)),
1252 path(~alice[
"USD"]),
1259 testcase(
"Circular XRP");
1261 using namespace jtx;
1262 auto const alice =
Account(
"alice");
1263 auto const bob =
Account(
"bob");
1264 auto const gw =
Account(
"gw");
1265 auto const USD = gw[
"USD"];
1266 auto const EUR = gw[
"EUR"];
1268 for (
auto const withFix : {
true,
false})
1277 Env env(*
this, feats);
1278 env.
fund(
XRP(10000), alice, bob, gw);
1279 env.
trust(USD(1000), alice, bob);
1280 env.
trust(EUR(1000), alice, bob);
1281 env(pay(gw, alice, USD(100)));
1282 env(pay(gw, alice, EUR(100)));
1290 TER const expectedTer =
1292 env(pay(alice, bob, EUR(1)),
1303 env.
fund(
XRP(10000), alice, bob, gw);
1304 env.
trust(USD(1000), alice, bob);
1305 env.
trust(EUR(1000), alice, bob);
1306 env(pay(gw, alice, USD(100)));
1307 env(pay(gw, alice, EUR(100)));
1314 env(pay(alice, bob,
XRP(1)),
1323 auto const JPY = gw[
"JPY"];
1325 env.
fund(
XRP(10000), alice, bob, gw);
1327 env.
trust(USD(1000), alice, bob);
1328 env.
trust(EUR(1000), alice, bob);
1329 env.
trust(JPY(1000), alice, bob);
1331 env(pay(gw, alice, USD(100)));
1332 env(pay(gw, alice, EUR(100)));
1333 env(pay(gw, alice, JPY(100)));
1342 env(pay(alice, bob, JPY(1)),
1353 testcase(
"Payment with ticket");
1354 using namespace jtx;
1356 auto const alice =
Account(
"alice");
1357 auto const bob =
Account(
"bob");
1359 Env env(*
this, features);
1365 env(ticket::create(alice, 1));
1377 using namespace jtx;
1405 using namespace jtx;
1418 using namespace jtx;