Path find cleanup (RIPD-1023)

This commit is contained in:
Miguel Portilla
2015-09-04 19:02:00 -04:00
committed by Vinnie Falco
parent 3af0c38315
commit 20f186d855
10 changed files with 324 additions and 292 deletions

View File

@@ -39,7 +39,7 @@
#include <ripple/app/misc/NetworkOPs.h>
#include <ripple/app/misc/SHAMapStore.h>
#include <ripple/app/misc/Validations.h>
#include <ripple/app/paths/FindPaths.h>
#include <ripple/app/paths/Pathfinder.h>
#include <ripple/app/paths/PathRequests.h>
#include <ripple/app/misc/UniqueNodeList.h>
#include <ripple/app/tx/InboundTransactions.h>
@@ -931,7 +931,7 @@ void ApplicationImp::setup()
m_amendmentTable->addInitial (
config_->section (SECTION_AMENDMENTS));
initializePathfinding ();
Pathfinder::initPathTable();
m_ledgerMaster->setMinValidations (
config_->VALIDATION_QUORUM, config_->LOCK_QUORUM);

View File

@@ -312,8 +312,7 @@ int PathRequest::parseJson (Json::Value const& jvParams)
return PFR_PJ_INVALID;
}
convert_all_ =
saDstAmount == STAmount(saDstAmount.issue(), 1u, 0, true);
convert_all_ = saDstAmount == STAmount(saDstAmount.issue(), 1u, 0, true);
if ((saDstAmount.getCurrency ().isZero () &&
saDstAmount.getIssuer ().isNonZero ()) ||
@@ -447,97 +446,155 @@ void PathRequest::resetLevel (int l)
iLastLevel = l;
}
bool
PathRequest::findPaths (
RippleLineCache::ref cache,
FindPaths& fp, Issue const& issue,
Json::Value& jvArray)
std::unique_ptr<Pathfinder> const&
PathRequest::getPathFinder(RippleLineCache::ref cache,
hash_map<Currency, std::unique_ptr<Pathfinder>>& currency_map,
Currency const& currency, STAmount const& dst_amount,
int const level)
{
STPath fullLiquidityPath;
auto result = fp.findPathsForIssue(issue,
mContext[issue], fullLiquidityPath, app_);
if (! result)
auto i = currency_map.find(currency);
if (i != currency_map.end())
return i->second;
auto pathfinder = std::make_unique<Pathfinder>(
cache, *raSrcAccount, *raDstAccount, currency,
boost::none, dst_amount, saSendMax, app_);
if (pathfinder->findPaths(level))
pathfinder->computePathRanks(max_paths_);
else
pathfinder.reset(); // It's a bad request - clear it.
return currency_map[currency] = std::move(pathfinder);
}
void
PathRequest::findPaths (RippleLineCache::ref cache, int const level,
Json::Value& jvArray)
{
auto sourceCurrencies = sciSourceCurrencies;
if (sourceCurrencies.empty ())
{
m_journal.debug << iIdentifier << " No paths found";
return false;
}
mContext[issue] = *result;
boost::optional<PaymentSandbox> sandbox;
sandbox.emplace(&*cache->getLedger(), tapNONE);
auto& sourceAccount = ! isXRP(issue.account)
? issue.account
: isXRP(issue.currency)
? xrpAccount()
: *raSrcAccount;
STAmount saMaxAmount = saSendMax.value_or(
STAmount({issue.currency, sourceAccount}, 1u, 0, true));
m_journal.debug << iIdentifier
<< " Paths found, calling rippleCalc";
path::RippleCalc::Input rcInput;
if (convert_all_)
rcInput.partialPaymentAllowed = true;
auto rc = path::RippleCalc::rippleCalculate(
*sandbox, saMaxAmount,
convert_all_ ? STAmount(saDstAmount.issue(), STAmount::cMaxValue,
STAmount::cMaxOffset) : saDstAmount,
*raDstAccount, *raSrcAccount, *result,
app_.logs (), &rcInput);
if (! convert_all_ &&
! fullLiquidityPath.empty() &&
(rc.result() == terNO_LINE || rc.result() == tecPATH_PARTIAL))
{
m_journal.debug << iIdentifier
<< " Trying with an extra path element";
result->push_back(fullLiquidityPath);
sandbox.emplace(&*cache->getLedger(), tapNONE);
rc = path::RippleCalc::rippleCalculate(
*sandbox, saMaxAmount, saDstAmount,
*raDstAccount, *raSrcAccount, *result, app_.logs ());
if (rc.result() != tesSUCCESS)
auto usCurrencies =
accountSourceCurrencies(*raSrcAccount, cache, true);
bool sameAccount = *raSrcAccount == *raDstAccount;
for (auto const& c : usCurrencies)
{
m_journal.warning << iIdentifier
<< " Failed with covering path "
<< transHuman(rc.result());
if (!sameAccount || (c != saDstAmount.getCurrency()))
{
sourceCurrencies.insert(
{c, c.isZero() ? xrpAccount() : *raSrcAccount});
}
}
}
auto const dst_amount = convert_all_ ?
STAmount(saDstAmount.issue(), STAmount::cMaxValue, STAmount::cMaxOffset)
: saDstAmount;
hash_map<Currency, std::unique_ptr<Pathfinder>> currency_map;
for (auto const& issue : sourceCurrencies)
{
JLOG(m_journal.debug)
<< iIdentifier
<< " Trying to find paths: "
<< STAmount(issue, 1).getFullText();
auto& pathfinder = getPathFinder(cache, currency_map,
issue.currency, dst_amount, level);
if (! pathfinder)
{
assert(false);
m_journal.debug << iIdentifier << " No paths found";
continue;
}
STPath fullLiquidityPath;
auto ps = pathfinder->getBestPaths(max_paths_,
fullLiquidityPath, mContext[issue], issue.account);
mContext[issue] = ps;
auto& sourceAccount = ! isXRP(issue.account)
? issue.account
: isXRP(issue.currency)
? xrpAccount()
: *raSrcAccount;
STAmount saMaxAmount = saSendMax.value_or(
STAmount({issue.currency, sourceAccount}, 1u, 0, true));
m_journal.debug << iIdentifier
<< " Paths found, calling rippleCalc";
path::RippleCalc::Input rcInput;
if (convert_all_)
rcInput.partialPaymentAllowed = true;
auto sandbox = std::make_unique<PaymentSandbox>
(&*cache->getLedger(), tapNONE);
auto rc = path::RippleCalc::rippleCalculate(
*sandbox,
saMaxAmount, // --> Amount to send is unlimited
// to get an estimate.
dst_amount, // --> Amount to deliver.
*raDstAccount, // --> Account to deliver to.
*raSrcAccount, // --> Account sending from.
ps, // --> Path set.
app_.logs(),
&rcInput);
if (! convert_all_ &&
! fullLiquidityPath.empty() &&
(rc.result() == terNO_LINE || rc.result() == tecPATH_PARTIAL))
{
m_journal.debug << iIdentifier
<< " Trying with an extra path element";
ps.push_back(fullLiquidityPath);
sandbox = std::make_unique<PaymentSandbox>
(&*cache->getLedger(), tapNONE);
rc = path::RippleCalc::rippleCalculate(
*sandbox,
saMaxAmount, // --> Amount to send is unlimited
// to get an estimate.
dst_amount, // --> Amount to deliver.
*raDstAccount, // --> Account to deliver to.
*raSrcAccount, // --> Account sending from.
ps, // --> Path set.
app_.logs());
if (rc.result() != tesSUCCESS)
{
m_journal.warning << iIdentifier
<< " Failed with covering path "
<< transHuman(rc.result());
}
else
{
m_journal.debug << iIdentifier
<< " Extra path element gives "
<< transHuman(rc.result());
}
}
if (rc.result () == tesSUCCESS)
{
Json::Value jvEntry (Json::objectValue);
rc.actualAmountIn.setIssuer (sourceAccount);
jvEntry[jss::source_amount] = rc.actualAmountIn.getJson (0);
jvEntry[jss::paths_computed] = ps.getJson(0);
if (convert_all_)
jvEntry[jss::destination_amount] = rc.actualAmountOut.getJson(0);
if (hasCompletion ())
{
// Old ripple_path_find API requires this
jvEntry[jss::paths_canonical] = Json::arrayValue;
}
jvArray.append (jvEntry);
}
else
{
m_journal.debug << iIdentifier
<< " Extra path element gives "
m_journal.debug << iIdentifier << " rippleCalc returns "
<< transHuman(rc.result());
}
}
if (rc.result () == tesSUCCESS)
{
Json::Value jvEntry (Json::objectValue);
rc.actualAmountIn.setIssuer (sourceAccount);
jvEntry[jss::source_amount] = rc.actualAmountIn.getJson (0);
jvEntry[jss::paths_computed] = result->getJson(0);
if (convert_all_)
jvEntry[jss::destination_amount] = rc.actualAmountOut.getJson(0);
if (hasCompletion ())
{
// Old ripple_path_find API requires this
jvEntry[jss::paths_canonical] = Json::arrayValue;
}
jvArray.append (jvEntry);
return true;
}
m_journal.debug << iIdentifier << " rippleCalc returns "
<< transHuman (rc.result ());
return false;
}
Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
@@ -550,25 +607,6 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
return jvStatus;
jvStatus = Json::objectValue;
auto sourceCurrencies = sciSourceCurrencies;
if (sourceCurrencies.empty ())
{
auto usCurrencies =
accountSourceCurrencies (*raSrcAccount, cache, true);
bool sameAccount = *raSrcAccount == *raDstAccount;
for (auto const& c: usCurrencies)
{
if (!sameAccount || (c != saDstAmount.getCurrency ()))
{
if (c.isZero ())
sourceCurrencies.insert ({c, xrpAccount()});
else
sourceCurrencies.insert ({c, *raSrcAccount});
}
}
}
if (hasCompletion ())
{
// Old ripple_path_find API gives destination_currencies
@@ -622,29 +660,10 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
m_journal.debug << iIdentifier << " processing at level " << iLevel;
bool found = false;
Json::Value jvArray = Json::arrayValue;
FindPaths fp (
cache,
*raSrcAccount,
*raDstAccount,
convert_all_ ? STAmount(saDstAmount.issue(), STAmount::cMaxValue,
STAmount::cMaxOffset) : saDstAmount,
saSendMax,
iLevel,
4); // iMaxPaths
for (auto const& i: sourceCurrencies)
{
JLOG(m_journal.debug)
<< iIdentifier
<< " Trying to find paths: "
<< STAmount(i, 1).getFullText();
if (findPaths(cache, fp, i, jvArray))
found = true;
}
findPaths(cache, iLevel, jvArray);
bLastSuccess = jvArray.size();
iLastLevel = iLevel;
bLastSuccess = found;
if (fast && ptQuickReply.is_not_a_date_time())
{

View File

@@ -21,7 +21,7 @@
#define RIPPLE_APP_PATHS_PATHREQUEST_H_INCLUDED
#include <ripple/app/ledger/Ledger.h>
#include <ripple/app/paths/FindPaths.h>
#include <ripple/app/paths/Pathfinder.h>
#include <ripple/app/paths/RippleLineCache.h>
#include <ripple/json/json_value.h>
#include <ripple/net/InfoSub.h>
@@ -98,10 +98,13 @@ private:
void setValid ();
void resetLevel (int level);
bool
findPaths (RippleLineCache::ref,
FindPaths&, Issue const&,
Json::Value& jvArray);
std::unique_ptr<Pathfinder> const&
getPathFinder(RippleLineCache::ref,
hash_map<Currency, std::unique_ptr<Pathfinder>>&, Currency const&,
STAmount const&, int const);
void
findPaths (RippleLineCache::ref, int const, Json::Value&);
int parseJson (Json::Value const&);
@@ -141,6 +144,8 @@ private:
boost::posix_time::ptime ptCreated;
boost::posix_time::ptime ptQuickReply;
boost::posix_time::ptime ptFullReply;
static unsigned int const max_paths_ = 4;
};
} // ripple

View File

@@ -18,7 +18,6 @@
//==============================================================================
#include <BeastConfig.h>
#include <ripple/basics/Log.h>
#include <ripple/json/json_reader.h>
#include <ripple/json/to_string.h>
#include <ripple/protocol/JsonFields.h>
@@ -151,16 +150,17 @@ find_paths(jtx::Env& env,
jvCurrency[jss::currency] = to_string(c);
jvSrcCurrencies.append(jvCurrency);
}
auto const convert_all =
saDstAmount == STAmount(saDstAmount.issue(), 1u, 0, true);
auto result = ripplePathFind(cache, src.id(), dst.id(),
saDstAmount, jvSrcCurrencies, boost::none, level, saSendMax,
saDstAmount == STAmount(saDstAmount.issue(), 1u, 0, true), env.app ());
(convert_all ? STAmount(saDstAmount.issue(), STAmount::cMaxValue,
STAmount::cMaxOffset) : saDstAmount), jvSrcCurrencies, boost::none,
level, saSendMax, convert_all, env.app());
if (! result.first)
{
throw std::runtime_error(
"Path_test::findPath: ripplePathFind find failed");
}
auto const& jv = result.second[0u];
Json::Value paths;
paths["Paths"] = jv["paths_computed"];

View File

@@ -31,7 +31,7 @@ ripplePathFind (RippleLineCache::pointer const& cache,
STAmount const& saDstAmount,
Json::Value const& jvSrcCurrencies,
boost::optional<Json::Value> const& contextPaths,
int const& level, boost::optional<STAmount> saSendMax,
int const level, boost::optional<STAmount> saSendMax,
bool convert_all, Application& app);
}

View File

@@ -23,7 +23,6 @@
#include <ripple/app/main/Application.h>
#include <ripple/app/misc/NetworkOPs.h>
#include <ripple/app/paths/AccountCurrencies.h>
#include <ripple/app/paths/FindPaths.h>
#include <ripple/app/paths/PathRequest.h>
#include <ripple/app/paths/PathRequests.h>
#include <ripple/app/paths/RippleCalc.h>
@@ -48,6 +47,8 @@
namespace ripple {
static unsigned int const max_paths = 4;
static
Json::Value
buildSrcCurrencies(AccountID const& account,
@@ -246,9 +247,11 @@ Json::Value doRipplePathFind (RPC::Context& context)
auto contextPaths = context.params.isMember(jss::paths) ?
boost::optional<Json::Value>(context.params[jss::paths]) :
boost::optional<Json::Value>(boost::none);
auto pathFindResult = ripplePathFind(cache, raSrc, raDst, saDstAmount,
jvSrcCurrencies, contextPaths, level, saSendMax, convert_all,
context.app);
auto pathFindResult = ripplePathFind(
cache, raSrc, raDst, (convert_all ? STAmount(saDstAmount.issue(),
STAmount::cMaxValue, STAmount::cMaxOffset) : saDstAmount),
jvSrcCurrencies, contextPaths, level, saSendMax,
convert_all, context.app);
if (!pathFindResult.first)
return pathFindResult.second;
@@ -262,26 +265,35 @@ Json::Value doRipplePathFind (RPC::Context& context)
return jvResult;
}
std::unique_ptr<Pathfinder> const&
getPathFinder(RippleLineCache::ref cache, AccountID const& raSrc,
AccountID const& raDst, boost::optional<STAmount> saSendMax,
hash_map<Currency, std::unique_ptr<Pathfinder>>& currency_map,
Currency const& currency, STAmount const& dst_amount,
int const level, Application& app)
{
auto i = currency_map.find(currency);
if (i != currency_map.end())
return i->second;
auto pathfinder = std::make_unique<Pathfinder>(cache, raSrc, raDst,
currency, boost::none, dst_amount, saSendMax, app);
if (pathfinder->findPaths(level))
pathfinder->computePathRanks(max_paths);
else
pathfinder.reset(); // It's a bad request - clear it.
return currency_map[currency] = std::move(pathfinder);
}
std::pair<bool, Json::Value>
ripplePathFind (RippleLineCache::pointer const& cache,
AccountID const& raSrc, AccountID const& raDst,
STAmount const& saDstAmount, Json::Value const& jvSrcCurrencies,
boost::optional<Json::Value> const& contextPaths,
int const& level, boost::optional<STAmount> saSendMax,
int const level, boost::optional<STAmount> saSendMax,
bool convert_all, Application& app)
{
auto const sa = STAmount(saDstAmount.issue(),
STAmount::cMaxValue, STAmount::cMaxOffset);
FindPaths fp(
cache,
raSrc,
raDst,
convert_all ? sa : saDstAmount,
saSendMax,
level,
4); // max paths
Json::Value jvArray(Json::arrayValue);
hash_map<Currency, std::unique_ptr<Pathfinder>> currency_map;
auto j = app.journal ("RPCHandler");
@@ -350,118 +362,111 @@ ripplePathFind (RippleLineCache::pointer const& cache,
STParsedJSONObject paths("pathSet", pathSet);
if (! paths.object)
return std::make_pair(false, paths.error);
else
{
spsComputed = paths.object->getFieldPathSet(sfPaths);
JLOG (j.trace) << "ripple_path_find: Paths: " <<
spsComputed.getJson(0);
}
spsComputed = paths.object->getFieldPathSet(sfPaths);
JLOG (j.trace) << "ripple_path_find: Paths: " <<
spsComputed.getJson(0);
}
auto& pathfinder = getPathFinder(cache, raSrc, raDst, saSendMax,
currency_map, issue.currency, saDstAmount, level, app);
if (! pathfinder)
{
JLOG (j.warning) << "ripple_path_find: No paths found.";
continue;
}
STPath fullLiquidityPath;
auto result = fp.findPathsForIssue(
issue,
spsComputed,
fullLiquidityPath,
app);
if (! result)
auto ps = pathfinder->getBestPaths(max_paths,
fullLiquidityPath, spsComputed, issue.account);
auto& issuer =
isXRP(uSrcIssuerID) ?
isXRP(uSrcCurrencyID) ? // Default to source account.
xrpAccount() :
(raSrc)
: uSrcIssuerID; // Use specifed issuer.
STAmount saMaxAmount = saSendMax.value_or(
STAmount({uSrcCurrencyID, issuer}, 1u, 0, true));
boost::optional<PaymentSandbox> sandbox;
sandbox.emplace(&*cache->getLedger(), tapNONE);
assert(sandbox->open());
path::RippleCalc::Input rcInput;
if (convert_all)
rcInput.partialPaymentAllowed = true;
auto rc = path::RippleCalc::rippleCalculate(
*sandbox,
saMaxAmount, // --> Amount to send is unlimited
// to get an estimate.
saDstAmount, // --> Amount to deliver.
raDst, // --> Account to deliver to.
raSrc, // --> Account sending from.
ps, // --> Path set.
app.logs(),
&rcInput);
JLOG(j.warning)
<< "ripple_path_find:"
<< " saMaxAmount=" << saMaxAmount
<< " saDstAmount=" << saDstAmount
<< " saMaxAmountAct=" << rc.actualAmountIn
<< " saDstAmountAct=" << rc.actualAmountOut;
if (! convert_all &&
! fullLiquidityPath.empty() &&
(rc.result() == terNO_LINE || rc.result() == tecPATH_PARTIAL))
{
JLOG (j.warning)
<< "ripple_path_find: No paths found.";
auto jpr = app.journal("PathRequest");
JLOG(jpr.debug)
<< "Trying with an extra path element";
ps.push_back(fullLiquidityPath);
sandbox.emplace(&*cache->getLedger(), tapNONE);
assert(sandbox->open());
rc = path::RippleCalc::rippleCalculate(
*sandbox,
saMaxAmount, // --> Amount to send is unlimited
// to get an estimate.
saDstAmount, // --> Amount to deliver.
raDst, // --> Account to deliver to.
raSrc, // --> Account sending from.
ps, // --> Path set.
app.logs());
JLOG(jpr.debug)
<< "Extra path element gives "
<< transHuman(rc.result());
}
if (rc.result() == tesSUCCESS)
{
Json::Value jvEntry(Json::objectValue);
STPathSet spsCanonical;
// Reuse the expanded as it would need to be calcuated
// anyway to produce the canonical. (At least unless we
// make a direct canonical.)
jvEntry[jss::source_amount] = rc.actualAmountIn.getJson(0);
jvEntry[jss::paths_canonical] = Json::arrayValue;
jvEntry[jss::paths_computed] = ps.getJson(0);
if (convert_all)
jvEntry[jss::destination_amount] = rc.actualAmountOut.getJson(0);
jvArray.append(jvEntry);
}
else
{
auto& issuer =
isXRP(uSrcIssuerID) ?
isXRP(uSrcCurrencyID) ? // Default to source account.
xrpAccount() :
(raSrc)
: uSrcIssuerID; // Use specifed issuer.
STAmount saMaxAmount = saSendMax.value_or(
STAmount({uSrcCurrencyID, issuer}, 1u, 0, true));
boost::optional<PaymentSandbox> sandbox;
sandbox.emplace(&*cache->getLedger(), tapNONE);
assert(sandbox->open());
path::RippleCalc::Input rcInput;
if (convert_all)
rcInput.partialPaymentAllowed = true;
auto rc = path::RippleCalc::rippleCalculate(
*sandbox,
saMaxAmount, // --> Amount to send is unlimited
// to get an estimate.
convert_all ? sa : saDstAmount, // --> Amount to deliver.
raDst, // --> Account to deliver to.
raSrc, // --> Account sending from.
*result, // --> Path set.
app.logs (),
&rcInput);
JLOG (j.warning)
<< "ripple_path_find:"
<< " saMaxAmount=" << saMaxAmount
<< " saDstAmount=" << saDstAmount
<< " saMaxAmountAct=" << rc.actualAmountIn
<< " saDstAmountAct=" << rc.actualAmountOut;
if (! convert_all &&
! fullLiquidityPath.empty() &&
(rc.result() == terNO_LINE || rc.result() == tecPATH_PARTIAL))
{
auto jpr = app.journal ("PathRequest");
JLOG (jpr.debug)
<< "Trying with an extra path element";
result->push_back(fullLiquidityPath);
sandbox.emplace(&*cache->getLedger(), tapNONE);
assert(sandbox->open());
rc = path::RippleCalc::rippleCalculate(
*sandbox,
saMaxAmount, // --> Amount to send is unlimited
// to get an estimate.
saDstAmount, // --> Amount to deliver.
raDst, // --> Account to deliver to.
raSrc, // --> Account sending from.
*result, // --> Path set.
app.logs ());
JLOG (jpr.debug)
<< "Extra path element gives "
<< transHuman(rc.result());
}
if (rc.result() == tesSUCCESS)
{
Json::Value jvEntry(Json::objectValue);
STPathSet spsCanonical;
// Reuse the expanded as it would need to be calcuated
// anyway to produce the canonical. (At least unless we
// make a direct canonical.)
jvEntry[jss::source_amount] = rc.actualAmountIn.getJson(0);
jvEntry[jss::paths_canonical] = Json::arrayValue;
jvEntry[jss::paths_computed] = result->getJson(0);
if (convert_all)
jvEntry[jss::destination_amount] = rc.actualAmountOut.getJson(0);
jvArray.append(jvEntry);
}
else
{
std::string strToken;
std::string strHuman;
transResultInfo(rc.result(), strToken, strHuman);
JLOG (j.debug)
<< "ripple_path_find: "
<< strToken << " "
<< strHuman << " "
<< spsComputed.getJson(0);
}
std::string strToken;
std::string strHuman;
transResultInfo(rc.result(), strToken, strHuman);
JLOG (j.debug)
<< "ripple_path_find: "
<< strToken << " "
<< strHuman << " "
<< spsComputed.getJson(0);
}
}

View File

@@ -20,7 +20,8 @@
#include <BeastConfig.h>
#include <ripple/rpc/impl/TransactionSign.h>
#include <ripple/app/ledger/LedgerMaster.h>
#include <ripple/app/paths/FindPaths.h>
#include <ripple/app/main/Application.h>
#include <ripple/app/paths/Pathfinder.h>
#include <ripple/basics/Log.h>
#include <ripple/core/LoadFeeTrack.h>
#include <ripple/json/json_writer.h>
@@ -192,33 +193,30 @@ static Json::Value checkPayment(
if (!lpf.isOk ())
return rpcError (rpcTOO_BUSY);
STPath fullLiquidityPath;
auto cache = std::make_shared<RippleLineCache> (ledger);
auto result = findPathsForOneIssuer (
cache,
srcAddressID,
*dstAccountID,
sendMax.issue(),
amount,
app.config().PATH_SEARCH_OLD,
4, // iMaxPaths
{},
fullLiquidityPath,
app);
STPathSet result;
if (ledger)
{
Pathfinder pf(std::make_shared<RippleLineCache>(ledger),
srcAddressID, *dstAccountID, sendMax.issue().currency,
sendMax.issue().account, amount, boost::none, app);
if (pf.findPaths(app.config().PATH_SEARCH_OLD))
{
// 4 is the maxium paths
pf.computePathRanks(4);
STPath fullLiquidityPath;
STPathSet paths;
result = pf.getBestPaths(4, fullLiquidityPath, paths,
sendMax.issue().account);
}
}
auto j = app.journal ("RPCHandler");
if (! result)
{
JLOG (j.debug)
<< "transactionSign: build_path: No paths found.";
return rpcError (rpcNO_PATH);
}
JLOG (j.debug)
<< "transactionSign: build_path: "
<< result->getJson (0);
<< result.getJson (0);
if (! result->empty ())
tx_json[jss::Paths] = result->getJson (0);
if (! result.empty ())
tx_json[jss::Paths] = result.getJson (0);
}
}
return Json::Value();

View File

@@ -30,7 +30,7 @@
#include <ripple/test/jtx/utility.h>
#include <ripple/app/tx/apply.h>
#include <ripple/app/ledger/LedgerTiming.h>
#include <ripple/app/paths/FindPaths.h>
#include <ripple/app/paths/Pathfinder.h>
#include <ripple/basics/Slice.h>
#include <ripple/json/to_string.h>
#include <ripple/protocol/ErrorCodes.h>
@@ -87,7 +87,7 @@ Env::Env (beast::unit_test::suite& test_)
, openLedger (closed_, app().config(), cachedSLEs_, journal)
{
memoize(master);
initializePathfinding();
Pathfinder::initPathTable();
}
std::shared_ptr<ReadView const>

View File

@@ -18,8 +18,8 @@
//==============================================================================
#include <BeastConfig.h>
#include <ripple/app/paths/Pathfinder.h>
#include <ripple/test/jtx/paths.h>
#include <ripple/app/paths/FindPaths.h>
#include <ripple/protocol/JsonFields.h>
namespace ripple {
@@ -36,16 +36,22 @@ paths::operator()(Env& env, JTx& jt) const
jv[jss::Destination].asString());
auto const amount = amountFromJson(
sfAmount, jv[jss::Amount]);
Pathfinder pf (
std::make_shared<RippleLineCache>(env.open()),
from, to, in_.currency, in_.account,
amount, boost::none, env.app());
if (! pf.findPaths(depth_))
return;
STPath fp;
auto const found = findPathsForOneIssuer(
std::make_shared<RippleLineCache>(
env.open()), from, to,
in_, amount,
depth_, limit_, {}, fp, env.app());
pf.computePathRanks (limit_);
auto const found = pf.getBestPaths(
limit_, fp, {}, in_.account);
// VFALCO TODO API to allow caller to examine the STPathSet
// VFALCO isDefault should be renamed to empty()
if (found && ! found->isDefault())
jv[jss::Paths] = found->getJson(0);
if (! found.isDefault())
jv[jss::Paths] = found.getJson(0);
}
//------------------------------------------------------------------------------

View File

@@ -22,7 +22,6 @@
#include <ripple/app/paths/RippleState.cpp>
#include <ripple/app/paths/AccountCurrencies.cpp>
#include <ripple/app/paths/Credit.cpp>
#include <ripple/app/paths/FindPaths.cpp>
#include <ripple/app/paths/Pathfinder.cpp>
#include <ripple/app/paths/Node.cpp>
#include <ripple/app/paths/PathRequest.cpp>