mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 10:35:50 +00:00
Compare commits
3 Commits
0.26.4-sp1
...
0.26.4-sp2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95f31b98a8 | ||
|
|
10d74ed100 | ||
|
|
8a7f612d5b |
@@ -1,5 +1,5 @@
|
||||
Name: rippled
|
||||
Version: 0.26.4-sp1
|
||||
Version: 0.26.4-sp2
|
||||
Release: 1%{?dist}
|
||||
Summary: Ripple peer-to-peer network daemon
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <ripple/common/RippleSSLContext.h>
|
||||
#include <ripple/app/main/Tuning.h>
|
||||
#include <ripple/app/misc/ProofOfWorkFactory.h>
|
||||
#include <ripple/app/paths/FindPaths.h>
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
#include <ripple/rpc/Manager.h>
|
||||
#include <ripple/nodestore/Database.h>
|
||||
@@ -653,7 +652,7 @@ public:
|
||||
updateTables ();
|
||||
|
||||
m_amendmentTable->addInitial();
|
||||
initializePathfinding ();
|
||||
Pathfinder::initPathTable ();
|
||||
|
||||
m_ledgerMaster->setMinValidations (getConfig ().VALIDATION_QUORUM);
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/paths/AccountCurrencies.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
CurrencySet accountSourceCurrencies (
|
||||
RippleAddress const& raAccountID,
|
||||
RippleLineCache::ref lrCache,
|
||||
bool includeXRP)
|
||||
{
|
||||
CurrencySet currencies;
|
||||
|
||||
// YYY Only bother if they are above reserve
|
||||
if (includeXRP)
|
||||
currencies.insert (xrpCurrency());
|
||||
|
||||
// List of ripple lines.
|
||||
auto& rippleLines (lrCache->getRippleLines (raAccountID.getAccountID ()));
|
||||
|
||||
for (auto const& item : rippleLines)
|
||||
{
|
||||
auto rspEntry = (RippleState*) item.get ();
|
||||
assert (rspEntry);
|
||||
if (!rspEntry)
|
||||
continue;
|
||||
|
||||
auto& saBalance = rspEntry->getBalance ();
|
||||
|
||||
// Filter out non
|
||||
if (saBalance > zero
|
||||
// Have IOUs to send.
|
||||
|| (rspEntry->getLimitPeer ()
|
||||
// Peer extends credit.
|
||||
&& ((-saBalance) < rspEntry->getLimitPeer ()))) // Credit left.
|
||||
{
|
||||
currencies.insert (saBalance.getCurrency ());
|
||||
}
|
||||
}
|
||||
|
||||
currencies.erase (badCurrency());
|
||||
return currencies;
|
||||
}
|
||||
|
||||
CurrencySet accountDestCurrencies (
|
||||
RippleAddress const& raAccountID,
|
||||
RippleLineCache::ref lrCache,
|
||||
bool includeXRP)
|
||||
{
|
||||
CurrencySet currencies;
|
||||
|
||||
if (includeXRP)
|
||||
currencies.insert (xrpCurrency());
|
||||
// Even if account doesn't exist
|
||||
|
||||
// List of ripple lines.
|
||||
auto& rippleLines (lrCache->getRippleLines (raAccountID.getAccountID ()));
|
||||
|
||||
for (auto const& item : rippleLines)
|
||||
{
|
||||
auto rspEntry = (RippleState*) item.get ();
|
||||
assert (rspEntry);
|
||||
if (!rspEntry)
|
||||
continue;
|
||||
|
||||
auto& saBalance = rspEntry->getBalance ();
|
||||
|
||||
if (saBalance < rspEntry->getLimit ()) // Can take more
|
||||
currencies.insert (saBalance.getCurrency ());
|
||||
}
|
||||
|
||||
currencies.erase (badCurrency());
|
||||
return currencies;
|
||||
}
|
||||
|
||||
} // ripple
|
||||
@@ -1,37 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLED_RIPPLE_APP_PATHS_ACCOUNTCURRENCIES_H
|
||||
#define RIPPLED_RIPPLE_APP_PATHS_ACCOUNTCURRENCIES_H
|
||||
|
||||
namespace ripple {
|
||||
|
||||
CurrencySet accountDestCurrencies
|
||||
(RippleAddress const& raAccountID,
|
||||
RippleLineCache::ref cache,
|
||||
bool includeXRP);
|
||||
|
||||
CurrencySet accountSourceCurrencies
|
||||
(RippleAddress const& raAccountID,
|
||||
RippleLineCache::ref lrLedger,
|
||||
bool includeXRP);
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
@@ -1,73 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/paths/Credit.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
STAmount creditLimit (
|
||||
LedgerEntrySet& ledger,
|
||||
Account const& account,
|
||||
Account const& issuer,
|
||||
Currency const& currency)
|
||||
{
|
||||
STAmount result ({currency, account});
|
||||
|
||||
auto sleRippleState = ledger.entryCache (ltRIPPLE_STATE,
|
||||
Ledger::getRippleStateIndex (account, issuer, currency));
|
||||
|
||||
if (sleRippleState)
|
||||
{
|
||||
result = sleRippleState->getFieldAmount (
|
||||
account < issuer ? sfLowLimit : sfHighLimit);
|
||||
|
||||
result.setIssuer (account);
|
||||
}
|
||||
|
||||
assert (result.getIssuer () == account);
|
||||
assert (result.getCurrency () == currency);
|
||||
return result;
|
||||
}
|
||||
|
||||
STAmount creditBalance (
|
||||
LedgerEntrySet& ledger,
|
||||
Account const& account,
|
||||
Account const& issuer,
|
||||
Currency const& currency)
|
||||
{
|
||||
STAmount result ({currency, account});
|
||||
|
||||
auto sleRippleState = ledger.entryCache (ltRIPPLE_STATE,
|
||||
Ledger::getRippleStateIndex (account, issuer, currency));
|
||||
|
||||
if (sleRippleState)
|
||||
{
|
||||
result = sleRippleState->getFieldAmount (sfBalance);
|
||||
if (account < issuer)
|
||||
result.negate ();
|
||||
|
||||
result.setIssuer (account);
|
||||
}
|
||||
|
||||
assert (result.getIssuer () == account);
|
||||
assert (result.getCurrency () == currency);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // ripple
|
||||
@@ -1,52 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLED_RIPPLE_APP_PATHS_CREDIT_H
|
||||
#define RIPPLED_RIPPLE_APP_PATHS_CREDIT_H
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/** Calculate the maximum amount of IOUs that an account can hold
|
||||
@param ledger the ledger to check against.
|
||||
@param account the account of interest.
|
||||
@param issuer the issuer of the IOU.
|
||||
@param currency the IOU to check.
|
||||
@return The maximum amount that can be held.
|
||||
*/
|
||||
STAmount creditLimit (
|
||||
LedgerEntrySet& ledger,
|
||||
Account const& account,
|
||||
Account const& issuer,
|
||||
Currency const& currency);
|
||||
|
||||
/** Returns the amount of IOUs issued by issuer that are held by an account
|
||||
@param ledger the ledger to check against.
|
||||
@param account the account of interest.
|
||||
@param issuer the issuer of the IOU.
|
||||
@param currency the IOU to check.
|
||||
*/
|
||||
STAmount creditBalance (
|
||||
LedgerEntrySet& ledger,
|
||||
Account const& account,
|
||||
Account const& issuer,
|
||||
Currency const& currency);
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
@@ -1,141 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/paths/FindPaths.h>
|
||||
#include <ripple/app/paths/Pathfinder.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class FindPaths::Impl {
|
||||
public:
|
||||
Impl (
|
||||
RippleLineCache::ref cache,
|
||||
Account const& srcAccount,
|
||||
Account const& dstAccount,
|
||||
STAmount const& dstAmount,
|
||||
int searchLevel,
|
||||
unsigned int maxPaths)
|
||||
: cache_ (cache),
|
||||
srcAccount_ (srcAccount),
|
||||
dstAccount_ (dstAccount),
|
||||
dstAmount_ (dstAmount),
|
||||
searchLevel_ (searchLevel),
|
||||
maxPaths_ (maxPaths)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool findPathsForIssue (
|
||||
Issue const& issue,
|
||||
STPathSet& pathsOut,
|
||||
STPath& fullLiquidityPath)
|
||||
{
|
||||
if (auto& pathfinder = getPathFinder (issue.currency))
|
||||
{
|
||||
pathsOut = pathfinder->getBestPaths (
|
||||
maxPaths_, fullLiquidityPath, issue.account);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
hash_map<Currency, std::unique_ptr<Pathfinder>> currencyMap_;
|
||||
|
||||
RippleLineCache::ref cache_;
|
||||
Account const srcAccount_;
|
||||
Account const dstAccount_;
|
||||
STAmount const dstAmount_;
|
||||
int const searchLevel_;
|
||||
unsigned int const maxPaths_;
|
||||
|
||||
std::unique_ptr<Pathfinder> const& getPathFinder (Currency const& currency)
|
||||
{
|
||||
auto i = currencyMap_.find (currency);
|
||||
if (i != currencyMap_.end ())
|
||||
return i->second;
|
||||
auto pathfinder = std::make_unique<Pathfinder> (
|
||||
cache_, srcAccount_, dstAccount_, currency, dstAmount_);
|
||||
if (pathfinder->findPaths (searchLevel_))
|
||||
pathfinder->computePathRanks (maxPaths_);
|
||||
else
|
||||
pathfinder.reset (); // It's a bad request - clear it.
|
||||
return currencyMap_[currency] = std::move (pathfinder);
|
||||
|
||||
// TODO(tom): why doesn't this faster way compile?
|
||||
// return currencyMap_.insert (i, std::move (pathfinder)).second;
|
||||
}
|
||||
};
|
||||
|
||||
FindPaths::FindPaths (
|
||||
RippleLineCache::ref cache,
|
||||
Account const& srcAccount,
|
||||
Account const& dstAccount,
|
||||
STAmount const& dstAmount,
|
||||
int level,
|
||||
unsigned int maxPaths)
|
||||
: impl_ (std::make_unique<Impl> (
|
||||
cache, srcAccount, dstAccount, dstAmount, level, maxPaths))
|
||||
{
|
||||
}
|
||||
|
||||
FindPaths::~FindPaths() = default;
|
||||
|
||||
bool FindPaths::findPathsForIssue (
|
||||
Issue const& issue,
|
||||
STPathSet& pathsOut,
|
||||
STPath& fullLiquidityPath)
|
||||
{
|
||||
return impl_->findPathsForIssue (issue, pathsOut, fullLiquidityPath);
|
||||
}
|
||||
|
||||
bool findPathsForOneIssuer (
|
||||
RippleLineCache::ref cache,
|
||||
Account const& srcAccount,
|
||||
Account const& dstAccount,
|
||||
Issue const& srcIssue,
|
||||
STAmount const& dstAmount,
|
||||
int searchLevel,
|
||||
unsigned int const maxPaths,
|
||||
STPathSet& pathsOut,
|
||||
STPath& fullLiquidityPath)
|
||||
{
|
||||
Pathfinder pf (
|
||||
cache,
|
||||
srcAccount,
|
||||
dstAccount,
|
||||
srcIssue.currency,
|
||||
srcIssue.account,
|
||||
dstAmount);
|
||||
|
||||
if (!pf.findPaths (searchLevel))
|
||||
return false;
|
||||
|
||||
pf.addPathsFromPreviousPathfinding (pathsOut);
|
||||
pf.computePathRanks (maxPaths);
|
||||
pathsOut = pf.getBestPaths(maxPaths, fullLiquidityPath, srcIssue.account);
|
||||
return true;
|
||||
}
|
||||
|
||||
void initializePathfinding ()
|
||||
{
|
||||
Pathfinder::initPathTable ();
|
||||
}
|
||||
|
||||
} // ripple
|
||||
@@ -1,93 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLED_RIPPLE_APP_PATHS_FINDPATHS_H
|
||||
#define RIPPLED_RIPPLE_APP_PATHS_FINDPATHS_H
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class FindPaths
|
||||
{
|
||||
public:
|
||||
FindPaths (
|
||||
RippleLineCache::ref cache,
|
||||
Account const& srcAccount,
|
||||
Account const& dstAccount,
|
||||
STAmount const& dstAmount,
|
||||
/** searchLevel is the maximum search level allowed in an output path.
|
||||
*/
|
||||
int searchLevel,
|
||||
/** maxPaths is the maximum number of paths that can be returned in
|
||||
pathsOut. */
|
||||
unsigned int const maxPaths);
|
||||
~FindPaths();
|
||||
|
||||
bool findPathsForIssue (
|
||||
Issue const& issue,
|
||||
|
||||
/** On input, pathsOut contains any paths you want to ensure are
|
||||
included if still good.
|
||||
|
||||
On output, pathsOut will have any additional paths found. Only
|
||||
non-default paths without source or destination will be added. */
|
||||
STPathSet& pathsOut,
|
||||
|
||||
/** On input, fullLiquidityPath must be an empty STPath.
|
||||
|
||||
On output, if fullLiquidityPath is non-empty, it contains one extra
|
||||
path that can move the entire liquidity requested. */
|
||||
STPath& fullLiquidityPath);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
bool findPathsForOneIssuer (
|
||||
RippleLineCache::ref cache,
|
||||
Account const& srcAccount,
|
||||
Account const& dstAccount,
|
||||
Issue const& srcIssue,
|
||||
STAmount const& dstAmount,
|
||||
|
||||
/** searchLevel is the maximum search level allowed in an output path. */
|
||||
int searchLevel,
|
||||
|
||||
/** maxPaths is the maximum number of paths that can be returned in
|
||||
pathsOut. */
|
||||
unsigned int const maxPaths,
|
||||
|
||||
/** On input, pathsOut contains any paths you want to ensure are included if
|
||||
still good.
|
||||
|
||||
On output, pathsOut will have any additional paths found. Only
|
||||
non-default paths without source or destination will be added. */
|
||||
STPathSet& pathsOut,
|
||||
|
||||
/** On input, fullLiquidityPath must be an empty STPath.
|
||||
|
||||
On output, if fullLiquidityPath is non-empty, it contains one extra path
|
||||
that can move the entire liquidity requested. */
|
||||
STPath& fullLiquidityPath);
|
||||
|
||||
void initializePathfinding ();
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
@@ -17,31 +17,27 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/paths/AccountCurrencies.h>
|
||||
#include <ripple/app/paths/FindPaths.h>
|
||||
#include <ripple/types/UintTypes.h>
|
||||
#include <ripple/core/Config.h>
|
||||
#include <ripple/core/LoadFeeTrack.h>
|
||||
#include <ripple/types/UintTypes.h>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <tuple>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
PathRequest::PathRequest (
|
||||
const std::shared_ptr<InfoSub>& subscriber,
|
||||
int id,
|
||||
PathRequests& owner,
|
||||
const std::shared_ptr<InfoSub>& subscriber, int id, PathRequests& owner,
|
||||
beast::Journal journal)
|
||||
: m_journal (journal)
|
||||
, mOwner (owner)
|
||||
, wpSubscriber (subscriber)
|
||||
, jvStatus (Json::objectValue)
|
||||
, bValid (false)
|
||||
, mLastIndex (0)
|
||||
, mInProgress (false)
|
||||
, iLastLevel (0)
|
||||
, bLastSuccess (false)
|
||||
, iIdentifier (id)
|
||||
: m_journal (journal)
|
||||
, mOwner (owner)
|
||||
, wpSubscriber (subscriber)
|
||||
, jvStatus (Json::objectValue)
|
||||
, bValid (false)
|
||||
, mLastIndex (0)
|
||||
, mInProgress (false)
|
||||
, iLastLevel (0)
|
||||
, bLastSuccess (false)
|
||||
, iIdentifier (id)
|
||||
{
|
||||
if (m_journal.debug)
|
||||
m_journal.debug << iIdentifier << " created";
|
||||
@@ -49,8 +45,7 @@ PathRequest::PathRequest (
|
||||
}
|
||||
|
||||
static std::string const get_milli_diff (
|
||||
boost::posix_time::ptime const& after,
|
||||
boost::posix_time::ptime
|
||||
boost::posix_time::ptime const& after, boost::posix_time::ptime
|
||||
const& before)
|
||||
{
|
||||
return beast::lexicalCastThrow <std::string> (
|
||||
@@ -179,7 +174,7 @@ bool PathRequest::isValid (RippleLineCache::ref crCache)
|
||||
bool const disallowXRP (
|
||||
asDst->peekSLE ().getFlags() & lsfDisallowXRP);
|
||||
|
||||
auto usDestCurrID = accountDestCurrencies (
|
||||
auto usDestCurrID = usAccountDestCurrencies (
|
||||
raDstAccount, crCache, !disallowXRP);
|
||||
|
||||
for (auto const& currency : usDestCurrID)
|
||||
@@ -228,15 +223,11 @@ Json::Value PathRequest::doCreate (
|
||||
{
|
||||
if (bValid)
|
||||
{
|
||||
m_journal.debug << iIdentifier
|
||||
<< " valid: " << raSrcAccount.humanAccountID ();
|
||||
m_journal.debug << iIdentifier
|
||||
<< " Deliver: " << saDstAmount.getFullText ();
|
||||
m_journal.debug << iIdentifier << " valid: " << raSrcAccount.humanAccountID ();
|
||||
m_journal.debug << iIdentifier << " Deliver: " << saDstAmount.getFullText ();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_journal.debug << iIdentifier << " invalid";
|
||||
}
|
||||
}
|
||||
|
||||
valid = bValid;
|
||||
@@ -277,12 +268,10 @@ int PathRequest::parseJson (Json::Value const& jvParams, bool complete)
|
||||
|
||||
if (jvParams.isMember ("destination_amount"))
|
||||
{
|
||||
if (! amountFromJsonNoThrow (
|
||||
saDstAmount, jvParams["destination_amount"]) ||
|
||||
(saDstAmount.getCurrency ().isZero () &&
|
||||
saDstAmount.getIssuer ().isNonZero ()) ||
|
||||
(saDstAmount.getCurrency () == badCurrency ()) ||
|
||||
saDstAmount <= zero)
|
||||
if (! amountFromJsonNoThrow (saDstAmount, jvParams["destination_amount"]) ||
|
||||
(saDstAmount.getCurrency ().isZero () && saDstAmount.getIssuer ().isNonZero ()) ||
|
||||
(saDstAmount.getCurrency () == badCurrency()) ||
|
||||
saDstAmount <= zero)
|
||||
{
|
||||
jvStatus = rpcError (rpcDST_AMT_MALFORMED);
|
||||
return PFR_PJ_INVALID;
|
||||
@@ -331,11 +320,6 @@ int PathRequest::parseJson (Json::Value const& jvParams, bool complete)
|
||||
return PFR_PJ_INVALID;
|
||||
}
|
||||
|
||||
if (uCur.isNonZero() && uIss.isZero())
|
||||
{
|
||||
uIss = raSrcAccount.getAccountID();
|
||||
}
|
||||
|
||||
sciSourceCurrencies.insert ({uCur, uIss});
|
||||
}
|
||||
}
|
||||
@@ -379,16 +363,16 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
||||
if (sourceCurrencies.empty ())
|
||||
{
|
||||
auto usCurrencies =
|
||||
accountSourceCurrencies (raSrcAccount, cache, true);
|
||||
usAccountSourceCurrencies (raSrcAccount, cache, true);
|
||||
bool sameAccount = raSrcAccount == raDstAccount;
|
||||
for (auto const& c: usCurrencies)
|
||||
{
|
||||
if (!sameAccount || (c != saDstAmount.getCurrency ()))
|
||||
{
|
||||
if (c.isZero ())
|
||||
sourceCurrencies.insert ({c, xrpAccount()});
|
||||
sourceCurrencies.insert (std::make_pair (c, xrpAccount()));
|
||||
else
|
||||
sourceCurrencies.insert ({c, raSrcAccount.getAccountID ()});
|
||||
sourceCurrencies.insert (std::make_pair (c, raSrcAccount.getAccountID ()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -406,30 +390,26 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
||||
bool loaded = getApp().getFeeTrack().isLoadedLocal();
|
||||
|
||||
if (iLevel == 0)
|
||||
{
|
||||
// first pass
|
||||
{ // first pass
|
||||
if (loaded || fast)
|
||||
iLevel = getConfig().PATH_SEARCH_FAST;
|
||||
else
|
||||
iLevel = getConfig().PATH_SEARCH;
|
||||
}
|
||||
else if ((iLevel == getConfig().PATH_SEARCH_FAST) && !fast)
|
||||
{
|
||||
// leaving fast pathfinding
|
||||
{ // leaving fast pathfinding
|
||||
iLevel = getConfig().PATH_SEARCH;
|
||||
if (loaded && (iLevel > getConfig().PATH_SEARCH_FAST))
|
||||
--iLevel;
|
||||
}
|
||||
else if (bLastSuccess)
|
||||
{
|
||||
// decrement, if possible
|
||||
{ // decrement, if possible
|
||||
if (iLevel > getConfig().PATH_SEARCH ||
|
||||
(loaded && (iLevel > getConfig().PATH_SEARCH_FAST)))
|
||||
--iLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
// adjust as needed
|
||||
{ // adjust as needed
|
||||
if (!loaded && (iLevel < getConfig().PATH_SEARCH_MAX))
|
||||
++iLevel;
|
||||
if (loaded && (iLevel > getConfig().PATH_SEARCH_FAST))
|
||||
@@ -440,17 +420,10 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
||||
|
||||
bool found = false;
|
||||
|
||||
FindPaths fp (
|
||||
cache,
|
||||
raSrcAccount.getAccountID (),
|
||||
raDstAccount.getAccountID (),
|
||||
saDstAmount,
|
||||
iLevel,
|
||||
4); // iMaxPaths
|
||||
for (auto const& currIssuer: sourceCurrencies)
|
||||
{
|
||||
{
|
||||
STAmount test (currIssuer, 1);
|
||||
STAmount test ({currIssuer.first, currIssuer.second}, 1);
|
||||
if (m_journal.debug)
|
||||
{
|
||||
m_journal.debug
|
||||
@@ -458,28 +431,26 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
||||
<< " Trying to find paths: " << test.getFullText ();
|
||||
}
|
||||
}
|
||||
bool valid;
|
||||
STPathSet& spsPaths = mContext[currIssuer];
|
||||
STPath fullLiquidityPath;
|
||||
auto valid = fp.findPathsForIssue (
|
||||
currIssuer,
|
||||
spsPaths,
|
||||
fullLiquidityPath);
|
||||
Pathfinder pf (cache, raSrcAccount, raDstAccount,
|
||||
currIssuer.first, currIssuer.second, saDstAmount, valid);
|
||||
CondLog (!valid, lsDEBUG, PathRequest)
|
||||
<< iIdentifier << " PF request not valid";
|
||||
|
||||
if (valid)
|
||||
STPath extraPath;
|
||||
if (valid && pf.findPaths (iLevel, 4, spsPaths, extraPath))
|
||||
{
|
||||
LedgerEntrySet lesSandbox (cache->getLedger (), tapNONE);
|
||||
auto& sourceAccount = !isXRP (currIssuer.account)
|
||||
? currIssuer.account
|
||||
: isXRP (currIssuer.currency)
|
||||
auto& account = currIssuer.second.isNonZero ()
|
||||
? Account(currIssuer.second)
|
||||
: isXRP (currIssuer.first)
|
||||
? xrpAccount()
|
||||
: raSrcAccount.getAccountID ();
|
||||
STAmount saMaxAmount ({currIssuer.currency, sourceAccount}, 1);
|
||||
STAmount saMaxAmount ({currIssuer.first, account}, 1);
|
||||
|
||||
saMaxAmount.negate ();
|
||||
m_journal.debug << iIdentifier
|
||||
<< " Paths found, calling rippleCalc";
|
||||
m_journal.debug << iIdentifier << " Paths found, calling rippleCalc";
|
||||
auto rc = path::RippleCalc::rippleCalculate (
|
||||
lesSandbox,
|
||||
saMaxAmount,
|
||||
@@ -488,15 +459,13 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
||||
raSrcAccount.getAccountID (),
|
||||
spsPaths);
|
||||
|
||||
if (!fullLiquidityPath.empty() &&
|
||||
if (!extraPath.empty() &&
|
||||
(rc.result () == terNO_LINE || rc.result () == tecPATH_PARTIAL))
|
||||
{
|
||||
m_journal.debug
|
||||
<< iIdentifier << " Trying with an extra path element";
|
||||
spsPaths.push_back (fullLiquidityPath);
|
||||
lesSandbox.clear();
|
||||
rc = path::RippleCalc::rippleCalculate (
|
||||
lesSandbox,
|
||||
spsPaths.push_back (extraPath);
|
||||
rc = path::RippleCalc::rippleCalculate (lesSandbox,
|
||||
saMaxAmount,
|
||||
saDstAmount,
|
||||
raDstAccount.getAccountID (),
|
||||
@@ -515,10 +484,8 @@ Json::Value PathRequest::doUpdate (RippleLineCache::ref cache, bool fast)
|
||||
if (rc.result () == tesSUCCESS)
|
||||
{
|
||||
Json::Value jvEntry (Json::objectValue);
|
||||
rc.actualAmountIn.setIssuer (sourceAccount);
|
||||
|
||||
jvEntry["source_amount"] = rc.actualAmountIn.getJson (0);
|
||||
jvEntry["paths_computed"] = spsPaths.getJson (0);
|
||||
jvEntry["source_amount"] = rc.actualAmountIn.getJson (0);
|
||||
jvEntry["paths_computed"] = spsPaths.getJson (0);
|
||||
found = true;
|
||||
jvArray.append (jvEntry);
|
||||
}
|
||||
|
||||
@@ -45,13 +45,13 @@ public:
|
||||
typedef const pointer& ref;
|
||||
typedef const wptr& wref;
|
||||
|
||||
// TODO(tom): Use Issue instead!
|
||||
typedef std::pair<Currency, Account> CurrencyIssuer;
|
||||
|
||||
public:
|
||||
// VFALCO TODO Break the cyclic dependency on InfoSub
|
||||
PathRequest (
|
||||
std::shared_ptr <InfoSub> const& subscriber,
|
||||
int id,
|
||||
PathRequests&,
|
||||
beast::Journal journal);
|
||||
PathRequest (std::shared_ptr <InfoSub> const& subscriber,
|
||||
int id, PathRequests&, beast::Journal journal);
|
||||
|
||||
~PathRequest ();
|
||||
|
||||
@@ -97,8 +97,8 @@ private:
|
||||
RippleAddress raDstAccount;
|
||||
STAmount saDstAmount;
|
||||
|
||||
std::set<Issue> sciSourceCurrencies;
|
||||
std::map<Issue, STPathSet> mContext;
|
||||
std::set<CurrencyIssuer> sciSourceCurrencies;
|
||||
std::map<CurrencyIssuer, STPathSet> mContext;
|
||||
|
||||
bool bValid;
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/paths/Credit.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// OPTIMIZE: When calculating path increment, note if increment consumes all
|
||||
@@ -316,13 +314,13 @@ TER PathState::pushNode (
|
||||
|
||||
if (resultCode == tesSUCCESS)
|
||||
{
|
||||
STAmount saOwed = creditBalance (lesEntries,
|
||||
STAmount saOwed = credit_balance (lesEntries,
|
||||
node.account_, backNode.account_,
|
||||
node.issue_.currency);
|
||||
STAmount saLimit;
|
||||
|
||||
if (saOwed <= zero) {
|
||||
saLimit = creditLimit (lesEntries,
|
||||
saLimit = credit_limit (lesEntries,
|
||||
node.account_,
|
||||
backNode.account_,
|
||||
node.issue_.currency);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,160 +31,114 @@ namespace ripple {
|
||||
class Pathfinder
|
||||
{
|
||||
public:
|
||||
/** Construct a pathfinder with an issuer.*/
|
||||
Pathfinder (
|
||||
RippleLineCache::ref cache,
|
||||
Account const& srcAccount,
|
||||
Account const& dstAccount,
|
||||
Currency const& uSrcCurrency,
|
||||
Account const& uSrcIssuer,
|
||||
STAmount const& dstAmount);
|
||||
RippleAddress const& srcAccountID,
|
||||
RippleAddress const& dstAccountID,
|
||||
Currency const& srcCurrencyID,
|
||||
Account const& srcIssuerID,
|
||||
STAmount const& dstAmount,
|
||||
bool& bValid);
|
||||
|
||||
/** Construct a pathfinder without an issuer.*/
|
||||
Pathfinder (
|
||||
RippleLineCache::ref cache,
|
||||
Account const& srcAccount,
|
||||
Account const& dstAccount,
|
||||
Currency const& uSrcCurrency,
|
||||
STAmount const& dstAmount);
|
||||
static void initPathTable();
|
||||
|
||||
~Pathfinder();
|
||||
bool findPaths (
|
||||
int iLevel,
|
||||
unsigned int const iMaxPaths,
|
||||
STPathSet& spsDst,
|
||||
STPath& spExtraPath);
|
||||
|
||||
static void initPathTable ();
|
||||
|
||||
bool findPaths (int searchLevel);
|
||||
|
||||
/** Make sure that all the input paths are included in mCompletePaths. */
|
||||
void addPathsFromPreviousPathfinding (STPathSet&);
|
||||
|
||||
/** Compute the rankings of the paths. */
|
||||
void computePathRanks (int maxPaths);
|
||||
|
||||
/* Get the best paths, up to maxPaths in number, from mCompletePaths.
|
||||
|
||||
On return, if fullLiquidityPath is not empty, then it contains the best
|
||||
additional single path which can consume all the liquidity.
|
||||
*/
|
||||
STPathSet getBestPaths (
|
||||
int maxPaths,
|
||||
STPath& fullLiquidityPath,
|
||||
Account const& srcIssuer);
|
||||
|
||||
enum NodeType
|
||||
{
|
||||
nt_SOURCE, // The source account: with an issuer account, if needed.
|
||||
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.
|
||||
};
|
||||
|
||||
// The PathType is a list of the NodeTypes for a path.
|
||||
using PathType = std::vector <NodeType>;
|
||||
|
||||
// PaymentType represents the types of the source and destination currencies
|
||||
// in a path request.
|
||||
private:
|
||||
enum PaymentType
|
||||
{
|
||||
pt_XRP_to_XRP,
|
||||
pt_XRP_to_nonXRP,
|
||||
pt_nonXRP_to_XRP,
|
||||
pt_nonXRP_to_same, // Destination currency is the same as source.
|
||||
pt_nonXRP_to_nonXRP // Destination currency is NOT the same as source.
|
||||
pt_nonXRP_to_same,
|
||||
pt_nonXRP_to_nonXRP
|
||||
};
|
||||
|
||||
struct PathRank
|
||||
enum NodeType
|
||||
{
|
||||
std::uint64_t quality;
|
||||
std::uint64_t length;
|
||||
STAmount liquidity;
|
||||
int index;
|
||||
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
|
||||
};
|
||||
|
||||
private:
|
||||
/*
|
||||
Call graph of Pathfinder methods.
|
||||
typedef std::vector<NodeType> PathType_t;
|
||||
typedef std::pair<int, PathType_t> CostedPath_t;
|
||||
typedef std::vector<CostedPath_t> CostedPathList_t;
|
||||
|
||||
findPaths:
|
||||
addPathsForType:
|
||||
addLinks:
|
||||
addLink:
|
||||
getPathsOut
|
||||
issueMatchesOrigin
|
||||
isNoRippleOut:
|
||||
isNoRipple
|
||||
typedef std::pair<int, const char*> PathCost;
|
||||
typedef std::vector<PathCost> PathCostList;
|
||||
|
||||
addPathsFromPreviousPathfinding
|
||||
|
||||
computePathRanks:
|
||||
rippleCalculate
|
||||
getPathLiquidity:
|
||||
rippleCalculate
|
||||
|
||||
getBestPaths
|
||||
*/
|
||||
typedef std::map<PaymentType, CostedPathList_t> PathTable;
|
||||
|
||||
|
||||
// Add all paths of one type to mCompletePaths.
|
||||
STPathSet& addPathsForType (PathType const& type);
|
||||
/** Fill a CostedPathList_t from its description. */
|
||||
static void fillPaths(PaymentType type,
|
||||
PathCostList const& costs);
|
||||
|
||||
bool issueMatchesOrigin (Issue const&);
|
||||
/** @return true if any building paths are now complete. */
|
||||
bool checkComplete (STPathSet& retPathSet);
|
||||
|
||||
static std::string pathTypeToString(PathType_t const&);
|
||||
|
||||
bool matchesOrigin (Issue const&);
|
||||
|
||||
int getPathsOut (
|
||||
Currency const& currency,
|
||||
Account const& account,
|
||||
Account const& accountID,
|
||||
bool isDestCurrency,
|
||||
Account const& dest);
|
||||
|
||||
void addLink (
|
||||
void addLink(
|
||||
STPath const& currentPath,
|
||||
STPathSet& incompletePaths,
|
||||
int addFlags);
|
||||
|
||||
// Call addLink() for each path in currentPaths.
|
||||
void addLinks (
|
||||
void addLink(
|
||||
STPathSet const& currentPaths,
|
||||
STPathSet& incompletePaths,
|
||||
int addFlags);
|
||||
|
||||
// Compute the liquidity for a path. Return tesSUCCESS if it has has enough
|
||||
// liquidity to be worth keeping, otherwise an error.
|
||||
TER getPathLiquidity (
|
||||
STPath const& path, // IN: The path to check.
|
||||
STAmount const& minDstAmount, // IN: The minimum output this path must
|
||||
// deliver to be worth keeping.
|
||||
STAmount& amountOut, // OUT: The actual liquidity on the path.
|
||||
uint64_t& qualityOut) const; // OUT: The returned initial quality
|
||||
STPathSet& getPaths(PathType_t const& type,
|
||||
bool addComplete = true);
|
||||
|
||||
STPathSet filterPaths(int iMaxPaths,
|
||||
STPath& extraPath);
|
||||
|
||||
TER checkPath (STPath const& path, STAmount const& minDestAmount,
|
||||
STAmount& amount, uint64_t& quality) const;
|
||||
|
||||
// Does this path end on an account-to-account link whose last account has
|
||||
// set the "no ripple" flag on the link?
|
||||
bool isNoRippleOut (STPath const& currentPath);
|
||||
|
||||
// Is the "no ripple" flag set from one account to another?
|
||||
bool isNoRipple (
|
||||
Account const& fromAccount,
|
||||
Account const& toAccount,
|
||||
Currency const& currency);
|
||||
Account const& setByID,
|
||||
Account const& setOnID,
|
||||
Currency const& currencyID);
|
||||
|
||||
Account mSrcAccount;
|
||||
Account mDstAccount;
|
||||
STAmount mDstAmount;
|
||||
Currency mSrcCurrency;
|
||||
boost::optional<Account> mSrcIssuer;
|
||||
STAmount mSrcAmount;
|
||||
/** The amount remaining from mSrcAccount after the default liquidity has
|
||||
been removed. */
|
||||
STAmount mRemainingAmount;
|
||||
// Our main table of paths
|
||||
|
||||
Ledger::pointer mLedger;
|
||||
LoadEvent::pointer m_loadEvent;
|
||||
RippleLineCache::pointer mRLCache;
|
||||
static PathTable mPathTable;
|
||||
static PathType_t makePath(char const*);
|
||||
|
||||
Account mSrcAccountID;
|
||||
Account mDstAccountID;
|
||||
STAmount mDstAmount;
|
||||
Currency mSrcCurrencyID;
|
||||
Account mSrcIssuerID;
|
||||
STAmount mSrcAmount;
|
||||
|
||||
Ledger::pointer mLedger;
|
||||
LoadEvent::pointer m_loadEvent;
|
||||
RippleLineCache::pointer mRLCache;
|
||||
|
||||
STPathElement mSource;
|
||||
STPathSet mCompletePaths;
|
||||
std::vector<PathRank> mPathRanks;
|
||||
std::map<PathType, STPathSet> mPaths;
|
||||
std::map<PathType_t, STPathSet> mPaths;
|
||||
|
||||
hash_map<Issue, int> mPathsOutCountMap;
|
||||
|
||||
@@ -192,18 +146,51 @@ private:
|
||||
static std::uint32_t const afADD_ACCOUNTS = 0x001;
|
||||
|
||||
// Add order books
|
||||
static std::uint32_t const afADD_BOOKS = 0x002;
|
||||
static std::uint32_t const afADD_BOOKS = 0x002;
|
||||
|
||||
// Add order book to XRP only
|
||||
static std::uint32_t const afOB_XRP = 0x010;
|
||||
static std::uint32_t const afOB_XRP = 0x010;
|
||||
|
||||
// Must link to destination currency
|
||||
static std::uint32_t const afOB_LAST = 0x040;
|
||||
static std::uint32_t const afOB_LAST = 0x040;
|
||||
|
||||
// Destination account only
|
||||
static std::uint32_t const afAC_LAST = 0x080;
|
||||
static std::uint32_t const afAC_LAST = 0x080;
|
||||
};
|
||||
|
||||
CurrencySet usAccountDestCurrencies
|
||||
(RippleAddress const& raAccountID,
|
||||
RippleLineCache::ref cache,
|
||||
bool includeXRP);
|
||||
|
||||
CurrencySet usAccountSourceCurrencies
|
||||
(RippleAddress const& raAccountID,
|
||||
RippleLineCache::ref lrLedger,
|
||||
bool includeXRP);
|
||||
|
||||
/** Calculate the maximum amount of IOUs that an account can hold
|
||||
@param ledger the ledger to check against.
|
||||
@param account the account of interest.
|
||||
@param issuer the issuer of the IOU.
|
||||
@param currency the IOU to check.
|
||||
@return The maximum amount that can be held.
|
||||
*/
|
||||
STAmount
|
||||
credit_limit (
|
||||
LedgerEntrySet& ledger, Account const& account,
|
||||
Account const& issuer, Currency const& currency);
|
||||
|
||||
/** Returns the amount of IOUs issued by issuer that are held by an account
|
||||
@param ledger the ledger to check against.
|
||||
@param account the account of interest.
|
||||
@param issuer the issuer of the IOU.
|
||||
@param currency the IOU to check.
|
||||
*/
|
||||
STAmount
|
||||
credit_balance (
|
||||
LedgerEntrySet& ledger, Account const& account,
|
||||
Account const& issuer, Currency const& currency);
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/book/Quality.h>
|
||||
#include <ripple/app/paths/Credit.h>
|
||||
#include <ripple/app/paths/cursor/RippleLiquidity.h>
|
||||
|
||||
namespace ripple {
|
||||
@@ -47,8 +46,8 @@ TER PathCursor::reverseLiquidityForAccount () const
|
||||
auto const isFinalNode = (nodeIndex_ == lastNodeIndex);
|
||||
|
||||
// 0 quality means none has yet been determined.
|
||||
std::uint64_t uRateMax = 0
|
||||
;
|
||||
std::uint64_t uRateMax = 0;
|
||||
|
||||
// Current is allowed to redeem to next.
|
||||
const bool previousNodeIsAccount = !nodeIndex_ ||
|
||||
previousNode().isAccount();
|
||||
@@ -81,7 +80,7 @@ TER PathCursor::reverseLiquidityForAccount () const
|
||||
// For previousNodeIsAccount:
|
||||
// Previous account is already owed.
|
||||
const STAmount saPrvOwed = (previousNodeIsAccount && nodeIndex_ != 0)
|
||||
? creditBalance (ledger(),
|
||||
? credit_balance (ledger(),
|
||||
node().account_,
|
||||
previousAccountID,
|
||||
node().issue_.currency)
|
||||
@@ -89,7 +88,7 @@ TER PathCursor::reverseLiquidityForAccount () const
|
||||
|
||||
// The limit amount that the previous account may owe.
|
||||
const STAmount saPrvLimit = (previousNodeIsAccount && nodeIndex_ != 0)
|
||||
? creditLimit (ledger(),
|
||||
? credit_limit (ledger(),
|
||||
node().account_,
|
||||
previousAccountID,
|
||||
node().issue_.currency)
|
||||
@@ -97,7 +96,7 @@ TER PathCursor::reverseLiquidityForAccount () const
|
||||
|
||||
// Next account is owed.
|
||||
const STAmount saNxtOwed = (nextNodeIsAccount && nodeIndex_ != lastNodeIndex)
|
||||
? creditBalance (ledger(),
|
||||
? credit_balance (ledger(),
|
||||
node().account_,
|
||||
nextAccountID,
|
||||
node().issue_.currency)
|
||||
|
||||
@@ -33,7 +33,7 @@ char const* getRawVersionString ()
|
||||
//
|
||||
// The build version number (edit this for each release)
|
||||
//
|
||||
"0.26.4-sp1"
|
||||
"0.26.4-sp2"
|
||||
//
|
||||
// Must follow the format described here:
|
||||
//
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/paths/AccountCurrencies.h>
|
||||
#include <ripple/app/paths/FindPaths.h>
|
||||
#include <ripple/rpc/impl/LegacyPathFind.h>
|
||||
|
||||
namespace ripple {
|
||||
@@ -121,10 +119,11 @@ Json::Value doRipplePathFind (RPC::Context& context)
|
||||
}
|
||||
else
|
||||
{
|
||||
auto currencies = accountSourceCurrencies (raSrc, cache, true);
|
||||
auto usCurrencies = usAccountSourceCurrencies (raSrc, cache, true);
|
||||
|
||||
jvSrcCurrencies = Json::Value (Json::arrayValue);
|
||||
|
||||
for (auto const& uCurrency: currencies)
|
||||
for (auto const& uCurrency: usCurrencies)
|
||||
{
|
||||
Json::Value jvCurrency (Json::objectValue);
|
||||
jvCurrency["currency"] = to_string(uCurrency);
|
||||
@@ -135,9 +134,7 @@ Json::Value doRipplePathFind (RPC::Context& context)
|
||||
// Fill in currencies destination will accept
|
||||
Json::Value jvDestCur (Json::arrayValue);
|
||||
|
||||
// TODO(tom): this could be optimized the same way that
|
||||
// PathRequest::doUpdate() is - if we don't obsolete this code first.
|
||||
auto usDestCurrID = accountDestCurrencies (raDst, cache, true);
|
||||
auto usDestCurrID = usAccountDestCurrencies (raDst, cache, true);
|
||||
for (auto const& uCurrency: usDestCurrID)
|
||||
jvDestCur.append (to_string (uCurrency));
|
||||
|
||||
@@ -146,29 +143,6 @@ Json::Value doRipplePathFind (RPC::Context& context)
|
||||
|
||||
Json::Value jvArray (Json::arrayValue);
|
||||
|
||||
int level = getConfig().PATH_SEARCH_OLD;
|
||||
if ((getConfig().PATH_SEARCH_MAX > level)
|
||||
&& !getApp().getFeeTrack().isLoadedLocal())
|
||||
{
|
||||
++level;
|
||||
}
|
||||
|
||||
if (context.params_.isMember("depth")
|
||||
&& context.params_["depth"].isIntegral())
|
||||
{
|
||||
int rLev = context.params_["search_depth"].asInt ();
|
||||
if ((rLev < level) || (context.role_ == Config::ADMIN))
|
||||
level = rLev;
|
||||
}
|
||||
|
||||
FindPaths fp (
|
||||
cache,
|
||||
raSrc.getAccountID(),
|
||||
raDst.getAccountID(),
|
||||
saDstAmount,
|
||||
level,
|
||||
4); // max paths
|
||||
|
||||
for (unsigned int i = 0; i != jvSrcCurrencies.size (); ++i)
|
||||
{
|
||||
Json::Value jvSource = jvSrcCurrencies[i];
|
||||
@@ -203,6 +177,11 @@ Json::Value doRipplePathFind (RPC::Context& context)
|
||||
return rpcError (rpcSRC_ISR_MALFORMED);
|
||||
}
|
||||
|
||||
STPathSet spsComputed;
|
||||
bool bValid;
|
||||
Pathfinder pf (cache, raSrc, raDst, uSrcCurrencyID,
|
||||
uSrcIssuerID, saDstAmount, bValid);
|
||||
|
||||
int level = getConfig().PATH_SEARCH_OLD;
|
||||
if ((getConfig().PATH_SEARCH_MAX > level)
|
||||
&& !getApp().getFeeTrack().isLoadedLocal())
|
||||
@@ -217,7 +196,6 @@ Json::Value doRipplePathFind (RPC::Context& context)
|
||||
level = rLev;
|
||||
}
|
||||
|
||||
STPathSet spsComputed;
|
||||
if (context.params_.isMember("paths"))
|
||||
{
|
||||
STParsedJSONObject paths ("paths", context.params_["paths"]);
|
||||
@@ -227,12 +205,8 @@ Json::Value doRipplePathFind (RPC::Context& context)
|
||||
spsComputed = paths.object.get()->downcast<STPathSet> ();
|
||||
}
|
||||
|
||||
STPath fullLiquidityPath;
|
||||
auto valid = fp.findPathsForIssue (
|
||||
{uSrcCurrencyID, uSrcIssuerID},
|
||||
spsComputed,
|
||||
fullLiquidityPath);
|
||||
if (!valid)
|
||||
STPath extraPath;
|
||||
if (!bValid || !pf.findPaths (level, 4, spsComputed, extraPath))
|
||||
{
|
||||
WriteLog (lsWARNING, RPCHandler)
|
||||
<< "ripple_path_find: No paths found.";
|
||||
@@ -267,13 +241,13 @@ Json::Value doRipplePathFind (RPC::Context& context)
|
||||
<< " saMaxAmountAct=" << rc.actualAmountIn
|
||||
<< " saDstAmountAct=" << rc.actualAmountOut;
|
||||
|
||||
if (fullLiquidityPath.size() > 0 &&
|
||||
if (extraPath.size() > 0 &&
|
||||
(rc.result() == terNO_LINE || rc.result() == tecPATH_PARTIAL))
|
||||
{
|
||||
WriteLog (lsDEBUG, PathRequest)
|
||||
<< "Trying with an extra path element";
|
||||
|
||||
spsComputed.push_back (fullLiquidityPath);
|
||||
spsComputed.push_back (extraPath);
|
||||
lesSandbox.clear ();
|
||||
rc = path::RippleCalc::rippleCalculate (
|
||||
lesSandbox,
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/paths/FindPaths.h>
|
||||
#include <ripple/basics/StringUtilities.h>
|
||||
#include <ripple/rpc/impl/TransactionSign.h>
|
||||
#include <beast/unit_test.h>
|
||||
@@ -126,6 +125,7 @@ static Json::Value signPayment(
|
||||
&& params.isMember ("build_path"))
|
||||
{
|
||||
// Need a ripple path.
|
||||
STPathSet spsPaths;
|
||||
Currency uSrcCurrencyID;
|
||||
Account uSrcIssuerID;
|
||||
|
||||
@@ -152,21 +152,22 @@ static Json::Value signPayment(
|
||||
if (!lpf.isOk ())
|
||||
return rpcError (rpcTOO_BUSY);
|
||||
|
||||
bool bValid;
|
||||
auto cache = std::make_shared<RippleLineCache> (lSnapshot);
|
||||
STPathSet spsPaths;
|
||||
STPath fullLiquidityPath;
|
||||
auto valid = findPathsForOneIssuer (
|
||||
Pathfinder pf (
|
||||
cache,
|
||||
raSrcAddressID.getAccountID(),
|
||||
dstAccountID.getAccountID(),
|
||||
saSendMax.issue (),
|
||||
amount,
|
||||
getConfig ().PATH_SEARCH_OLD,
|
||||
4, // iMaxPaths
|
||||
spsPaths,
|
||||
fullLiquidityPath);
|
||||
raSrcAddressID,
|
||||
dstAccountID,
|
||||
saSendMax.getCurrency (),
|
||||
saSendMax.getIssuer (),
|
||||
amount, bValid);
|
||||
|
||||
if (!valid)
|
||||
STPath extraPath;
|
||||
if (!bValid ||
|
||||
!pf.findPaths (getConfig ().PATH_SEARCH_OLD,
|
||||
4,
|
||||
spsPaths,
|
||||
extraPath))
|
||||
{
|
||||
WriteLog (lsDEBUG, RPCHandler)
|
||||
<< "transactionSign: build_path: No paths found.";
|
||||
|
||||
@@ -117,5 +117,7 @@
|
||||
#include <ripple/app/main/ParameterTable.h>
|
||||
#include <ripple/app/paths/PathState.h>
|
||||
#include <ripple/app/paths/RippleCalc.h>
|
||||
#include <ripple/app/paths/Pathfinder.h>
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -29,8 +29,5 @@
|
||||
#include <ripple/app/ledger/OrderBookIterator.cpp>
|
||||
#include <ripple/app/consensus/DisputedTx.cpp>
|
||||
#include <ripple/app/misc/HashRouter.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/misc/AmendmentTableImpl.cpp>
|
||||
|
||||
Reference in New Issue
Block a user