From 50a993e9215020aa85b65499041ce8576a751456 Mon Sep 17 00:00:00 2001 From: MJK Date: Thu, 4 Oct 2012 18:21:05 -0700 Subject: [PATCH] Ripple tentatively implemented --- src/Pathfinder.cpp | 73 ++++++++++++++++++++++++++++++++--------- src/RPCServer.cpp | 8 ++--- src/RippleLines.cpp | 7 ++++ src/RippleLines.h | 3 +- src/SerializedTypes.cpp | 35 ++++++++++++++++++++ src/SerializedTypes.h | 12 +++++-- 6 files changed, 113 insertions(+), 25 deletions(-) diff --git a/src/Pathfinder.cpp b/src/Pathfinder.cpp index 4f0276a451..9290f921ae 100644 --- a/src/Pathfinder.cpp +++ b/src/Pathfinder.cpp @@ -84,24 +84,65 @@ Pathfinder::Pathfinder(NewcoinAddress& srcAccountID, NewcoinAddress& dstAccountI bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet) { - if(mLedger) - { - PathOption::pointer head(new PathOption(mSrcAccountID,mSrcCurrencyID,mDstAmount.getCurrency())); - addOptions(head); + if(mLedger) { + std::queue pqueue; + STPathElement ele(mSrcAccountID, + mSrcCurrencyID, + uint160()); + STPath path; + path.addElement(ele); + pqueue.push(path); + while(pqueue.size()) { - for(int n=0; n tempPaths=mBuildingPaths; - mBuildingPaths.clear(); - BOOST_FOREACH(PathOption::pointer path,tempPaths) - { - addOptions(path); - } - if(checkComplete(retPathSet)) return(true); - } - } + STPath path = pqueue.front(); + pqueue.pop(); + // get the first path from the queue - return(false); + ele = path.mPath.back(); + // get the last node from the path + + if (ele.mAccountID == mDstAccountID) { + path.mPath.erase(path.mPath.begin()); + path.mPath.erase(path.mPath.begin() + path.mPath.size()-1); + retPathSet.addPath(path); + return true; + } + // found the destination + + if (!ele.mCurrencyID) { + BOOST_FOREACH(OrderBook::pointer book,mOrderBook.getXNSInBooks()) + { + //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); + pqueue.push(new_path); + } + } + + } 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); + } + } + } + // 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) diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 3790691058..4b5de9ef8d 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -1890,20 +1890,16 @@ Json::Value RPCServer::doSend(const Json::Value& params) // XXX Don't allow send to self of same currency. Transaction::pointer trans; - if (asDst) { // Destination exists, ordinary send. - STPathSet spsPaths; - uint160 srcCurrencyID; -// bool ret_b; -// ret_b = false; + STPathSet spsPaths; + uint160 srcCurrencyID; if (!saSrcAmountMax.isNative() || !saDstAmount.isNative()) { STAmount::currencyFromString(srcCurrencyID, sSrcCurrency); Pathfinder pf(naSrcAccountID, naDstAccountID, srcCurrencyID, saDstAmount); -// ret_b = pf.findPaths(5, 1, spsPaths); pf.findPaths(5, 1, spsPaths); } diff --git a/src/RippleLines.cpp b/src/RippleLines.cpp index bae60414b1..e9a8ad25fa 100644 --- a/src/RippleLines.cpp +++ b/src/RippleLines.cpp @@ -8,6 +8,13 @@ RippleLines::RippleLines(const uint160& accountID, Ledger::pointer ledger) fillLines(accountID,ledger); } +void RippleLines::printRippleLines() { + for (int i =0; i < mLines.size(); i++) { + std::cout << i << ": " << mLines[i]->getAccountID().humanAccountID() << std::endl; + } + std::cout << std::endl; +} + RippleLines::RippleLines(const uint160& accountID ) { fillLines(accountID,theApp->getMasterLedger().getCurrentLedger()); diff --git a/src/RippleLines.h b/src/RippleLines.h index 13ea7f5dc4..00373838dd 100644 --- a/src/RippleLines.h +++ b/src/RippleLines.h @@ -16,4 +16,5 @@ public: RippleLines(const uint160& accountID ); // looks in the current ledger std::vector& getLines(){ return(mLines); } -}; \ No newline at end of file + void printRippleLines(); +}; diff --git a/src/SerializedTypes.cpp b/src/SerializedTypes.cpp index 92316d8b96..32fab92f21 100644 --- a/src/SerializedTypes.cpp +++ b/src/SerializedTypes.cpp @@ -10,10 +10,35 @@ #include "Log.h" #include "NewcoinAddress.h" #include "utils.h" +#include "NewcoinAddress.h" STAmount saZero(CURRENCY_ONE, ACCOUNT_ONE, 0); STAmount saOne(CURRENCY_ONE, ACCOUNT_ONE, 1); +void STPathSet::printDebug() { + for (int i = 0; i < value.size(); i++) { + std::cout << i << ": "; + for (int j = 0; j < value[i].mPath.size(); j++) { + //STPathElement pe = value[i].mPath[j]; + NewcoinAddress nad; + nad.setAccountID(value[i].mPath[j].mAccountID); + std::cout << " " << nad.humanAccountID(); + //std::cout << " " << pe.mAccountID.GetHex(); + } + std::cout << std::endl; + } + +} + +void STPath::printDebug() { + std::cout << "STPath:" << std::endl; + for(int i =0; i < mPath.size(); i++) { + NewcoinAddress nad; + nad.setAccountID(mPath[i].mAccountID); + std::cout << " " << i << ": " << nad.humanAccountID() << std::endl; + } +} + std::string SerializedType::getFullText() const { std::string ret; @@ -331,6 +356,16 @@ bool STPathSet::isEquivalent(const SerializedType& t) const return v && (value == v->value); } +bool STPath::hasSeen(const uint160 &acct) { + + for (int i = 0; i < mPath.size();i++) { + STPathElement ele = getElement(i); + if (ele.getAccountID() == acct) + return true; + } + + return false; +} int STPath::getSerializeSize() const { int iBytes = 0; diff --git a/src/SerializedTypes.h b/src/SerializedTypes.h index 0c1cd3bac2..cee687a7fd 100644 --- a/src/SerializedTypes.h +++ b/src/SerializedTypes.h @@ -518,6 +518,9 @@ public: class STPathElement { + friend class STPathSet; + friend class STPath; + friend class Pathfinder; public: enum { typeEnd = 0x00, @@ -567,6 +570,8 @@ public: class STPath { + friend class STPathSet; + friend class Pathfinder; protected: std::vector mPath; @@ -574,12 +579,14 @@ public: STPath() { ; } STPath(const std::vector& p) : mPath(p) { ; } + void printDebug(); int getElementCount() const { return mPath.size(); } bool isEmpty() const { return mPath.empty(); } const STPathElement& getElement(int offset) const { return mPath[offset]; } const STPathElement& getElemet(int offset) { return mPath[offset]; } - void addElement(const STPathElement& e) { mPath.push_back(e); } + void addElement(const STPathElement &e) { mPath.push_back(e); } void clear() { mPath.clear(); } + bool hasSeen(const uint160 &acct); int getSerializeSize() const; // std::string getText() const; Json::Value getJson(int) const; @@ -636,7 +643,6 @@ protected: static STPathSet* construct(SerializerIterator&, SField::ref); public: - STPathSet() { ; } STPathSet(SField::ref n) : SerializedType(n) { ; } STPathSet(const std::vector& v) : value(v) { ; } @@ -658,6 +664,8 @@ public: virtual bool isEquivalent(const SerializedType& t) const; + void printDebug(); + std::vector::iterator begin() { return value.begin(); } std::vector::iterator end() { return value.end(); } std::vector::const_iterator begin() const { return value.begin(); }