21#include <test/jtx/envconfig.h>
23#include <xrpld/app/paths/AccountCurrencies.h>
24#include <xrpld/core/JobQueue.h>
25#include <xrpld/rpc/Context.h>
26#include <xrpld/rpc/RPCHandler.h>
27#include <xrpld/rpc/detail/RPCHelpers.h>
28#include <xrpld/rpc/detail/Tuning.h>
30#include <xrpl/beast/unit_test.h>
31#include <xrpl/json/json_reader.h>
32#include <xrpl/protocol/STParsedJSON.h>
33#include <xrpl/protocol/TxFlags.h>
34#include <xrpl/protocol/jss.h>
35#include <xrpl/resource/Fees.h>
48 jv[jss::command] =
"ripple_path_find";
49 jv[jss::source_account] =
toBase58(src);
63 jv[jss::destination_account] = d;
66 j[jss::currency] =
"USD";
67 j[jss::value] =
"0.01";
85 cfg->PATH_SEARCH_OLD = 7;
87 cfg->PATH_SEARCH_MAX = 10;
103 template <
class Rep,
class Period>
133 auto& app = env.
app();
142 app.getLedgerMaster(),
152 params[jss::command] =
"ripple_path_find";
153 params[jss::source_account] =
toBase58(src);
154 params[jss::destination_account] =
toBase58(dst);
155 params[jss::destination_amount] =
163 j[jss::currency] =
to_string(saSrcCurrency.value());
169 app.getJobQueue().postCoro(
170 jtCLIENT,
"RPC-Client", [&](
auto const& coro) {
171 context.params = std::move(params);
177 using namespace std::chrono_literals;
179 BEAST_EXPECT(!result.
isMember(jss::error));
193 env, src, dst, saDstAmount, saSendMax, saSrcCurrency);
194 BEAST_EXPECT(!result.
isMember(jss::error));
197 if (result.
isMember(jss::destination_amount))
202 if (result.
isMember(jss::alternatives))
204 auto const& alts = result[jss::alternatives];
207 auto const&
path = alts[0u];
209 if (
path.isMember(jss::source_amount))
212 if (
path.isMember(jss::destination_amount))
216 if (
path.isMember(jss::paths_computed))
219 p[
"Paths"] =
path[jss::paths_computed];
233 using namespace std::chrono_literals;
236 auto const gw =
Account(
"gateway");
237 env.
fund(
XRP(10000),
"alice",
"bob", gw);
239 env.
trust(gw[
"USD"](100),
"alice",
"bob");
242 auto& app = env.
app();
251 app.getLedgerMaster(),
262 app.getJobQueue().postCoro(
263 jtCLIENT,
"RPC-Client", [&](
auto const& coro) {
264 context.params =
rpf(
271 BEAST_EXPECT(!result.
isMember(jss::error));
274 app.getJobQueue().postCoro(
275 jtCLIENT,
"RPC-Client", [&](
auto const& coro) {
285 BEAST_EXPECT(result.
isMember(jss::error));
290 app.getJobQueue().postCoro(
291 jtCLIENT,
"RPC-Client", [&](
auto const& coro) {
298 BEAST_EXPECT(!result.
isMember(jss::error));
302 app.getJobQueue().postCoro(
303 jtCLIENT,
"RPC-Client", [&](
auto const& coro) {
310 BEAST_EXPECT(result.
isMember(jss::error));
316 testcase(
"no direct path no intermediary no alternatives");
319 env.
fund(
XRP(10000),
"alice",
"bob");
324 BEAST_EXPECT(std::get<0>(result).empty());
330 testcase(
"direct path no intermediary");
333 env.
fund(
XRP(10000),
"alice",
"bob");
341 BEAST_EXPECT(st.
empty());
351 auto const gw =
Account(
"gateway");
352 auto const USD = gw[
"USD"];
353 env.
fund(
XRP(10000),
"alice",
"bob", gw);
355 env.
trust(USD(600),
"alice");
356 env.
trust(USD(700),
"bob");
357 env(
pay(gw,
"alice", USD(70)));
358 env(
pay(
"alice",
"bob", USD(24)));
371 auto const gw =
Account(
"gateway");
372 auto const USD = gw[
"USD"];
373 env.
fund(
XRP(10000),
"alice",
"bob", gw);
375 env.
trust(USD(600),
"alice");
376 env.
trust(USD(700),
"bob");
377 env(
pay(gw,
"alice", USD(70)));
378 env(
pay(gw,
"bob", USD(50)));
394 env.
fund(
XRP(10000),
"alice",
"bob");
398 BEAST_EXPECT(std::get<0>(result).empty());
409 env.
fund(
XRP(10000),
"alice",
"bob",
"carol",
"dan",
"edward");
421 env,
"alice",
"edward",
Account(
"edward")[
"USD"](-1));
429 auto const gw =
Account(
"gateway");
430 auto const USD = gw[
"USD"];
431 env.
fund(
XRP(10000),
"alice",
"bob",
"carol", gw);
433 env.
trust(USD(100),
"bob",
"carol");
434 env(
pay(gw,
"carol", USD(100)));
435 env(
offer(
"carol",
XRP(100), USD(100)));
446 BEAST_EXPECT(st.
empty());
453 BEAST_EXPECT(sa ==
XRP(100));
461 testcase(
"alternative path consume both");
464 auto const gw =
Account(
"gateway");
465 auto const USD = gw[
"USD"];
466 auto const gw2 =
Account(
"gateway2");
467 auto const gw2_USD = gw2[
"USD"];
468 env.
fund(
XRP(10000),
"alice",
"bob", gw, gw2);
470 env.
trust(USD(600),
"alice");
471 env.
trust(gw2_USD(800),
"alice");
472 env.
trust(USD(700),
"bob");
473 env.
trust(gw2_USD(900),
"bob");
474 env(
pay(gw,
"alice", USD(70)));
475 env(
pay(gw2,
"alice", gw2_USD(70)));
476 env(
pay(
"alice",
"bob",
Account(
"bob")[
"USD"](140)),
491 testcase(
"alternative paths consume best transfer");
494 auto const gw =
Account(
"gateway");
495 auto const USD = gw[
"USD"];
496 auto const gw2 =
Account(
"gateway2");
497 auto const gw2_USD = gw2[
"USD"];
498 env.
fund(
XRP(10000),
"alice",
"bob", gw, gw2);
501 env.
trust(USD(600),
"alice");
502 env.
trust(gw2_USD(800),
"alice");
503 env.
trust(USD(700),
"bob");
504 env.
trust(gw2_USD(900),
"bob");
505 env(
pay(gw,
"alice", USD(70)));
506 env(
pay(gw2,
"alice", gw2_USD(70)));
507 env(
pay(
"alice",
"bob", USD(70)));
521 testcase(
"alternative paths - consume best transfer first");
524 auto const gw =
Account(
"gateway");
525 auto const USD = gw[
"USD"];
526 auto const gw2 =
Account(
"gateway2");
527 auto const gw2_USD = gw2[
"USD"];
528 env.
fund(
XRP(10000),
"alice",
"bob", gw, gw2);
531 env.
trust(USD(600),
"alice");
532 env.
trust(gw2_USD(800),
"alice");
533 env.
trust(USD(700),
"bob");
534 env.
trust(gw2_USD(900),
"bob");
535 env(
pay(gw,
"alice", USD(70)));
536 env(
pay(gw2,
"alice", gw2_USD(70)));
537 env(
pay(
"alice",
"bob",
Account(
"bob")[
"USD"](77)),
553 testcase(
"alternative paths - limit returned paths to best quality");
556 auto const gw =
Account(
"gateway");
557 auto const USD = gw[
"USD"];
558 auto const gw2 =
Account(
"gateway2");
559 auto const gw2_USD = gw2[
"USD"];
560 env.
fund(
XRP(10000),
"alice",
"bob",
"carol",
"dan", gw, gw2);
562 env(
rate(
"carol", 1.1));
563 env.
trust(
Account(
"carol")[
"USD"](800),
"alice",
"bob");
565 env.
trust(USD(800),
"alice",
"bob");
566 env.
trust(gw2_USD(800),
"alice",
"bob");
569 env(
pay(gw2,
"alice", gw2_USD(100)));
570 env(
pay(
"carol",
"alice",
Account(
"carol")[
"USD"](100)));
571 env(
pay(gw,
"alice", USD(100)));
589 testcase(
"path negative: Issue #5");
592 env.
fund(
XRP(10000),
"alice",
"bob",
"carol",
"dan");
594 env.
trust(
Account(
"bob")[
"USD"](100),
"alice",
"carol",
"dan");
597 env(
pay(
"bob",
"carol",
Account(
"bob")[
"USD"](75)));
603 BEAST_EXPECT(std::get<0>(result).empty());
608 BEAST_EXPECT(std::get<0>(result).empty());
628 testcase(
"path negative: ripple-client issue #23: smaller");
631 env.
fund(
XRP(10000),
"alice",
"bob",
"carol",
"dan");
637 env(
pay(
"alice",
"bob",
Account(
"bob")[
"USD"](55)),
648 testcase(
"path negative: ripple-client issue #23: larger");
651 env.
fund(
XRP(10000),
"alice",
"bob",
"carol",
"dan",
"edward");
658 env(
pay(
"alice",
"bob",
Account(
"bob")[
"USD"](50)),
679 auto const gw =
Account(
"gateway");
680 auto const AUD = gw[
"AUD"];
681 env.
fund(
XRP(10000),
"alice",
"bob",
"carol", gw);
684 env.
trust(AUD(100),
"bob",
"carol");
685 env(
pay(gw,
"carol", AUD(50)));
686 env(
offer(
"carol",
XRP(50), AUD(50)));
693 BEAST_EXPECT(std::get<0>(result).empty());
702 env.
fund(
XRP(10000),
"alice",
"bob",
"carol");
721 env.
fund(
XRP(10000),
"alice",
"bob");
724 json(
"{\"" + sfQualityIn.fieldName +
"\": 2000}"),
725 json(
"{\"" + sfQualityOut.fieldName +
"\": 1400000000}"));
732 "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji",
738 "issuer" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
742 "HighQualityIn" : 2000,
743 "HighQualityOut" : 1400000000,
744 "LedgerEntryType" : "RippleState",
747 "issuer" : "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
758 for (
auto it = jv.
begin(); it != jv.
end(); ++it)
759 BEAST_EXPECT(*it == jv_l[it.memberName()]);
768 env.
fund(
XRP(10000),
"alice",
"bob");
778 "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji",
784 "issuer" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
788 "LedgerEntryType" : "RippleState",
791 "issuer" : "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
802 for (
auto it = jv.
begin(); it != jv.
end(); ++it)
803 BEAST_EXPECT(*it == jv_l[it.memberName()]);
819 env.
fund(
XRP(10000),
"alice",
"bob");
822 env(
pay(
"bob",
"alice",
Account(
"bob")[
"USD"](50)));
831 "issuer" : "rrrrrrrrrrrrrrrrrrrrBZbvji",
838 "issuer" : "rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK",
842 "LedgerEntryType" : "RippleState",
846 "issuer" : "rG1QQv2nh2gr7RCZ1P8YYcBUKCCN633jCn",
857 for (
auto it = jv.
begin(); it != jv.
end(); ++it)
858 BEAST_EXPECT(*it == jv_l[it.memberName()]);
860 env(
pay(
"alice",
"bob",
Account(
"alice")[
"USD"](50)));
870 testcase(
"Path Find: XRP -> XRP and XRP -> IOU");
881 env.fund(
XRP(100000), A1);
882 env.fund(
XRP(10000), A2);
883 env.fund(
XRP(1000), A3, G1, G2, G3, M1);
886 env.trust(G1[
"XYZ"](5000), A1);
887 env.trust(G3[
"ABC"](5000), A1);
888 env.trust(G2[
"XYZ"](5000), A2);
889 env.trust(G3[
"ABC"](5000), A2);
890 env.trust(A2[
"ABC"](1000), A3);
891 env.trust(G1[
"XYZ"](100000), M1);
892 env.trust(G2[
"XYZ"](100000), M1);
893 env.trust(G3[
"ABC"](100000), M1);
896 env(
pay(G1, A1, G1[
"XYZ"](3500)));
897 env(
pay(G3, A1, G3[
"ABC"](1200)));
898 env(
pay(G2, M1, G2[
"XYZ"](25000)));
899 env(
pay(G3, M1, G3[
"ABC"](25000)));
902 env(
offer(M1, G1[
"XYZ"](1000), G2[
"XYZ"](1000)));
903 env(
offer(M1,
XRP(10000), G3[
"ABC"](1000)));
909 auto const& send_amt =
XRP(10);
912 BEAST_EXPECT(
equal(da, send_amt));
913 BEAST_EXPECT(st.
empty());
919 auto const& send_amt =
XRP(200);
922 BEAST_EXPECT(
equal(da, send_amt));
923 BEAST_EXPECT(st.
empty());
927 auto const& send_amt = G3[
"ABC"](10);
930 BEAST_EXPECT(
equal(da, send_amt));
936 auto const& send_amt = A2[
"ABC"](1);
939 BEAST_EXPECT(
equal(da, send_amt));
945 auto const& send_amt = A3[
"ABC"](1);
948 BEAST_EXPECT(
equal(da, send_amt));
957 testcase(
"Path Find: non-XRP -> XRP");
965 env.fund(
XRP(1000), A1, A2, G3);
966 env.fund(
XRP(11000), M1);
969 env.trust(G3[
"ABC"](1000), A1, A2);
970 env.trust(G3[
"ABC"](100000), M1);
973 env(
pay(G3, A1, G3[
"ABC"](1000)));
974 env(
pay(G3, A2, G3[
"ABC"](1000)));
975 env(
pay(G3, M1, G3[
"ABC"](1200)));
978 env(
offer(M1, G3[
"ABC"](1000),
XRP(10000)));
983 auto const& send_amt =
XRP(10);
985 find_paths(env, A1, A2, send_amt, std::nullopt, A2[
"ABC"].currency);
986 BEAST_EXPECT(
equal(da, send_amt));
987 BEAST_EXPECT(
equal(sa, A1[
"ABC"](1)));
994 testcase(
"Path Find: Bitstamp and SnapSwap, liquidity with no offers");
999 Account G1BS{
"G1BS"};
1000 Account G2SW{
"G2SW"};
1003 env.fund(
XRP(1000), G1BS, G2SW, A1, A2);
1004 env.fund(
XRP(11000), M1);
1007 env.trust(G1BS[
"HKD"](2000), A1);
1008 env.trust(G2SW[
"HKD"](2000), A2);
1009 env.trust(G1BS[
"HKD"](100000), M1);
1010 env.trust(G2SW[
"HKD"](100000), M1);
1013 env(
pay(G1BS, A1, G1BS[
"HKD"](1000)));
1014 env(
pay(G2SW, A2, G2SW[
"HKD"](1000)));
1018 env(
pay(G1BS, M1, G1BS[
"HKD"](1200)));
1019 env(
pay(G2SW, M1, G2SW[
"HKD"](5000)));
1026 auto const& send_amt = A2[
"HKD"](10);
1028 env, A1, A2, send_amt, std::nullopt, A2[
"HKD"].currency);
1029 BEAST_EXPECT(
equal(da, send_amt));
1030 BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
1031 BEAST_EXPECT(
same(st,
stpath(G1BS, M1, G2SW)));
1035 auto const& send_amt = A1[
"HKD"](10);
1037 env, A2, A1, send_amt, std::nullopt, A1[
"HKD"].currency);
1038 BEAST_EXPECT(
equal(da, send_amt));
1039 BEAST_EXPECT(
equal(sa, A2[
"HKD"](10)));
1040 BEAST_EXPECT(
same(st,
stpath(G2SW, M1, G1BS)));
1044 auto const& send_amt = A2[
"HKD"](10);
1046 env, G1BS, A2, send_amt, std::nullopt, A1[
"HKD"].currency);
1047 BEAST_EXPECT(
equal(da, send_amt));
1048 BEAST_EXPECT(
equal(sa, G1BS[
"HKD"](10)));
1053 auto const& send_amt = M1[
"HKD"](10);
1055 env, M1, G1BS, send_amt, std::nullopt, A1[
"HKD"].currency);
1056 BEAST_EXPECT(
equal(da, send_amt));
1057 BEAST_EXPECT(
equal(sa, M1[
"HKD"](10)));
1058 BEAST_EXPECT(st.
empty());
1062 auto const& send_amt = A1[
"HKD"](10);
1064 env, G2SW, A1, send_amt, std::nullopt, A1[
"HKD"].currency);
1065 BEAST_EXPECT(
equal(da, send_amt));
1066 BEAST_EXPECT(
equal(sa, G2SW[
"HKD"](10)));
1074 testcase(
"Path Find: non-XRP -> non-XRP, same currency");
1075 using namespace jtx;
1088 env.fund(
XRP(1000), A1, A2, A3, G1, G2, G3, G4);
1089 env.fund(
XRP(10000), A4);
1090 env.fund(
XRP(11000), M1, M2);
1093 env.trust(G1[
"HKD"](2000), A1);
1094 env.trust(G2[
"HKD"](2000), A2);
1095 env.trust(G1[
"HKD"](2000), A3);
1096 env.trust(G1[
"HKD"](100000), M1);
1097 env.trust(G2[
"HKD"](100000), M1);
1098 env.trust(G1[
"HKD"](100000), M2);
1099 env.trust(G2[
"HKD"](100000), M2);
1102 env(
pay(G1, A1, G1[
"HKD"](1000)));
1103 env(
pay(G2, A2, G2[
"HKD"](1000)));
1104 env(
pay(G1, A3, G1[
"HKD"](1000)));
1105 env(
pay(G1, M1, G1[
"HKD"](1200)));
1106 env(
pay(G2, M1, G2[
"HKD"](5000)));
1107 env(
pay(G1, M2, G1[
"HKD"](1200)));
1108 env(
pay(G2, M2, G2[
"HKD"](5000)));
1111 env(
offer(M1, G1[
"HKD"](1000), G2[
"HKD"](1000)));
1112 env(
offer(M2,
XRP(10000), G2[
"HKD"](1000)));
1113 env(
offer(M2, G1[
"HKD"](1000),
XRP(10000)));
1121 auto const& send_amt = G1[
"HKD"](10);
1123 env, A1, G1, send_amt, std::nullopt, G1[
"HKD"].currency);
1124 BEAST_EXPECT(st.empty());
1125 BEAST_EXPECT(
equal(da, send_amt));
1126 BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
1132 auto const& send_amt = A1[
"HKD"](10);
1134 env, A1, G1, send_amt, std::nullopt, G1[
"HKD"].currency);
1135 BEAST_EXPECT(st.empty());
1137 BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
1143 auto const& send_amt = A3[
"HKD"](10);
1145 env, A1, A3, send_amt, std::nullopt, G1[
"HKD"].currency);
1146 BEAST_EXPECT(
equal(da, send_amt));
1147 BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
1154 auto const& send_amt = G2[
"HKD"](10);
1156 env, G1, G2, send_amt, std::nullopt, G1[
"HKD"].currency);
1157 BEAST_EXPECT(
equal(da, send_amt));
1158 BEAST_EXPECT(
equal(sa, G1[
"HKD"](10)));
1170 auto const& send_amt = G2[
"HKD"](10);
1172 env, A1, G2, send_amt, std::nullopt, G1[
"HKD"].currency);
1173 BEAST_EXPECT(
equal(da, send_amt));
1174 BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
1186 auto const& send_amt = A2[
"HKD"](10);
1188 env, A1, A2, send_amt, std::nullopt, G1[
"HKD"].currency);
1189 BEAST_EXPECT(
equal(da, send_amt));
1190 BEAST_EXPECT(
equal(sa, A1[
"HKD"](10)));
1203 testcase(
"Path Find: non-XRP -> non-XRP, same currency)");
1204 using namespace jtx;
1213 env.fund(
XRP(11000), M1);
1214 env.fund(
XRP(1000), A1, A2, A3, G1, G2);
1217 env.trust(G1[
"HKD"](2000), A1);
1218 env.trust(G2[
"HKD"](2000), A2);
1219 env.trust(A2[
"HKD"](2000), A3);
1220 env.trust(G1[
"HKD"](100000), M1);
1221 env.trust(G2[
"HKD"](100000), M1);
1224 env(
pay(G1, A1, G1[
"HKD"](1000)));
1225 env(
pay(G2, A2, G2[
"HKD"](1000)));
1226 env(
pay(G1, M1, G1[
"HKD"](5000)));
1227 env(
pay(G2, M1, G2[
"HKD"](5000)));
1230 env(
offer(M1, G1[
"HKD"](1000), G2[
"HKD"](1000)));
1234 auto const& send_amt = A2[
"HKD"](10);
1238 find_paths(env, G1, A2, send_amt, std::nullopt, G1[
"HKD"].currency);
1240 BEAST_EXPECT(
equal(sa, G1[
"HKD"](10)));
1248 using namespace jtx;
1249 auto const alice =
Account(
"alice");
1250 auto const bob =
Account(
"bob");
1251 auto const charlie =
Account(
"charlie");
1252 auto const gw =
Account(
"gw");
1253 auto const USD = gw[
"USD"];
1257 env.
fund(
XRP(10000), alice, bob, charlie, gw);
1259 env.
trust(USD(100), alice, bob, charlie);
1261 env(
pay(gw, charlie, USD(10)));
1263 env(
offer(charlie,
XRP(10), USD(10)));
1267 BEAST_EXPECT(sa ==
XRP(10));
1268 BEAST_EXPECT(
equal(da, USD(10)));
1269 if (BEAST_EXPECT(st.size() == 1 && st[0].size() == 1))
1271 auto const& pathElem = st[0][0];
1273 pathElem.isOffer() && pathElem.getIssuerID() == gw.id() &&
1274 pathElem.getCurrency() == USD.currency);
1280 env.fund(
XRP(10000), alice, bob, charlie, gw);
1282 env.trust(USD(100), alice, bob, charlie);
1284 env(
pay(gw, alice, USD(10)));
1286 env(
offer(charlie, USD(10),
XRP(10)));
1290 BEAST_EXPECT(sa == USD(10));
1292 if (BEAST_EXPECT(st.size() == 1 && st[0].size() == 1))
1294 auto const& pathElem = st[0][0];
1296 pathElem.isOffer() &&
1306 using namespace jtx;
1311 auto const alice =
Account(
"alice");
1312 auto const bob =
Account(
"bob");
1313 auto const george =
Account(
"george");
1314 auto const USD = george[
"USD"];
1341 env(
pay(george, alice, USD(70)));
1346 BEAST_EXPECT(
equal(da, bob[
"USD"](5)));
1350 BEAST_EXPECT(st.size() == 1);
1352 BEAST_EXPECT(
equal(sa, alice[
"USD"](5)));
1356 BEAST_EXPECT(st.size() == 0);
1360 test(
"ripple -> ripple",
true,
true,
true);
1361 test(
"ripple -> no ripple",
true,
false,
true);
1362 test(
"no ripple -> ripple",
false,
true,
true);
1363 test(
"no ripple -> no ripple",
false,
false,
false);
Unserialize a JSON document into a Value.
bool parse(std::string const &document, Value &root)
Read a Value from a JSON document.
const_iterator begin() const
const_iterator end() const
bool isMember(char const *key) const
Return true if the object has a member named key.
testcase_t testcase
Memberspace for declaring test cases.
An endpoint that consumes resources.
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Holds the serialized result of parsing an input JSON object.
std::optional< STObject > object
The STObject if the parse was successful.
std::condition_variable cv_
bool wait_for(std::chrono::duration< Rep, Period > const &rel_time)
void alternative_path_consume_both()
void noripple_combinations()
void trust_auto_clear_trust_normal_clear()
void payment_auto_path_find()
void issues_path_negative_issue()
void indirect_paths_path_find()
void alternative_paths_consume_best_transfer()
void alternative_paths_limit_returned_paths_to_best_quality()
void trust_auto_clear_trust_auto_clear()
void direct_path_no_intermediary()
std::tuple< STPathSet, STAmount, STAmount > find_paths(jtx::Env &env, jtx::Account const &src, jtx::Account const &dst, STAmount const &saDstAmount, std::optional< STAmount > const &saSendMax=std::nullopt, std::optional< Currency > const &saSrcCurrency=std::nullopt)
void path_find_consume_all()
void issues_path_negative_ripple_client_issue_23_larger()
void source_currencies_limit()
void issues_path_negative_ripple_client_issue_23_smaller()
void alternative_paths_consume_best_transfer_first()
void via_offers_via_gateway()
auto find_paths_request(jtx::Env &env, jtx::Account const &src, jtx::Account const &dst, STAmount const &saDstAmount, std::optional< STAmount > const &saSendMax=std::nullopt, std::optional< Currency > const &saSrcCurrency=std::nullopt)
void quality_paths_quality_set_and_test()
void run() override
Runs the suite.
void no_direct_path_no_intermediary_no_alternatives()
Immutable cryptographic account descriptor.
A transaction testing environment.
void require(Args const &... args)
Check a set of requirements.
bool close(NetClock::time_point closeTime, std::optional< std::chrono::milliseconds > consensusDelay=std::nullopt)
Close and advance the ledger.
void trust(STAmount const &amount, Account const &account)
Establish trust lines.
beast::Journal const journal
void fund(bool setDefaultRipple, STAmount const &amount, Account const &account)
std::shared_ptr< SLE const > le(Account const &account) const
Return an account root.
Set Paths, SendMax on a JTx.
Sets the SendMax on a JTx.
Set the expected result code for a JTx The test will fail if the code doesn't match.
@ arrayValue
array value (ordered list)
@ objectValue
object value (collection of name/value pairs).
static int constexpr max_src_cur
Maximum number of source currencies allowed in a path find request.
static int constexpr max_auto_src_cur
Maximum number of auto source currencies in a path find request.
Status doCommand(RPC::JsonContext &context, Json::Value &result)
Execute an RPC command and store the results in a Json::Value.
static constexpr auto apiVersionIfUnspecified
Charge const feeReferenceRPC
Keylet line(AccountID const &id0, AccountID const &id1, Currency const ¤cy) noexcept
The index of a trust line for a given currency.
PrettyAmount drops(Integer i)
Returns an XRP PrettyAmount, which is trivially convertible to STAmount.
Json::Value trust(Account const &account, STAmount const &amount, std::uint32_t flags)
Modify a trust line.
Json::Value pay(AccountID const &account, AccountID const &to, AnyAmount amount)
Create a payment.
bool same(STPathSet const &st1, Args const &... args)
std::unique_ptr< Config > envconfig()
creates and initializes a default configuration for jtx::Env
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
STPathElement IPE(Issue const &iss)
Json::Value offer(Account const &account, STAmount const &takerPays, STAmount const &takerGets, std::uint32_t flags)
Create an offer.
XRP_t const XRP
Converts to XRP Issue or STAmount.
STPath stpath(Args const &... args)
Json::Value rpf(jtx::Account const &src, jtx::Account const &dst, std::uint32_t num_src)
bool equal(std::unique_ptr< Step > const &s1, DirectStepInfo const &dsi)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Issue const & xrpIssue()
Returns an asset specifier that represents XRP.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
AccountID const & xrpAccount()
Compute AccountID from public key.
STAmount amountFromJson(SField const &name, Json::Value const &v)
constexpr std::uint32_t tfClearNoRipple
Currency const & xrpCurrency()
XRP currency.
std::string to_string(base_uint< Bits, Tag > const &a)
constexpr std::uint32_t tfSetNoRipple