mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-05 16:57:56 +00:00
New improved Pathfinding engine
This commit is contained in:
@@ -34,10 +34,12 @@ void OrderBookDB::setup (Ledger::ref ledger)
|
|||||||
|
|
||||||
mDestMap.clear ();
|
mDestMap.clear ();
|
||||||
mSourceMap.clear ();
|
mSourceMap.clear ();
|
||||||
|
mXRPBooks.clear ();
|
||||||
|
|
||||||
WriteLog (lsDEBUG, OrderBookDB) << "OrderBookDB>";
|
WriteLog (lsDEBUG, OrderBookDB) << "OrderBookDB>";
|
||||||
|
|
||||||
// walk through the entire ledger looking for orderbook entries
|
// walk through the entire ledger looking for orderbook entries
|
||||||
|
int books = 0;
|
||||||
uint256 currentIndex = ledger->getFirstLedgerIndex ();
|
uint256 currentIndex = ledger->getFirstLedgerIndex ();
|
||||||
|
|
||||||
while (currentIndex.isNonZero ())
|
while (currentIndex.isNonZero ())
|
||||||
@@ -62,13 +64,16 @@ void OrderBookDB::setup (Ledger::ref ledger)
|
|||||||
|
|
||||||
mSourceMap[currencyIssuer_ct (ci, ii)].push_back (book);
|
mSourceMap[currencyIssuer_ct (ci, ii)].push_back (book);
|
||||||
mDestMap[currencyIssuer_ct (co, io)].push_back (book);
|
mDestMap[currencyIssuer_ct (co, io)].push_back (book);
|
||||||
|
if (co.isZero())
|
||||||
|
mXRPBooks.insert(currencyIssuer_ct (ci, ii));
|
||||||
|
++books;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentIndex = ledger->getNextLedgerIndex (currentIndex);
|
currentIndex = ledger->getNextLedgerIndex (currentIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteLog (lsDEBUG, OrderBookDB) << "OrderBookDB<";
|
WriteLog (lsDEBUG, OrderBookDB) << "OrderBookDB< " << books << " books found";
|
||||||
}
|
}
|
||||||
|
|
||||||
// return list of all orderbooks that want this issuerID and currencyID
|
// return list of all orderbooks that want this issuerID and currencyID
|
||||||
@@ -85,6 +90,13 @@ void OrderBookDB::getBooksByTakerPays (const uint160& issuerID, const uint160& c
|
|||||||
bookRet.clear ();
|
bookRet.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OrderBookDB::isBookToXRP(const uint160& issuerID, const uint160& currencyID)
|
||||||
|
{
|
||||||
|
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||||
|
|
||||||
|
return mXRPBooks.count(currencyIssuer_ct(currencyID, issuerID)) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
// return list of all orderbooks that give this issuerID and currencyID
|
// return list of all orderbooks that give this issuerID and currencyID
|
||||||
void OrderBookDB::getBooksByTakerGets (const uint160& issuerID, const uint160& currencyID,
|
void OrderBookDB::getBooksByTakerGets (const uint160& issuerID, const uint160& currencyID,
|
||||||
std::vector<OrderBook::pointer>& bookRet)
|
std::vector<OrderBook::pointer>& bookRet)
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ public:
|
|||||||
void getBooksByTakerGets (const uint160& issuerID, const uint160& currencyID,
|
void getBooksByTakerGets (const uint160& issuerID, const uint160& currencyID,
|
||||||
std::vector<OrderBook::pointer>& bookRet);
|
std::vector<OrderBook::pointer>& bookRet);
|
||||||
|
|
||||||
|
bool isBookToXRP (const uint160& issuerID, const uint160& currencyID);
|
||||||
|
|
||||||
BookListeners::pointer getBookListeners (const uint160& currencyPays, const uint160& currencyGets,
|
BookListeners::pointer getBookListeners (const uint160& currencyPays, const uint160& currencyGets,
|
||||||
const uint160& issuerPays, const uint160& issuerGets);
|
const uint160& issuerPays, const uint160& issuerGets);
|
||||||
|
|
||||||
@@ -61,11 +63,12 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> > mSourceMap; // by ci/ii
|
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> > mSourceMap; // by ci/ii
|
||||||
|
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> > mDestMap; // by co/io
|
||||||
|
boost::unordered_set< currencyIssuer_t > mXRPBooks; // does an order book to XRP exist
|
||||||
typedef RippleRecursiveMutex LockType;
|
typedef RippleRecursiveMutex LockType;
|
||||||
typedef LockType::ScopedLockType ScopedLockType;
|
typedef LockType::ScopedLockType ScopedLockType;
|
||||||
LockType mLock;
|
LockType mLock;
|
||||||
|
|
||||||
boost::unordered_map< currencyIssuer_t, std::vector<OrderBook::pointer> > mDestMap; // by co/io
|
|
||||||
|
|
||||||
// issuerPays, issuerGets, currencyPays, currencyGets
|
// issuerPays, issuerGets, currencyPays, currencyGets
|
||||||
std::map<uint160, std::map<uint160, std::map<uint160, std::map<uint160, BookListeners::pointer> > > > mListeners;
|
std::map<uint160, std::map<uint160, std::map<uint160, std::map<uint160, BookListeners::pointer> > > > mListeners;
|
||||||
|
|||||||
@@ -1142,7 +1142,7 @@ uint32 LedgerEntrySet::rippleTransferRate (const uint160& uIssuerID)
|
|||||||
? sleAccount->getFieldU32 (sfTransferRate)
|
? sleAccount->getFieldU32 (sfTransferRate)
|
||||||
: QUALITY_ONE;
|
: QUALITY_ONE;
|
||||||
|
|
||||||
WriteLog (lsDEBUG, LedgerEntrySet) << boost::str (boost::format ("rippleTransferRate: uIssuerID=%s account_exists=%d transfer_rate=%f")
|
WriteLog (lsTRACE, LedgerEntrySet) << boost::str (boost::format ("rippleTransferRate: uIssuerID=%s account_exists=%d transfer_rate=%f")
|
||||||
% RippleAddress::createHumanAccountID (uIssuerID)
|
% RippleAddress::createHumanAccountID (uIssuerID)
|
||||||
% !!sleAccount
|
% !!sleAccount
|
||||||
% (uQuality / 1000000000.0));
|
% (uQuality / 1000000000.0));
|
||||||
|
|||||||
@@ -456,6 +456,7 @@ public:
|
|||||||
updateTables ();
|
updateTables ();
|
||||||
|
|
||||||
mFeatures->addInitialFeatures ();
|
mFeatures->addInitialFeatures ();
|
||||||
|
Pathfinder::initPathTable ();
|
||||||
|
|
||||||
if (getConfig ().START_UP == Config::FRESH)
|
if (getConfig ().START_UP == Config::FRESH)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ PathRequest::PathRequest (const boost::shared_ptr<InfoSub>& subscriber)
|
|||||||
, jvStatus (Json::objectValue)
|
, jvStatus (Json::objectValue)
|
||||||
, bValid (false)
|
, bValid (false)
|
||||||
, bNew (true)
|
, bNew (true)
|
||||||
|
, iLastLevel (0)
|
||||||
|
, bLastSuccess (false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,6 +268,43 @@ bool PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
|
|
||||||
Json::Value jvArray = Json::arrayValue;
|
Json::Value jvArray = Json::arrayValue;
|
||||||
|
|
||||||
|
int iLevel = iLastLevel;
|
||||||
|
bool loaded = getApp().getFeeTrack().isLoadedLocal();
|
||||||
|
|
||||||
|
if (iLevel == 0)
|
||||||
|
{ // first pass
|
||||||
|
if (loaded)
|
||||||
|
iLevel = getConfig().PATH_SEARCH_FAST;
|
||||||
|
else if (!fast)
|
||||||
|
iLevel = getConfig().PATH_SEARCH_OLD;
|
||||||
|
else if (getConfig().PATH_SEARCH < getConfig().PATH_SEARCH_MAX)
|
||||||
|
iLevel = getConfig().PATH_SEARCH + 1; // start with an extra boost
|
||||||
|
else
|
||||||
|
iLevel = getConfig().PATH_SEARCH;
|
||||||
|
}
|
||||||
|
else if ((iLevel == getConfig().PATH_SEARCH_FAST) && !fast)
|
||||||
|
{ // leaving fast pathfinding
|
||||||
|
iLevel = getConfig().PATH_SEARCH;
|
||||||
|
if (loaded && (iLevel > getConfig().PATH_SEARCH_FAST))
|
||||||
|
--iLevel;
|
||||||
|
else if (!loaded && (iLevel < getConfig().PATH_SEARCH))
|
||||||
|
++iLevel;
|
||||||
|
}
|
||||||
|
else if (bLastSuccess)
|
||||||
|
{ // decrement, if possible
|
||||||
|
if ((iLevel > getConfig().PATH_SEARCH) || (loaded && (iLevel > getConfig().PATH_SEARCH_FAST)))
|
||||||
|
--iLevel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // adjust as needed
|
||||||
|
if (!loaded && (iLevel < getConfig().PATH_SEARCH_MAX))
|
||||||
|
++iLevel;
|
||||||
|
if (loaded && (iLevel > getConfig().PATH_SEARCH_FAST))
|
||||||
|
--iLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
BOOST_FOREACH (const currIssuer_t & currIssuer, sourceCurrencies)
|
BOOST_FOREACH (const currIssuer_t & currIssuer, sourceCurrencies)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -273,12 +312,12 @@ bool PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
WriteLog (lsDEBUG, PathRequest) << "Trying to find paths: " << test.getFullText ();
|
WriteLog (lsDEBUG, PathRequest) << "Trying to find paths: " << test.getFullText ();
|
||||||
}
|
}
|
||||||
bool valid;
|
bool valid;
|
||||||
STPathSet spsPaths;
|
STPathSet& spsPaths = mContext[currIssuer];
|
||||||
Pathfinder pf (cache, raSrcAccount, raDstAccount,
|
Pathfinder pf (cache, raSrcAccount, raDstAccount,
|
||||||
currIssuer.first, currIssuer.second, saDstAmount, valid);
|
currIssuer.first, currIssuer.second, saDstAmount, valid);
|
||||||
CondLog (!valid, lsINFO, PathRequest) << "PF request not valid";
|
CondLog (!valid, lsINFO, PathRequest) << "PF request not valid";
|
||||||
|
|
||||||
if (valid && pf.findPaths (getConfig ().PATH_SEARCH_SIZE - (fast ? 1 : 0), 3, spsPaths))
|
if (valid && pf.findPaths (iLevel, 4, spsPaths))
|
||||||
{
|
{
|
||||||
LedgerEntrySet lesSandbox (cache->getLedger (), tapNONE);
|
LedgerEntrySet lesSandbox (cache->getLedger (), tapNONE);
|
||||||
std::vector<PathState::pointer> vpsExpanded;
|
std::vector<PathState::pointer> vpsExpanded;
|
||||||
@@ -298,6 +337,7 @@ bool PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
Json::Value jvEntry (Json::objectValue);
|
Json::Value jvEntry (Json::objectValue);
|
||||||
jvEntry["source_amount"] = saMaxAmountAct.getJson (0);
|
jvEntry["source_amount"] = saMaxAmountAct.getJson (0);
|
||||||
jvEntry["paths_computed"] = spsPaths.getJson (0);
|
jvEntry["paths_computed"] = spsPaths.getJson (0);
|
||||||
|
found = true;
|
||||||
jvArray.append (jvEntry);
|
jvArray.append (jvEntry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -310,6 +350,10 @@ bool PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
|||||||
WriteLog (lsINFO, PathRequest) << "No paths found";
|
WriteLog (lsINFO, PathRequest) << "No paths found";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iLastLevel = iLevel;
|
||||||
|
bLastSuccess = found;
|
||||||
|
|
||||||
jvStatus["alternatives"] = jvArray;
|
jvStatus["alternatives"] = jvArray;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class RippleLineCache;
|
|||||||
class PathRequest : public boost::enable_shared_from_this<PathRequest>
|
class PathRequest : public boost::enable_shared_from_this<PathRequest>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef boost::weak_ptr<PathRequest> wptr;
|
typedef boost::weak_ptr<PathRequest> wptr;
|
||||||
typedef boost::shared_ptr<PathRequest> pointer;
|
typedef boost::shared_ptr<PathRequest> pointer;
|
||||||
typedef const pointer& ref;
|
typedef const pointer& ref;
|
||||||
typedef const wptr& wref;
|
typedef const wptr& wref;
|
||||||
@@ -56,15 +56,19 @@ private:
|
|||||||
Json::Value jvStatus; // Last result
|
Json::Value jvStatus; // Last result
|
||||||
|
|
||||||
// Client request parameters
|
// Client request parameters
|
||||||
RippleAddress raSrcAccount;
|
RippleAddress raSrcAccount;
|
||||||
RippleAddress raDstAccount;
|
RippleAddress raDstAccount;
|
||||||
STAmount saDstAmount;
|
STAmount saDstAmount;
|
||||||
std::set<currIssuer_t> sciSourceCurrencies;
|
std::set<currIssuer_t> sciSourceCurrencies;
|
||||||
std::vector<Json::Value> vjvBridges;
|
std::vector<Json::Value> vjvBridges;
|
||||||
|
std::map<currIssuer_t, STPathSet> mContext;
|
||||||
|
|
||||||
bool bValid;
|
bool bValid;
|
||||||
bool bNew;
|
bool bNew;
|
||||||
|
|
||||||
|
int iLastLevel;
|
||||||
|
bool bLastSuccess;
|
||||||
|
|
||||||
// Track all requests
|
// Track all requests
|
||||||
static std::set<wptr> sRequests;
|
static std::set<wptr> sRequests;
|
||||||
|
|
||||||
|
|||||||
@@ -391,7 +391,7 @@ void PathState::setExpanded (
|
|||||||
const uint160 uOutIssuerID = saOutReq.getIssuer ();
|
const uint160 uOutIssuerID = saOutReq.getIssuer ();
|
||||||
const uint160 uSenderIssuerID = !!uMaxCurrencyID ? uSenderID : ACCOUNT_XRP; // Sender is always issuer for non-XRP.
|
const uint160 uSenderIssuerID = !!uMaxCurrencyID ? uSenderID : ACCOUNT_XRP; // Sender is always issuer for non-XRP.
|
||||||
|
|
||||||
WriteLog (lsDEBUG, RippleCalc) << boost::str (boost::format ("setExpanded> %s") % spSourcePath.getJson (0));
|
WriteLog (lsTRACE, RippleCalc) << boost::str (boost::format ("setExpanded> %s") % spSourcePath.getJson (0));
|
||||||
|
|
||||||
lesEntries = lesSource.duplicate ();
|
lesEntries = lesSource.duplicate ();
|
||||||
|
|
||||||
@@ -467,7 +467,7 @@ void PathState::setExpanded (
|
|||||||
{
|
{
|
||||||
if (tesSUCCESS == terStatus)
|
if (tesSUCCESS == terStatus)
|
||||||
{
|
{
|
||||||
WriteLog (lsDEBUG, RippleCalc) << boost::str (boost::format ("setExpanded: element in path:"));
|
WriteLog (lsTRACE, RippleCalc) << boost::str (boost::format ("setExpanded: element in path:"));
|
||||||
terStatus = pushNode (speElement.getNodeType (), speElement.getAccountID (), speElement.getCurrency (), speElement.getIssuerID ());
|
terStatus = pushNode (speElement.getNodeType (), speElement.getAccountID (), speElement.getCurrency (), speElement.getIssuerID ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -47,24 +47,54 @@ public:
|
|||||||
const RippleAddress& srcAccountID, const RippleAddress& dstAccountID,
|
const RippleAddress& srcAccountID, const RippleAddress& dstAccountID,
|
||||||
const uint160& srcCurrencyID, const uint160& srcIssuerID, const STAmount& dstAmount, bool& bValid);
|
const uint160& srcCurrencyID, const uint160& srcIssuerID, const STAmount& dstAmount, bool& bValid);
|
||||||
|
|
||||||
bool findPaths (const unsigned int iMaxSteps, const unsigned int iMaxPaths, STPathSet& spsDst);
|
static void initPathTable();
|
||||||
|
bool findPaths (int iLevel, const unsigned int iMaxPaths, STPathSet& spsDst);
|
||||||
bool bDefaultPath (const STPath& spPath);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// void addOptions(PathOption::pointer tail);
|
|
||||||
|
enum PaymentType
|
||||||
|
{
|
||||||
|
pt_XRP_to_XRP,
|
||||||
|
pt_XRP_to_nonXRP,
|
||||||
|
pt_nonXRP_to_XRP,
|
||||||
|
pt_nonXRP_to_same,
|
||||||
|
pt_nonXRP_to_nonXRP
|
||||||
|
};
|
||||||
|
|
||||||
|
enum NodeType
|
||||||
|
{
|
||||||
|
nt_SOURCE, // The source account with an issuer account, if required
|
||||||
|
nt_ACCOUNTS, // Accounts that connect from this source/currency
|
||||||
|
nt_BOOKS, // Order books that connect to this currency
|
||||||
|
nt_XRP_BOOK, // The order book from this currency to XRP
|
||||||
|
nt_DEST_BOOK, // The order book to the destination currency/issuer
|
||||||
|
nt_DESTINATION // The destination account only
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<NodeType> PathType_t;
|
||||||
|
typedef std::pair<int, PathType_t> CostedPath_t;
|
||||||
|
typedef std::vector<CostedPath_t> CostedPathList_t;
|
||||||
|
|
||||||
// returns true if any building paths are now complete?
|
// returns true if any building paths are now complete?
|
||||||
bool checkComplete (STPathSet& retPathSet);
|
bool checkComplete (STPathSet& retPathSet);
|
||||||
|
|
||||||
// void addPathOption(PathOption::pointer pathOption);
|
static std::string pathTypeToString(PathType_t const&);
|
||||||
|
|
||||||
bool matchesOrigin (const uint160& currency, const uint160& issuer);
|
bool matchesOrigin (const uint160& currency, const uint160& issuer);
|
||||||
|
|
||||||
int getPathsOut (const uint160& currency, const uint160& accountID,
|
int getPathsOut (const uint160& currency, const uint160& accountID,
|
||||||
bool isDestCurrency, const uint160& dest);
|
bool isDestCurrency, const uint160& dest);
|
||||||
|
|
||||||
private:
|
void addLink(const STPath& currentPath, STPathSet& incompletePaths, int addFlags);
|
||||||
|
void addLink(const STPathSet& currentPaths, STPathSet& incompletePaths, int addFlags);
|
||||||
|
STPathSet& getPaths(const PathType_t& type, bool addComplete = true);
|
||||||
|
STPathSet filterPaths(int iMaxPaths);
|
||||||
|
|
||||||
|
// Our main table of paths
|
||||||
|
|
||||||
|
static std::map<PaymentType, CostedPathList_t> mPathTable;
|
||||||
|
static PathType_t makePath(char const*);
|
||||||
|
|
||||||
uint160 mSrcAccountID;
|
uint160 mSrcAccountID;
|
||||||
uint160 mDstAccountID;
|
uint160 mDstAccountID;
|
||||||
STAmount mDstAmount;
|
STAmount mDstAmount;
|
||||||
@@ -73,15 +103,21 @@ private:
|
|||||||
STAmount mSrcAmount;
|
STAmount mSrcAmount;
|
||||||
|
|
||||||
Ledger::pointer mLedger;
|
Ledger::pointer mLedger;
|
||||||
PathState::pointer mPsDefault;
|
|
||||||
LoadEvent::pointer m_loadEvent;
|
LoadEvent::pointer m_loadEvent;
|
||||||
RippleLineCache::pointer mRLCache;
|
RippleLineCache::pointer mRLCache;
|
||||||
|
|
||||||
|
STPathElement mSource;
|
||||||
|
STPathSet mCompletePaths;
|
||||||
|
std::map< PathType_t, STPathSet > mPaths;
|
||||||
|
|
||||||
boost::unordered_map<uint160, AccountItems::pointer> mRLMap;
|
boost::unordered_map<uint160, AccountItems::pointer> mRLMap;
|
||||||
boost::unordered_map<std::pair<uint160, uint160>, int> mPOMap;
|
boost::unordered_map<std::pair<uint160, uint160>, int> mPOMap;
|
||||||
|
|
||||||
// std::list<PathOption::pointer> mBuildingPaths;
|
static const uint32 afADD_ACCOUNTS = 0x001; // Add ripple paths
|
||||||
// std::list<PathOption::pointer> mCompletePaths;
|
static const uint32 afADD_BOOKS = 0x002; // Add order books
|
||||||
|
static const uint32 afOB_XRP = 0x010; // Add order book to XRP only
|
||||||
|
static const uint32 afOB_LAST = 0x040; // Must link to destination currency
|
||||||
|
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, Ledger::ref lrLedger,
|
||||||
|
|||||||
@@ -1250,14 +1250,7 @@ void PeerImp::recvTransaction (protocol::TMTransaction& packet, Application::Sco
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getApp().getMasterTransaction().fetch(txID, true))
|
WriteLog (lsDEBUG, Peer) << "Got transaction from peer " << getDisplayName () << " : " << txID;
|
||||||
{
|
|
||||||
WriteLog (lsDEBUG, Peer) << "Peer " << getDisplayName() << " send old TX " << txID;
|
|
||||||
applyLoadCharge (LT_InvalidRequest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteLog (lsDEBUG, Peer) << "Got new transaction from peer " << getDisplayName () << " : " << txID;
|
|
||||||
|
|
||||||
if (mCluster)
|
if (mCluster)
|
||||||
flags |= SF_TRUSTED | SF_SIGGOOD;
|
flags |= SF_TRUSTED | SF_SIGGOOD;
|
||||||
@@ -1943,6 +1936,7 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
|||||||
uint256 txHash;
|
uint256 txHash;
|
||||||
memcpy (txHash.begin (), packet.ledgerhash ().data (), 32);
|
memcpy (txHash.begin (), packet.ledgerhash ().data (), 32);
|
||||||
map = getApp().getOPs ().getTXMap (txHash);
|
map = getApp().getOPs ().getTXMap (txHash);
|
||||||
|
masterLockHolder.unlock();
|
||||||
|
|
||||||
if (!map)
|
if (!map)
|
||||||
{
|
{
|
||||||
@@ -1982,6 +1976,12 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (getApp().getFeeTrack().isLoadedLocal() && !mCluster)
|
||||||
|
{
|
||||||
|
WriteLog (lsDEBUG, Peer) << "Too busy to fetch ledger data";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Figure out what ledger they want
|
// Figure out what ledger they want
|
||||||
WriteLog (lsTRACE, Peer) << "Received request for ledger data " << getIP ();
|
WriteLog (lsTRACE, Peer) << "Received request for ledger data " << getIP ();
|
||||||
Ledger::pointer ledger;
|
Ledger::pointer ledger;
|
||||||
@@ -2280,7 +2280,7 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PeerImp::hasLedger (uint256 const& hash, uint32 seq) const
|
bool PeerImp::hasLedger (uint256 const& hash, uint32 seq) const
|
||||||
{
|
{ // FIXME: mRecentLedgers needs some kind of synchronization
|
||||||
if ((seq != 0) && (seq >= mMinLedger) && (seq <= mMaxLedger))
|
if ((seq != 0) && (seq >= mMinLedger) && (seq <= mMaxLedger))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ Json::Value RPCHandler::transactionSign (Json::Value params, bool bSubmit, bool
|
|||||||
Pathfinder pf (cache, raSrcAddressID, dstAccountID,
|
Pathfinder pf (cache, raSrcAddressID, dstAccountID,
|
||||||
saSendMax.getCurrency (), saSendMax.getIssuer (), saSend, bValid);
|
saSendMax.getCurrency (), saSendMax.getIssuer (), saSend, bValid);
|
||||||
|
|
||||||
if (!bValid || !pf.findPaths (getConfig ().PATH_SEARCH_SIZE, 3, spsPaths))
|
if (!bValid || !pf.findPaths (getConfig ().PATH_SEARCH_OLD, 5, spsPaths))
|
||||||
{
|
{
|
||||||
WriteLog (lsDEBUG, RPCHandler) << "transactionSign: build_path: No paths found.";
|
WriteLog (lsDEBUG, RPCHandler) << "transactionSign: build_path: No paths found.";
|
||||||
|
|
||||||
@@ -1513,7 +1513,10 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, LoadType* loadType
|
|||||||
bool bValid;
|
bool bValid;
|
||||||
Pathfinder pf (cache, raSrc, raDst, uSrcCurrencyID, uSrcIssuerID, saDstAmount, bValid);
|
Pathfinder pf (cache, raSrc, raDst, uSrcCurrencyID, uSrcIssuerID, saDstAmount, bValid);
|
||||||
|
|
||||||
if (!bValid || !pf.findPaths (getConfig ().PATH_SEARCH_SIZE, 3, spsComputed))
|
int level = getConfig().PATH_SEARCH_OLD;
|
||||||
|
if ((getConfig().PATH_SEARCH_MAX > level) && getApp().getFeeTrack().isLoadedLocal())
|
||||||
|
++level;
|
||||||
|
if (!bValid || !pf.findPaths (level, 4, spsComputed))
|
||||||
{
|
{
|
||||||
WriteLog (lsWARNING, RPCHandler) << "ripple_path_find: No paths found.";
|
WriteLog (lsWARNING, RPCHandler) << "ripple_path_find: No paths found.";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,11 @@ Config::Config ()
|
|||||||
|
|
||||||
LEDGER_HISTORY = 256;
|
LEDGER_HISTORY = 256;
|
||||||
|
|
||||||
PATH_SEARCH_SIZE = DEFAULT_PATH_SEARCH_SIZE;
|
PATH_SEARCH_OLD = DEFAULT_PATH_SEARCH_OLD;
|
||||||
|
PATH_SEARCH = DEFAULT_PATH_SEARCH;
|
||||||
|
PATH_SEARCH_FAST = DEFAULT_PATH_SEARCH_FAST;
|
||||||
|
PATH_SEARCH_MAX = DEFAULT_PATH_SEARCH_MAX;
|
||||||
|
|
||||||
ACCOUNT_PROBE_MAX = 10;
|
ACCOUNT_PROBE_MAX = 10;
|
||||||
|
|
||||||
VALIDATORS_SITE = DEFAULT_VALIDATORS_SITE;
|
VALIDATORS_SITE = DEFAULT_VALIDATORS_SITE;
|
||||||
@@ -502,8 +506,14 @@ void Config::load ()
|
|||||||
LEDGER_HISTORY = lexicalCastThrow <uint32> (strTemp);
|
LEDGER_HISTORY = lexicalCastThrow <uint32> (strTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SectionSingleB (secConfig, SECTION_PATH_SEARCH_SIZE, strTemp))
|
if (SectionSingleB (secConfig, SECTION_PATH_SEARCH_OLD, strTemp))
|
||||||
PATH_SEARCH_SIZE = lexicalCastThrow <int> (strTemp);
|
PATH_SEARCH_OLD = lexicalCastThrow <int> (strTemp);
|
||||||
|
if (SectionSingleB (secConfig, SECTION_PATH_SEARCH, strTemp))
|
||||||
|
PATH_SEARCH = lexicalCastThrow <int> (strTemp);
|
||||||
|
if (SectionSingleB (secConfig, SECTION_PATH_SEARCH_FAST, strTemp))
|
||||||
|
PATH_SEARCH_FAST = lexicalCastThrow <int> (strTemp);
|
||||||
|
if (SectionSingleB (secConfig, SECTION_PATH_SEARCH_MAX, strTemp))
|
||||||
|
PATH_SEARCH_MAX = lexicalCastThrow <int> (strTemp);
|
||||||
|
|
||||||
if (SectionSingleB (secConfig, SECTION_ACCOUNT_PROBE_MAX, strTemp))
|
if (SectionSingleB (secConfig, SECTION_ACCOUNT_PROBE_MAX, strTemp))
|
||||||
ACCOUNT_PROBE_MAX = lexicalCastThrow <int> (strTemp);
|
ACCOUNT_PROBE_MAX = lexicalCastThrow <int> (strTemp);
|
||||||
|
|||||||
@@ -44,8 +44,10 @@ const int SYSTEM_WEBSOCKET_PUBLIC_PORT = 6563; // XXX Going away.
|
|||||||
// Might connect with fewer for testing.
|
// Might connect with fewer for testing.
|
||||||
#define DEFAULT_PEER_CONNECT_LOW_WATER 10
|
#define DEFAULT_PEER_CONNECT_LOW_WATER 10
|
||||||
|
|
||||||
// Grows exponentially worse.
|
#define DEFAULT_PATH_SEARCH_OLD 7
|
||||||
#define DEFAULT_PATH_SEARCH_SIZE 4
|
#define DEFAULT_PATH_SEARCH 7
|
||||||
|
#define DEFAULT_PATH_SEARCH_FAST 2
|
||||||
|
#define DEFAULT_PATH_SEARCH_MAX 10
|
||||||
|
|
||||||
enum SizedItemName
|
enum SizedItemName
|
||||||
{
|
{
|
||||||
@@ -291,7 +293,10 @@ public:
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Path searching
|
// Path searching
|
||||||
int PATH_SEARCH_SIZE;
|
int PATH_SEARCH_OLD;
|
||||||
|
int PATH_SEARCH;
|
||||||
|
int PATH_SEARCH_FAST;
|
||||||
|
int PATH_SEARCH_MAX;
|
||||||
|
|
||||||
// Validation
|
// Validation
|
||||||
RippleAddress VALIDATION_SEED, VALIDATION_PUB, VALIDATION_PRIV;
|
RippleAddress VALIDATION_SEED, VALIDATION_PUB, VALIDATION_PRIV;
|
||||||
|
|||||||
@@ -37,7 +37,10 @@ struct ConfigSection
|
|||||||
#define SECTION_NETWORK_QUORUM "network_quorum"
|
#define SECTION_NETWORK_QUORUM "network_quorum"
|
||||||
#define SECTION_NODE_SEED "node_seed"
|
#define SECTION_NODE_SEED "node_seed"
|
||||||
#define SECTION_NODE_SIZE "node_size"
|
#define SECTION_NODE_SIZE "node_size"
|
||||||
#define SECTION_PATH_SEARCH_SIZE "path_search_size"
|
#define SECTION_PATH_SEARCH_OLD "path_search_old"
|
||||||
|
#define SECTION_PATH_SEARCH "path_search"
|
||||||
|
#define SECTION_PATH_SEARCH_FAST "path_search_fast"
|
||||||
|
#define SECTION_PATH_SEARCH_MAX "path_search_max"
|
||||||
#define SECTION_PEER_CONNECT_LOW_WATER "peer_connect_low_water"
|
#define SECTION_PEER_CONNECT_LOW_WATER "peer_connect_low_water"
|
||||||
#define SECTION_PEER_IP "peer_ip"
|
#define SECTION_PEER_IP "peer_ip"
|
||||||
#define SECTION_PEER_PORT "peer_port"
|
#define SECTION_PEER_PORT "peer_port"
|
||||||
|
|||||||
@@ -1164,6 +1164,12 @@ public:
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STPathElement ()
|
||||||
|
: mType (0)
|
||||||
|
{
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
int getNodeType () const
|
int getNodeType () const
|
||||||
{
|
{
|
||||||
return mType;
|
return mType;
|
||||||
@@ -1193,8 +1199,8 @@ public:
|
|||||||
|
|
||||||
bool operator== (const STPathElement& t) const
|
bool operator== (const STPathElement& t) const
|
||||||
{
|
{
|
||||||
return mType == t.mType && mAccountID == t.mAccountID && mCurrencyID == t.mCurrencyID &&
|
return ((mType & typeAccount) == (t.mType & typeAccount)) &&
|
||||||
mIssuerID == t.mIssuerID;
|
(mAccountID == t.mAccountID) && (mCurrencyID == t.mCurrencyID) && (mIssuerID == t.mIssuerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -1368,6 +1374,15 @@ public:
|
|||||||
{
|
{
|
||||||
value.push_back (e);
|
value.push_back (e);
|
||||||
}
|
}
|
||||||
|
void addUniquePath (const STPath& e)
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(const STPath& p, value)
|
||||||
|
{
|
||||||
|
if (p == e)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
value.push_back (e);
|
||||||
|
}
|
||||||
|
|
||||||
bool assembleAdd(STPath const& base, STPathElement const& tail)
|
bool assembleAdd(STPath const& base, STPathElement const& tail)
|
||||||
{ // assemble base+tail and add it to the set if it's not a duplicate
|
{ // assemble base+tail and add it to the set if it's not a duplicate
|
||||||
@@ -1398,6 +1413,15 @@ public:
|
|||||||
|
|
||||||
void printDebug ();
|
void printDebug ();
|
||||||
|
|
||||||
|
STPath& operator[](size_t n)
|
||||||
|
{
|
||||||
|
return value[n];
|
||||||
|
}
|
||||||
|
STPath const& operator[](size_t n) const
|
||||||
|
{
|
||||||
|
return value[n];
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<STPath>::iterator begin ()
|
std::vector<STPath>::iterator begin ()
|
||||||
{
|
{
|
||||||
return value.begin ();
|
return value.begin ();
|
||||||
|
|||||||
@@ -443,7 +443,7 @@
|
|||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# 5. Ripple Protcol
|
# 5. Ripple Protocol
|
||||||
#
|
#
|
||||||
#------------------
|
#------------------
|
||||||
#
|
#
|
||||||
@@ -554,6 +554,25 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
# [path_search]
|
||||||
|
# When searching for paths, the default search aggressiveness. This can take
|
||||||
|
# exponentially more resources as the size is increased.
|
||||||
|
#
|
||||||
|
# The default is: 7
|
||||||
|
#
|
||||||
|
# [path_search_fast]
|
||||||
|
# [path_search_max]
|
||||||
|
# When seaching for paths, the minimum and maximum search aggressiveness.
|
||||||
|
#
|
||||||
|
# The default for 'path_search_fast' is 2. The default for 'path_search_max' is 10.
|
||||||
|
#
|
||||||
|
# [path_search_old]
|
||||||
|
#
|
||||||
|
# For clients that use the legacy path finding interfaces, the search
|
||||||
|
# agressiveness to use. The default is 7.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# 6. HTTPS Client
|
# 6. HTTPS Client
|
||||||
|
|||||||
Reference in New Issue
Block a user