mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Legacy Pathfinding API improvements:
* Use the cache for source/dest currencies * Allow a search depth and initial paths to be specified in old pathfinding
This commit is contained in:
committed by
Vinnie Falco
parent
fca8fa1b1b
commit
1fe57720c4
@@ -110,14 +110,15 @@ bool PathRequest::needsUpdate (bool newOnly, LedgerIndex index)
|
||||
}
|
||||
}
|
||||
|
||||
bool PathRequest::isValid (Ledger::ref lrLedger)
|
||||
bool PathRequest::isValid (RippleLineCache::ref crCache)
|
||||
{
|
||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||
bValid = raSrcAccount.isSet () && raDstAccount.isSet () && saDstAmount.isPositive ();
|
||||
Ledger::pointer lrLedger = crCache->getLedger ();
|
||||
|
||||
if (bValid)
|
||||
{
|
||||
AccountState::pointer asSrc = getApp().getOPs ().getAccountState (lrLedger, raSrcAccount);
|
||||
AccountState::pointer asSrc = getApp().getOPs ().getAccountState (crCache->getLedger(), raSrcAccount);
|
||||
|
||||
if (!asSrc)
|
||||
{
|
||||
@@ -153,7 +154,7 @@ bool PathRequest::isValid (Ledger::ref lrLedger)
|
||||
{
|
||||
bool includeXRP = !isSetBit (asDst->peekSLE ().getFlags(), lsfDisallowXRP);
|
||||
boost::unordered_set<uint160> usDestCurrID =
|
||||
usAccountDestCurrencies (raDstAccount, lrLedger, includeXRP);
|
||||
usAccountDestCurrencies (raDstAccount, crCache, includeXRP);
|
||||
|
||||
BOOST_FOREACH (const uint160 & uCurrency, usDestCurrID)
|
||||
jvDestCur.append (STAmount::createHumanCurrency (uCurrency));
|
||||
@@ -179,7 +180,7 @@ Json::Value PathRequest::doCreate (Ledger::ref lrLedger, RippleLineCache::ref& c
|
||||
|
||||
if (parseJson (value, true) != PFR_PJ_INVALID)
|
||||
{
|
||||
bValid = isValid (lrLedger);
|
||||
bValid = isValid (cache);
|
||||
|
||||
if (bValid)
|
||||
status = doUpdate (cache, true);
|
||||
@@ -324,7 +325,7 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
||||
|
||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||
|
||||
if (!isValid (cache->getLedger ()))
|
||||
if (!isValid (cache))
|
||||
return jvStatus;
|
||||
jvStatus = Json::objectValue;
|
||||
|
||||
@@ -333,7 +334,7 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
||||
if (sourceCurrencies.empty ())
|
||||
{
|
||||
boost::unordered_set<uint160> usCurrencies =
|
||||
usAccountSourceCurrencies (raSrcAccount, cache->getLedger (), true);
|
||||
usAccountSourceCurrencies (raSrcAccount, cache, true);
|
||||
bool sameAccount = raSrcAccount == raDstAccount;
|
||||
BOOST_FOREACH (const uint160 & c, usCurrencies)
|
||||
{
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
|
||||
~PathRequest ();
|
||||
|
||||
bool isValid (const boost::shared_ptr<Ledger>&);
|
||||
bool isValid (RippleLineCache::ref crCache);
|
||||
bool isValid ();
|
||||
bool isNew ();
|
||||
bool needsUpdate (bool newOnly, LedgerIndex index);
|
||||
|
||||
@@ -202,16 +202,19 @@ bool Pathfinder::findPaths (int iLevel, const unsigned int iMaxPaths, STPathSet&
|
||||
BOOST_FOREACH(const STPath& path, pathsOut)
|
||||
{ // make sure no paths were lost
|
||||
bool found = false;
|
||||
BOOST_FOREACH(const STPath& ePath, mCompletePaths)
|
||||
if (!path.isEmpty ())
|
||||
{
|
||||
if (ePath == path)
|
||||
BOOST_FOREACH(const STPath& ePath, mCompletePaths)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
if (ePath == path)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
mCompletePaths.addPath(path);
|
||||
}
|
||||
if (!found)
|
||||
mCompletePaths.addPath(path);
|
||||
}
|
||||
|
||||
WriteLog (lsDEBUG, Pathfinder) << mCompletePaths.size() << " paths to filter";
|
||||
@@ -385,7 +388,8 @@ STPathSet Pathfinder::filterPaths(int iMaxPaths, STPath& extraPath)
|
||||
return spsDst;
|
||||
}
|
||||
|
||||
boost::unordered_set<uint160> usAccountSourceCurrencies (const RippleAddress& raAccountID, Ledger::ref lrLedger,
|
||||
boost::unordered_set<uint160> usAccountSourceCurrencies (
|
||||
const RippleAddress& raAccountID, RippleLineCache::ref lrCache,
|
||||
bool includeXRP)
|
||||
{
|
||||
boost::unordered_set<uint160> usCurrencies;
|
||||
@@ -395,7 +399,7 @@ boost::unordered_set<uint160> usAccountSourceCurrencies (const RippleAddress& ra
|
||||
usCurrencies.insert (uint160 (CURRENCY_XRP));
|
||||
|
||||
// List of ripple lines.
|
||||
AccountItems rippleLines (raAccountID.getAccountID (), lrLedger, AccountItem::pointer (new RippleState ()));
|
||||
AccountItems& rippleLines (lrCache->getRippleLines (raAccountID.getAccountID ()));
|
||||
|
||||
BOOST_FOREACH (AccountItem::ref item, rippleLines.getItems ())
|
||||
{
|
||||
@@ -415,7 +419,9 @@ boost::unordered_set<uint160> usAccountSourceCurrencies (const RippleAddress& ra
|
||||
return usCurrencies;
|
||||
}
|
||||
|
||||
boost::unordered_set<uint160> usAccountDestCurrencies (const RippleAddress& raAccountID, Ledger::ref lrLedger,
|
||||
boost::unordered_set<uint160> usAccountDestCurrencies (
|
||||
const RippleAddress& raAccountID,
|
||||
RippleLineCache::ref lrCache,
|
||||
bool includeXRP)
|
||||
{
|
||||
boost::unordered_set<uint160> usCurrencies;
|
||||
@@ -424,7 +430,7 @@ boost::unordered_set<uint160> usAccountDestCurrencies (const RippleAddress& raAc
|
||||
usCurrencies.insert (uint160 (CURRENCY_XRP)); // Even if account doesn't exist
|
||||
|
||||
// List of ripple lines.
|
||||
AccountItems rippleLines (raAccountID.getAccountID (), lrLedger, AccountItem::pointer (new RippleState ()));
|
||||
AccountItems& rippleLines (lrCache->getRippleLines (raAccountID.getAccountID ()));
|
||||
|
||||
BOOST_FOREACH (AccountItem::ref item, rippleLines.getItems ())
|
||||
{
|
||||
@@ -474,6 +480,7 @@ int Pathfinder::getPathsOut (RippleCurrency const& currencyID, const uint160& ac
|
||||
|
||||
int count = 0;
|
||||
AccountItems& rippleLines (mRLCache->getRippleLines (accountID));
|
||||
|
||||
BOOST_FOREACH (AccountItem::ref item, rippleLines.getItems ())
|
||||
{
|
||||
RippleState* rspEntry = (RippleState*) item.get ();
|
||||
@@ -635,7 +642,7 @@ void Pathfinder::addLink(
|
||||
bool const bIsEndCurrency = (uEndCurrency == mDstAmount.getCurrency());
|
||||
bool const bIsNoRippleOut = isNoRippleOut (currentPath);
|
||||
|
||||
AccountItems& rippleLines(mRLCache->getRippleLines(uEndAccount));
|
||||
AccountItems& rippleLines (mRLCache->getRippleLines(uEndAccount));
|
||||
|
||||
std::vector< std::pair<int, uint160> > candidates;
|
||||
candidates.reserve(rippleLines.getItems().size());
|
||||
@@ -866,7 +873,7 @@ void Pathfinder::initPathTable()
|
||||
{ // XRP to non-XRP
|
||||
CostedPathList_t& list = mPathTable[pt_XRP_to_nonXRP];
|
||||
|
||||
list.push_back(CostedPath_t(0, makePath("sfd"))); // source -> book -> gateway
|
||||
list.push_back(CostedPath_t(1, makePath("sfd"))); // source -> book -> gateway
|
||||
list.push_back(CostedPath_t(3, makePath("sfad"))); // source -> book -> account -> destination
|
||||
list.push_back(CostedPath_t(5, makePath("sfaad"))); // source -> book -> account -> account -> destination
|
||||
list.push_back(CostedPath_t(6, makePath("sbfd"))); // source -> book -> book -> destination
|
||||
@@ -878,8 +885,8 @@ void Pathfinder::initPathTable()
|
||||
{ // non-XRP to XRP
|
||||
CostedPathList_t& list = mPathTable[pt_nonXRP_to_XRP];
|
||||
|
||||
list.push_back(CostedPath_t(0, makePath("sxd"))); // gateway buys XRP
|
||||
list.push_back(CostedPath_t(1, makePath("saxd"))); // source -> gateway -> book(XRP) -> dest
|
||||
list.push_back(CostedPath_t(1, makePath("sxd"))); // gateway buys XRP
|
||||
list.push_back(CostedPath_t(2, makePath("saxd"))); // source -> gateway -> book(XRP) -> dest
|
||||
list.push_back(CostedPath_t(6, makePath("saaxd")));
|
||||
list.push_back(CostedPath_t(7, makePath("sbxd")));
|
||||
list.push_back(CostedPath_t(8, makePath("sabxd")));
|
||||
|
||||
@@ -136,10 +136,14 @@ private:
|
||||
static const uint32 afAC_LAST = 0x080; // Destination account only
|
||||
};
|
||||
|
||||
boost::unordered_set<uint160> usAccountDestCurrencies (const RippleAddress& raAccountID, Ledger::ref lrLedger,
|
||||
boost::unordered_set<uint160> usAccountDestCurrencies
|
||||
(const RippleAddress& raAccountID,
|
||||
RippleLineCache::ref cache,
|
||||
bool includeXRP);
|
||||
|
||||
boost::unordered_set<uint160> usAccountSourceCurrencies (const RippleAddress& raAccountID, Ledger::ref lrLedger,
|
||||
boost::unordered_set<uint160> usAccountSourceCurrencies
|
||||
(const RippleAddress& raAccountID,
|
||||
RippleLineCache::ref lrLedger,
|
||||
bool includeXRP);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1780,7 +1780,7 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, Resource::Charge&
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::unordered_set<uint160> usCurrencies = usAccountSourceCurrencies (raSrc, lpLedger, true);
|
||||
boost::unordered_set<uint160> usCurrencies = usAccountSourceCurrencies (raSrc, cache, true);
|
||||
|
||||
jvSrcCurrencies = Json::Value (Json::arrayValue);
|
||||
|
||||
@@ -1797,7 +1797,7 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, Resource::Charge&
|
||||
// Fill in currencies destination will accept
|
||||
Json::Value jvDestCur (Json::arrayValue);
|
||||
|
||||
boost::unordered_set<uint160> usDestCurrID = usAccountDestCurrencies (raDst, lpLedger, true);
|
||||
boost::unordered_set<uint160> usDestCurrID = usAccountDestCurrencies (raDst, cache, true);
|
||||
BOOST_FOREACH (const uint160 & uCurrency, usDestCurrID)
|
||||
jvDestCur.append (STAmount::createHumanCurrency (uCurrency));
|
||||
|
||||
@@ -1847,6 +1847,22 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, Resource::Charge&
|
||||
int level = getConfig().PATH_SEARCH_OLD;
|
||||
if ((getConfig().PATH_SEARCH_MAX > level) && !getApp().getFeeTrack().isLoadedLocal())
|
||||
++level;
|
||||
if (params.isMember("depth") && params["depth"].isIntegral())
|
||||
{
|
||||
int rLev = params["search_depth"].asInt ();
|
||||
if ((rLev < level) || (mRole == Config::ADMIN))
|
||||
level = rLev;
|
||||
}
|
||||
|
||||
if (params.isMember("paths"))
|
||||
{
|
||||
STParsedJSON paths ("paths", params["paths"]);
|
||||
if (paths.object.get() == nullptr)
|
||||
return paths.error;
|
||||
else
|
||||
spsComputed = paths.object.get()->downcast<STPathSet> ();
|
||||
}
|
||||
|
||||
STPath extraPath;
|
||||
if (!bValid || !pf.findPaths (level, 4, spsComputed, extraPath))
|
||||
{
|
||||
|
||||
@@ -166,6 +166,24 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class D>
|
||||
D& downcast()
|
||||
{
|
||||
D* ptr = dynamic_cast<D*> (this);
|
||||
if (ptr == nullptr)
|
||||
throw std::runtime_error ("type mismatch");
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
template <class D>
|
||||
D const& downcast() const
|
||||
{
|
||||
D const * ptr = dynamic_cast<D const*> (this);
|
||||
if (ptr == nullptr)
|
||||
throw std::runtime_error ("type mismatch");
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
// VFALCO TODO make accessors for this
|
||||
SField::ptr fName;
|
||||
|
||||
Reference in New Issue
Block a user