diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 51c038a037..ad53e90aad 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -761,10 +761,8 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest) return rpcError(rpcINVALID_PARAMS); } - STPathSet spsComputed; - std::vector vpsExpanded; - - Pathfinder pf(raSrc, raDst, uSrcCurrencyID, uSrcIssuerID, saDstAmount); + STPathSet spsComputed; + Pathfinder pf(raSrc, raDst, uSrcCurrencyID, uSrcIssuerID, saDstAmount); if (!pf.findPaths(5, 1, spsComputed)) { @@ -772,37 +770,40 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest) } else { - STAmount saMaxAmountAct; - STAmount saDstAmountAct; - STAmount saMaxAmount( - uSrcCurrencyID, - !!uSrcIssuerID - ? uSrcIssuerID - : !!uSrcCurrencyID - ? raSrc.getAccountID() - : ACCOUNT_XRP, - 1); + std::vector vpsExpanded; + STAmount saMaxAmountAct; + STAmount saDstAmountAct; + STAmount saMaxAmount( + uSrcCurrencyID, + !!uSrcIssuerID + ? uSrcIssuerID + : !!uSrcCurrencyID + ? raSrc.getAccountID() + : ACCOUNT_XRP, + 1); saMaxAmount.negate(); - cLog(lsDEBUG) << "ripple_path_find: PATHS: " << spsComputed.size(); - TER terResult = RippleCalc::rippleCalc( lesSnapshot, - saMaxAmountAct, - saDstAmountAct, - vpsExpanded, + saMaxAmountAct, // <-- + saDstAmountAct, // <-- + vpsExpanded, // <-- saMaxAmount, // --> Amount to send is unlimited to get an estimate. saDstAmount, // --> Amount to deliver. raDst.getAccountID(), // --> Account to deliver to. raSrc.getAccountID(), // --> Account sending from. spsComputed, // --> Path set. false, // --> Don't allow partial payment. This is for normal fill or kill payments. - // Must achive delivery goal. + // Must achieve delivery goal. false, // --> Don't limit quality. Average quality is wanted for normal payments. - false, // --> Allow direct ripple. + false, // --> Allow direct ripple to be added to path set. to path set. true); // --> Stand alone mode, no point in deleting unfundeds. + // cLog(lsDEBUG) << "ripple_path_find: PATHS IN: " << spsComputed.size() << " : " << spsComputed.getJson(0); + // cLog(lsDEBUG) << "ripple_path_find: PATHS EXP: " << vpsExpanded.size(); + + cLog(lsDEBUG) << boost::str(boost::format("ripple_path_find: saMaxAmount=%s saDstAmount=%s saMaxAmountAct=%s saDstAmountAct=%s") % saMaxAmount @@ -816,7 +817,9 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest) STPathSet spsCanonical; - RippleCalc::setCanonical(spsCanonical, vpsExpanded); + // Reuse the expanded as it would need to be calcuated anyway to produce the canonical. + // (At least unless we make a direct canonical.) + RippleCalc::setCanonical(spsCanonical, vpsExpanded, false); jvEntry["source_amount"] = saMaxAmountAct.getJson(0); // jvEntry["paths_expanded"] = vpsExpanded.getJson(0); @@ -840,6 +843,7 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest) } } + // Each alternative differs by source currency. jvResult["alternatives"] = jvArray; } diff --git a/src/cpp/ripple/RippleCalc.cpp b/src/cpp/ripple/RippleCalc.cpp index 6811375535..8919a848e1 100644 --- a/src/cpp/ripple/RippleCalc.cpp +++ b/src/cpp/ripple/RippleCalc.cpp @@ -580,24 +580,39 @@ void PathState::setCanonical( % getJson()); } -void RippleCalc::setCanonical(STPathSet& spsDst, const std::vector& vpsExpanded) +void RippleCalc::setCanonical(STPathSet& spsDst, const std::vector& vpsExpanded, bool bKeepDefault) { + // cLog(lsDEBUG) << boost::str(boost::format("SET: setCanonical> %d") % vpsExpanded.size()); + BOOST_FOREACH(PathState::ref pspExpanded, vpsExpanded) { - PathState psCanonical(*pspExpanded, false); - - psCanonical.setCanonical(*pspExpanded); - - STPath spCanonical; - - BOOST_FOREACH(const PaymentNode& pnElem, psCanonical.vpnNodes) + // Obvious defaults have 2 nodes when expanded. + if (bKeepDefault || 2 != pspExpanded->vpnNodes.size()) { - STPathElement speElem(pnElem.uFlags, pnElem.uAccountID, pnElem.uCurrencyID, pnElem.uIssuerID); - spCanonical.addElement(speElem); - } + PathState psCanonical(*pspExpanded, false); - spsDst.addPath(spCanonical); + // cLog(lsDEBUG) << boost::str(boost::format("SET: setCanonical: %d %d %s") % bKeepDirect % pspExpanded->vpnNodes.size() % pspExpanded->getJson()); + + psCanonical.setCanonical(*pspExpanded); + + // Non-obvious defaults have 0 nodes when canonicalized. + if (bKeepDefault || psCanonical.vpnNodes.size()) + { + STPath spCanonical; + + BOOST_FOREACH(const PaymentNode& pnElem, psCanonical.vpnNodes) + { + STPathElement speElem(pnElem.uFlags, pnElem.uAccountID, pnElem.uCurrencyID, pnElem.uIssuerID); + + spCanonical.addElement(speElem); + } + + spsDst.addPath(spCanonical); + } + } } + + // cLog(lsDEBUG) << boost::str(boost::format("SET: setCanonical< %d") % spsDst.size()); } Json::Value PathState::getJson() const diff --git a/src/cpp/ripple/RippleCalc.h b/src/cpp/ripple/RippleCalc.h index b96418f74f..906dd191fd 100644 --- a/src/cpp/ripple/RippleCalc.h +++ b/src/cpp/ripple/RippleCalc.h @@ -210,7 +210,7 @@ public: const bool bStandAlone ); - static void setCanonical(STPathSet& spsDst, const std::vector& vpsExpanded); + static void setCanonical(STPathSet& spsDst, const std::vector& vpsExpanded, bool bKeepDefault); }; #endif