diff --git a/src/test/app/Path_test.cpp b/src/test/app/Path_test.cpp index 4cfe938798d..8e76081bca3 100644 --- a/src/test/app/Path_test.cpp +++ b/src/test/app/Path_test.cpp @@ -19,7 +19,11 @@ #include #include +#include +#include #include +#include +#include #include #include #include @@ -685,6 +689,292 @@ class Path_test : public beast::unit_test::Suite BEAST_EXPECT(equal(sa, Account("alice")["USD"](5))); } +<<<<<<< HEAD + Json::Value + six_path_append_request_result() +======= + json::Value + sixPathAppendRequestResult() +>>>>>>> 362775e809fd6980492750b09a40fed7d205a9af + { + using namespace jtx; + Env env = pathTestEnv(); + +<<<<<<< HEAD + Account A1{"A1"}; + Account A2{"A2"}; + Account G1{"G1"}; + Account G2{"G2"}; + Account M1{"M1"}; + Account M2{"M2"}; + Account M3{"M3"}; + Account M4{"M4"}; + Account M5{"M5"}; + Account M6{"M6"}; + Account MM{"MM"}; + + env.fund(XRP(1000), A1, A2, G1, G2, M1, M2, M3, M4, M5, M6, MM); + env.close(); + + env.trust(G1["HKD"](2000), A1); + env.trust(G2["HKD"](2000), A2); + + env.trust(G1["HKD"](100000), M1, M2, M3, M4, M5, M6, MM); + env.trust(G2["HKD"](100000), M1, M2, M3, M4, M5, M6, MM); + env.close(); + + env(pay(G1, A1, G1["HKD"](1000))); + + env(pay(G1, M1, G1["HKD"](10))); + env(pay(G1, M2, G1["HKD"](10))); + env(pay(G1, M3, G1["HKD"](10))); + env(pay(G1, M4, G1["HKD"](10))); + env(pay(G1, M5, G1["HKD"](10))); + env(pay(G1, M6, G1["HKD"](10))); + env(pay(G1, MM, G1["HKD"](1000))); + + env(pay(G2, M1, G2["HKD"](10))); + env(pay(G2, M2, G2["HKD"](10))); + env(pay(G2, M3, G2["HKD"](10))); + env(pay(G2, M4, G2["HKD"](10))); + env(pay(G2, M5, G2["HKD"](10))); + env(pay(G2, M6, G2["HKD"](10))); + env(pay(G2, MM, G2["HKD"](1000))); + env.close(); + + env(offer(MM, G1["HKD"](1000), G2["HKD"](100))); + env.close(); + + return find_paths_request(env, A1, A2, A2["HKD"](60), std::nullopt, G1["HKD"].currency); + } + + void + pathfind_paths_computed_never_exceeds_six() + { + testcase("pathfind paths_computed never exceeds six"); + + auto const result = six_path_append_request_result(); +======= + Account const a1{"A1"}; + Account const a2{"A2"}; + Account const g1{"G1"}; + Account const g2{"G2"}; + Account const m1{"M1"}; + Account const m2{"M2"}; + Account const m3{"M3"}; + Account const m4{"M4"}; + Account const m5{"M5"}; + Account const m6{"M6"}; + Account const mm{"MM"}; + + env.fund(XRP(1000), a1, a2, g1, g2, m1, m2, m3, m4, m5, m6, mm); + env.close(); + + env.trust(g1["HKD"](2000), a1); + env.trust(g2["HKD"](2000), a2); + + env.trust(g1["HKD"](100000), m1, m2, m3, m4, m5, m6, mm); + env.trust(g2["HKD"](100000), m1, m2, m3, m4, m5, m6, mm); + env.close(); + + env(pay(g1, a1, g1["HKD"](1000))); + + env(pay(g1, m1, g1["HKD"](10))); + env(pay(g1, m2, g1["HKD"](10))); + env(pay(g1, m3, g1["HKD"](10))); + env(pay(g1, m4, g1["HKD"](10))); + env(pay(g1, m5, g1["HKD"](10))); + env(pay(g1, m6, g1["HKD"](10))); + env(pay(g1, mm, g1["HKD"](1000))); + + env(pay(g2, m1, g2["HKD"](10))); + env(pay(g2, m2, g2["HKD"](10))); + env(pay(g2, m3, g2["HKD"](10))); + env(pay(g2, m4, g2["HKD"](10))); + env(pay(g2, m5, g2["HKD"](10))); + env(pay(g2, m6, g2["HKD"](10))); + env(pay(g2, mm, g2["HKD"](1000))); + env.close(); + + env(offer(mm, g1["HKD"](1000), g2["HKD"](100))); + env.close(); + + return findPathsRequest(env, a1, a2, a2["HKD"](60), std::nullopt, g1["HKD"].currency); + } + + void + pathfindPathsComputedNeverExceedsSix() + { + testcase("pathfind paths_computed never exceeds six"); + + auto const result = sixPathAppendRequestResult(); +>>>>>>> 362775e809fd6980492750b09a40fed7d205a9af + BEAST_EXPECT(result.isMember(jss::alternatives)); + if (!result.isMember(jss::alternatives)) + return; + + BEAST_EXPECT(result[jss::alternatives].isArray()); + if (!result[jss::alternatives].isArray()) + return; + + bool sawPathsComputed = false; + for (auto const& alt : result[jss::alternatives]) + { + if (!alt.isMember(jss::paths_computed)) + continue; + sawPathsComputed = true; + BEAST_EXPECT(alt[jss::paths_computed].isArray()); + if (alt[jss::paths_computed].isArray()) + BEAST_EXPECT(alt[jss::paths_computed].size() <= 6); + } + BEAST_EXPECT(sawPathsComputed); + } + + void +<<<<<<< HEAD + pathfind_can_return_six_paths_with_append() +======= + pathfindCanReturnSixPathsWithAppend() +>>>>>>> 362775e809fd6980492750b09a40fed7d205a9af + { + testcase("pathfind can return six paths with append"); + using namespace jtx; + Env env = pathTestEnv(); + +<<<<<<< HEAD + Account A1{"A1"}; + Account A2{"A2"}; + Account G1{"G1"}; + Account G2{"G2"}; + Account M1{"M1"}; + Account M2{"M2"}; + Account M3{"M3"}; + Account M4{"M4"}; + Account M5{"M5"}; + Account M6{"M6"}; + Account MM{"MM"}; + + env.fund(XRP(1000), A1, A2, G1, G2, M1, M2, M3, M4, M5, M6, MM); + env.close(); + + env.trust(G1["HKD"](2000), A1); + env.trust(G2["HKD"](2000), A2); + + env.trust(G1["HKD"](100000), M1, M2, M3, M4, M5, M6, MM); + env.trust(G2["HKD"](100000), M1, M2, M3, M4, M5, M6, MM); + env.close(); + + env(pay(G1, A1, G1["HKD"](1000))); + + env(pay(G1, M1, G1["HKD"](10))); + env(pay(G1, M2, G1["HKD"](10))); + env(pay(G1, M3, G1["HKD"](10))); + env(pay(G1, M4, G1["HKD"](10))); + env(pay(G1, M5, G1["HKD"](10))); + env(pay(G1, M6, G1["HKD"](10))); + env(pay(G1, MM, G1["HKD"](1000))); + + env(pay(G2, M1, G2["HKD"](10))); + env(pay(G2, M2, G2["HKD"](10))); + env(pay(G2, M3, G2["HKD"](10))); + env(pay(G2, M4, G2["HKD"](10))); + env(pay(G2, M5, G2["HKD"](10))); + env(pay(G2, M6, G2["HKD"](10))); + env(pay(G2, MM, G2["HKD"](1000))); + env.close(); + + env(offer(MM, G1["HKD"](1000), G2["HKD"](100))); + env.close(); + + auto cache = + std::make_shared(env.current(), env.app().getJournal("RippleLineCache")); + Pathfinder pf( + cache, + A1.id(), + A2.id(), + G1["HKD"].currency, + std::nullopt, + A2["HKD"](60), +======= + Account const a1{"A1"}; + Account const a2{"A2"}; + Account const g1{"G1"}; + Account const g2{"G2"}; + Account const m1{"M1"}; + Account const m2{"M2"}; + Account const m3{"M3"}; + Account const m4{"M4"}; + Account const m5{"M5"}; + Account const m6{"M6"}; + Account const mm{"MM"}; + + env.fund(XRP(1000), a1, a2, g1, g2, m1, m2, m3, m4, m5, m6, mm); + env.close(); + + env.trust(g1["HKD"](2000), a1); + env.trust(g2["HKD"](2000), a2); + + env.trust(g1["HKD"](100000), m1, m2, m3, m4, m5, m6, mm); + env.trust(g2["HKD"](100000), m1, m2, m3, m4, m5, m6, mm); + env.close(); + + env(pay(g1, a1, g1["HKD"](1000))); + + env(pay(g1, m1, g1["HKD"](10))); + env(pay(g1, m2, g1["HKD"](10))); + env(pay(g1, m3, g1["HKD"](10))); + env(pay(g1, m4, g1["HKD"](10))); + env(pay(g1, m5, g1["HKD"](10))); + env(pay(g1, m6, g1["HKD"](10))); + env(pay(g1, mm, g1["HKD"](1000))); + + env(pay(g2, m1, g2["HKD"](10))); + env(pay(g2, m2, g2["HKD"](10))); + env(pay(g2, m3, g2["HKD"](10))); + env(pay(g2, m4, g2["HKD"](10))); + env(pay(g2, m5, g2["HKD"](10))); + env(pay(g2, m6, g2["HKD"](10))); + env(pay(g2, mm, g2["HKD"](1000))); + env.close(); + + env(offer(mm, g1["HKD"](1000), g2["HKD"](100))); + env.close(); + + auto cache = + std::make_shared(env.current(), env.app().getJournal("AssetCache")); + Pathfinder pf( + cache, + a1.id(), + a2.id(), + g1["HKD"].currency, + std::nullopt, + a2["HKD"](60), +>>>>>>> 362775e809fd6980492750b09a40fed7d205a9af + std::nullopt, + std::nullopt, + env.app()); + + BEAST_EXPECT(pf.findPaths(7)); + pf.computePathRanks(5); + + STPath fullLiquidityPath; +<<<<<<< HEAD + auto bestPaths = pf.getBestPaths(5, fullLiquidityPath, STPathSet{}, A1.id()); +======= + auto bestPaths = pf.getBestPaths(5, fullLiquidityPath, STPathSet{}, a1.id()); +>>>>>>> 362775e809fd6980492750b09a40fed7d205a9af + BEAST_EXPECT(bestPaths.size() == 5); + BEAST_EXPECT(!fullLiquidityPath.empty()); + + if (!fullLiquidityPath.empty()) +<<<<<<< HEAD + bestPaths.push_back(fullLiquidityPath); +======= + bestPaths.pushBack(fullLiquidityPath); +>>>>>>> 362775e809fd6980492750b09a40fed7d205a9af + BEAST_EXPECT(bestPaths.size() == 6); + } + void issuesPathNegativeIssue(bool const domainEnabled) { @@ -1907,6 +2197,13 @@ class Path_test : public beast::unit_test::Suite hybridOfferPath(); ammDomainPath(); +<<<<<<< HEAD + pathfind_paths_computed_never_exceeds_six(); + pathfind_can_return_six_paths_with_append(); +======= + pathfindPathsComputedNeverExceedsSix(); + pathfindCanReturnSixPathsWithAppend(); +>>>>>>> 362775e809fd6980492750b09a40fed7d205a9af } }; diff --git a/src/xrpld/rpc/detail/Pathfinder.cpp b/src/xrpld/rpc/detail/Pathfinder.cpp index daa50cfb079..d1b64a01636 100644 --- a/src/xrpld/rpc/detail/Pathfinder.cpp +++ b/src/xrpld/rpc/detail/Pathfinder.cpp @@ -1406,11 +1406,12 @@ Pathfinder::initPathTable() fillPaths( PaymentType::NonXrpToXrp, - {{1, "sxd"}, // gateway buys XRP - {2, "saxd"}, // source -> gateway -> book(XRP) -> dest + {{1, "sxd"}, // gateway buys XRP + {2, "saxd"}, // source -> gateway -> book(XRP) -> dest + {5, "sabxd"}, // source -> gateway -> book -> book(XRP) -> dest {6, "saaxd"}, {7, "sbxd"}, - {8, "sabxd"}, + {8, "sabbxd"}, // source -> gateway -> book -> book -> book(XRP) -> dest {9, "sabaxd"}}); // non-XRP to non-XRP (same currency)