mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-01 00:15:51 +00:00
Cosmetic changes for path finding.
This commit is contained in:
@@ -36,27 +36,24 @@ Test XRP to USD
|
||||
Test USD to EUR
|
||||
*/
|
||||
|
||||
|
||||
// we sort the options by:
|
||||
// cost of path
|
||||
// length of path
|
||||
// width of path
|
||||
// correct currency at the end
|
||||
|
||||
|
||||
|
||||
bool sortPathOptions(PathOption::pointer first, PathOption::pointer second)
|
||||
{
|
||||
if(first->mTotalCost<second->mTotalCost) return(true);
|
||||
if(first->mTotalCost>second->mTotalCost) return(false);
|
||||
if (first->mTotalCost<second->mTotalCost) return(true);
|
||||
if (first->mTotalCost>second->mTotalCost) return(false);
|
||||
|
||||
if(first->mCorrectCurrency && !second->mCorrectCurrency) return(true);
|
||||
if(!first->mCorrectCurrency && second->mCorrectCurrency) return(false);
|
||||
if (first->mCorrectCurrency && !second->mCorrectCurrency) return(true);
|
||||
if (!first->mCorrectCurrency && second->mCorrectCurrency) return(false);
|
||||
|
||||
if(first->mPath.getElementCount()<second->mPath.getElementCount()) return(true);
|
||||
if(first->mPath.getElementCount()>second->mPath.getElementCount()) return(false);
|
||||
if (first->mPath.getElementCount()<second->mPath.getElementCount()) return(true);
|
||||
if (first->mPath.getElementCount()>second->mPath.getElementCount()) return(false);
|
||||
|
||||
if(first->mMinWidth<second->mMinWidth) return true;
|
||||
if (first->mMinWidth<second->mMinWidth) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -76,98 +73,115 @@ PathOption::PathOption(PathOption::pointer other)
|
||||
}
|
||||
|
||||
|
||||
Pathfinder::Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount) :
|
||||
Pathfinder::Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount) :
|
||||
mSrcAccountID(srcAccountID.getAccountID()), mDstAccountID(dstAccountID.getAccountID()), mDstAmount(dstAmount), mSrcCurrencyID(srcCurrencyID), mOrderBook(theApp->getMasterLedger().getCurrentLedger())
|
||||
{
|
||||
mLedger=theApp->getMasterLedger().getCurrentLedger();
|
||||
}
|
||||
|
||||
// Returns a single path, if possible.
|
||||
// --> maxSearchSteps: unused
|
||||
// --> maxPay: unused
|
||||
bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet)
|
||||
{
|
||||
if(mLedger) {
|
||||
std::queue<STPath> pqueue;
|
||||
STPathElement ele(mSrcAccountID,
|
||||
mSrcCurrencyID,
|
||||
uint160());
|
||||
STPath path;
|
||||
path.addElement(ele);
|
||||
pqueue.push(path);
|
||||
while(pqueue.size()) {
|
||||
if (mLedger) {
|
||||
std::queue<STPath> pqueue;
|
||||
STPathElement ele(mSrcAccountID,
|
||||
mSrcCurrencyID,
|
||||
uint160());
|
||||
STPath path;
|
||||
|
||||
STPath path = pqueue.front();
|
||||
pqueue.pop();
|
||||
// get the first path from the queue
|
||||
path.addElement(ele); // Add the source.
|
||||
|
||||
ele = path.mPath.back();
|
||||
// get the last node from the path
|
||||
pqueue.push(path);
|
||||
|
||||
if (ele.mAccountID == mDstAccountID) {
|
||||
path.mPath.erase(path.mPath.begin());
|
||||
path.mPath.erase(path.mPath.begin() + path.mPath.size()-1);
|
||||
if (path.mPath.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
retPathSet.addPath(path);
|
||||
return true;
|
||||
}
|
||||
// found the destination
|
||||
while (pqueue.size()) {
|
||||
STPath path = pqueue.front();
|
||||
|
||||
if (!ele.mCurrencyID) {
|
||||
BOOST_FOREACH(OrderBook::pointer book,mOrderBook.getXRPInBooks())
|
||||
{
|
||||
//if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
|
||||
{
|
||||
pqueue.pop(); // Pop the first path from the queue.
|
||||
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
|
||||
new_path.mPath.push_back(new_ele);
|
||||
new_path.mCurrencyID = book->getCurrencyOut();
|
||||
new_path.mCurrentAccount = book->getCurrencyOut();
|
||||
ele = path.mPath.back(); // Get the last node from the path.
|
||||
|
||||
pqueue.push(new_path);
|
||||
// Determine if path is solved.
|
||||
if (ele.mAccountID == mDstAccountID) {
|
||||
// Found a path to the destination.
|
||||
|
||||
}
|
||||
}
|
||||
if (2 == path.mPath.size()) {
|
||||
// Empty path is default. Drop it.
|
||||
continue;
|
||||
}
|
||||
|
||||
} else {
|
||||
RippleLines rippleLines(ele.mAccountID);
|
||||
BOOST_FOREACH(RippleState::pointer line,rippleLines.getLines())
|
||||
{
|
||||
if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
|
||||
{
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(line->getAccountIDPeer().getAccountID(),
|
||||
ele.mCurrencyID,
|
||||
uint160());
|
||||
|
||||
new_path.mPath.push_back(new_ele);
|
||||
pqueue.push(new_path);
|
||||
}
|
||||
} // BOOST_FOREACHE
|
||||
// Remove implied first and last nodes.
|
||||
path.mPath.erase(path.mPath.begin());
|
||||
path.mPath.erase(path.mPath.begin() + path.mPath.size()-1);
|
||||
|
||||
// every offer that wants the source currency
|
||||
std::vector<OrderBook::pointer> books;
|
||||
mOrderBook.getBooks(path.mCurrentAccount, path.mCurrencyID, books);
|
||||
// Return the path.
|
||||
retPathSet.addPath(path);
|
||||
|
||||
BOOST_FOREACH(OrderBook::pointer book,books)
|
||||
{
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
|
||||
return true;
|
||||
}
|
||||
|
||||
new_path.mPath.push_back(new_ele);
|
||||
new_path.mCurrentAccount=book->getIssuerOut();
|
||||
new_path.mCurrencyID=book->getCurrencyOut();
|
||||
if (!ele.mCurrencyID) {
|
||||
// Last element is for XRP continue with qualifying books.
|
||||
|
||||
pqueue.push(new_path);
|
||||
BOOST_FOREACH(OrderBook::pointer book, mOrderBook.getXRPInBooks())
|
||||
{
|
||||
//if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
|
||||
{
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
|
||||
|
||||
}
|
||||
new_path.mPath.push_back(new_ele);
|
||||
new_path.mCurrencyID = book->getCurrencyOut();
|
||||
new_path.mCurrentAccount = book->getCurrencyOut();
|
||||
|
||||
} // else
|
||||
// enumerate all adjacent nodes, construct a new path and push it into the queue
|
||||
} // While
|
||||
} // if there is a ledger
|
||||
pqueue.push(new_path);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
// Last element is for non-XRP continue by adding ripple lines and order books.
|
||||
|
||||
// Create new paths for each outbound account not already in the path.
|
||||
RippleLines rippleLines(ele.mAccountID);
|
||||
|
||||
BOOST_FOREACH(RippleState::pointer line, rippleLines.getLines())
|
||||
{
|
||||
if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
|
||||
{
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(line->getAccountIDPeer().getAccountID(),
|
||||
ele.mCurrencyID,
|
||||
uint160());
|
||||
|
||||
new_path.mPath.push_back(new_ele);
|
||||
pqueue.push(new_path);
|
||||
}
|
||||
}
|
||||
|
||||
// Every book that wants the source currency.
|
||||
std::vector<OrderBook::pointer> books;
|
||||
|
||||
mOrderBook.getBooks(path.mCurrentAccount, path.mCurrencyID, books);
|
||||
|
||||
BOOST_FOREACH(OrderBook::pointer book,books)
|
||||
{
|
||||
STPath new_path(path);
|
||||
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
|
||||
|
||||
new_path.mPath.push_back(new_ele);
|
||||
new_path.mCurrentAccount=book->getIssuerOut();
|
||||
new_path.mCurrencyID=book->getCurrencyOut();
|
||||
|
||||
pqueue.push(new_path);
|
||||
}
|
||||
}
|
||||
|
||||
// enumerate all adjacent nodes, construct a new path and push it into the queue
|
||||
} // While
|
||||
} // if there is a ledger
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Pathfinder::checkComplete(STPathSet& retPathSet)
|
||||
@@ -196,9 +210,9 @@ bool Pathfinder::checkComplete(STPathSet& retPathSet)
|
||||
|
||||
void Pathfinder::addOptions(PathOption::pointer tail)
|
||||
{
|
||||
if(!tail->mCurrencyID)
|
||||
if (!tail->mCurrencyID)
|
||||
{ // source XRP
|
||||
BOOST_FOREACH(OrderBook::pointer book,mOrderBook.getXRPInBooks())
|
||||
BOOST_FOREACH(OrderBook::pointer book, mOrderBook.getXRPInBooks())
|
||||
{
|
||||
PathOption::pointer pathOption(new PathOption(tail));
|
||||
|
||||
@@ -209,13 +223,14 @@ void Pathfinder::addOptions(PathOption::pointer tail)
|
||||
pathOption->mCurrencyID=book->getCurrencyOut();
|
||||
addPathOption(pathOption);
|
||||
}
|
||||
}else
|
||||
}
|
||||
else
|
||||
{ // ripple
|
||||
RippleLines rippleLines(tail->mCurrentAccount);
|
||||
BOOST_FOREACH(RippleState::pointer line,rippleLines.getLines())
|
||||
{
|
||||
// TODO: make sure we can move in the correct direction
|
||||
STAmount balance=line->getBalance();
|
||||
STAmount balance=line->getBalance();
|
||||
if(balance.getCurrency()==tail->mCurrencyID)
|
||||
{ // we have a ripple line from the tail to somewhere else
|
||||
PathOption::pointer pathOption(new PathOption(tail));
|
||||
|
||||
Reference in New Issue
Block a user