mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Rough cut at ripple_path_find.
This commit is contained in:
@@ -84,7 +84,7 @@ Pathfinder::Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID,
|
|||||||
// Returns a single path, if possible.
|
// Returns a single path, if possible.
|
||||||
// --> maxSearchSteps: unused
|
// --> maxSearchSteps: unused
|
||||||
// --> maxPay: unused
|
// --> maxPay: unused
|
||||||
bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet)
|
bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet, bool bAllowEmpty)
|
||||||
{
|
{
|
||||||
if (mLedger) {
|
if (mLedger) {
|
||||||
std::queue<STPath> pqueue;
|
std::queue<STPath> pqueue;
|
||||||
@@ -107,16 +107,28 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet
|
|||||||
// Determine if path is solved.
|
// Determine if path is solved.
|
||||||
|
|
||||||
// Done, if dest wants XRP and last element produces XRP.
|
// Done, if dest wants XRP and last element produces XRP.
|
||||||
// Done, if dest wants non-XRP and last element is dest.
|
if (!ele.mCurrencyID // Tail output is XRP
|
||||||
|
&& !mDstAmount.getCurrency()) {
|
||||||
|
|
||||||
if (!ele.mCurrencyID) {
|
// Remove implied first.
|
||||||
|
path.mPath.erase(path.mPath.begin());
|
||||||
|
|
||||||
|
// Return the path.
|
||||||
|
retPathSet.addPath(path);
|
||||||
|
|
||||||
|
cLog(lsDEBUG) << "findPaths: adding: " << path.getJson(0);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (ele.mAccountID == mDstAccountID) {
|
|
||||||
|
// Done, if dest wants non-XRP and last element is dest.
|
||||||
|
// YYY Allows going through self. Is this wanted?
|
||||||
|
if (ele.mAccountID == mDstAccountID // Tail is destination
|
||||||
|
&& ele.mCurrencyID == mDstAmount.getCurrency()) { // With correct output currency.
|
||||||
// Found a path to the destination.
|
// Found a path to the destination.
|
||||||
|
|
||||||
if (2 == path.mPath.size()) {
|
if (!bAllowEmpty && 2 == path.mPath.size()) {
|
||||||
// Empty path is default. Drop it.
|
// Empty path is default. Drop it.
|
||||||
// XXX Don't drop empty path - we still want an estimate.
|
|
||||||
cLog(lsDEBUG) << "findPaths: dropping empty path.";
|
cLog(lsDEBUG) << "findPaths: dropping empty path.";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -128,14 +140,19 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet
|
|||||||
// Return the path.
|
// Return the path.
|
||||||
retPathSet.addPath(path);
|
retPathSet.addPath(path);
|
||||||
|
|
||||||
|
cLog(lsDEBUG) << "findPaths: adding: " << path.getJson(0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bContinued = false;
|
||||||
|
|
||||||
if (!ele.mCurrencyID) {
|
if (!ele.mCurrencyID) {
|
||||||
// Last element is for XRP continue with qualifying books.
|
// Last element is for XRP continue with qualifying books.
|
||||||
|
|
||||||
BOOST_FOREACH(OrderBook::pointer book, mOrderBook.getXRPInBooks())
|
BOOST_FOREACH(OrderBook::pointer book, mOrderBook.getXRPInBooks())
|
||||||
{
|
{
|
||||||
|
// XXX Don't allow looping through same order books.
|
||||||
|
|
||||||
//if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
|
//if (!path.hasSeen(line->getAccountIDPeer().getAccountID()))
|
||||||
{
|
{
|
||||||
STPath new_path(path);
|
STPath new_path(path);
|
||||||
@@ -145,10 +162,20 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet
|
|||||||
new_path.mCurrencyID = book->getCurrencyOut();
|
new_path.mCurrencyID = book->getCurrencyOut();
|
||||||
new_path.mCurrentAccount = book->getCurrencyOut();
|
new_path.mCurrentAccount = book->getCurrencyOut();
|
||||||
|
|
||||||
|
cLog(lsDEBUG) <<
|
||||||
|
boost::str(boost::format("findPaths: XRP input - %s/%s")
|
||||||
|
% STAmount::createHumanCurrency(new_path.mCurrencyID)
|
||||||
|
% RippleAddress::createHumanAccountID(new_path.mCurrentAccount));
|
||||||
|
|
||||||
pqueue.push(new_path);
|
pqueue.push(new_path);
|
||||||
|
|
||||||
|
bContinued = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tLog(!bContinued, lsDEBUG)
|
||||||
|
<< boost::str(boost::format("findPaths: XRP input - dead end"));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Last element is for non-XRP continue by adding ripple lines and order books.
|
// Last element is for non-XRP continue by adding ripple lines and order books.
|
||||||
|
|
||||||
@@ -164,8 +191,17 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet
|
|||||||
ele.mCurrencyID,
|
ele.mCurrencyID,
|
||||||
uint160());
|
uint160());
|
||||||
|
|
||||||
|
cLog(lsDEBUG) <<
|
||||||
|
boost::str(boost::format("findPaths: %s/%s --> %s/%s")
|
||||||
|
% RippleAddress::createHumanAccountID(ele.mAccountID)
|
||||||
|
% STAmount::createHumanCurrency(ele.mCurrencyID)
|
||||||
|
% RippleAddress::createHumanAccountID(line->getAccountIDPeer().getAccountID())
|
||||||
|
% STAmount::createHumanCurrency(ele.mCurrencyID));
|
||||||
|
|
||||||
new_path.mPath.push_back(new_ele);
|
new_path.mPath.push_back(new_ele);
|
||||||
pqueue.push(new_path);
|
pqueue.push(new_path);
|
||||||
|
|
||||||
|
bContinued = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,17 +215,31 @@ bool Pathfinder::findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet
|
|||||||
STPath new_path(path);
|
STPath new_path(path);
|
||||||
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
|
STPathElement new_ele(uint160(), book->getCurrencyOut(), book->getIssuerOut());
|
||||||
|
|
||||||
|
cLog(lsDEBUG) <<
|
||||||
|
boost::str(boost::format("findPaths: %s/%s :: %s/%s")
|
||||||
|
% STAmount::createHumanCurrency(ele.mCurrencyID)
|
||||||
|
% RippleAddress::createHumanAccountID(ele.mAccountID)
|
||||||
|
% STAmount::createHumanCurrency(book->getCurrencyOut())
|
||||||
|
% RippleAddress::createHumanAccountID(book->getIssuerOut()));
|
||||||
|
|
||||||
new_path.mPath.push_back(new_ele);
|
new_path.mPath.push_back(new_ele);
|
||||||
new_path.mCurrentAccount=book->getIssuerOut();
|
new_path.mCurrentAccount=book->getIssuerOut();
|
||||||
new_path.mCurrencyID=book->getCurrencyOut();
|
new_path.mCurrencyID=book->getCurrencyOut();
|
||||||
|
|
||||||
pqueue.push(new_path);
|
pqueue.push(new_path);
|
||||||
|
|
||||||
|
bContinued = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// enumerate all adjacent nodes, construct a new path and push it into the queue
|
tLog(!bContinued, lsDEBUG)
|
||||||
} // While
|
<< boost::str(boost::format("findPaths: non-XRP input - dead end"));
|
||||||
} // if there is a ledger
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cLog(lsWARNING) << boost::str(boost::format("findPaths: no ledger"));
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,20 +38,20 @@ class Pathfinder
|
|||||||
OrderBookDB mOrderBook;
|
OrderBookDB mOrderBook;
|
||||||
Ledger::pointer mLedger;
|
Ledger::pointer mLedger;
|
||||||
|
|
||||||
std::list<PathOption::pointer> mBuildingPaths;
|
// std::list<PathOption::pointer> mBuildingPaths;
|
||||||
std::list<PathOption::pointer> mCompletePaths;
|
// std::list<PathOption::pointer> mCompletePaths;
|
||||||
|
|
||||||
void addOptions(PathOption::pointer tail);
|
// void addOptions(PathOption::pointer tail);
|
||||||
|
|
||||||
// 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);
|
// void addPathOption(PathOption::pointer pathOption);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount);
|
Pathfinder(RippleAddress& srcAccountID, RippleAddress& dstAccountID, uint160& srcCurrencyID, STAmount dstAmount);
|
||||||
|
|
||||||
// returns false if there is no path. otherwise fills out retPath
|
// returns false if there is no path. otherwise fills out retPath
|
||||||
bool findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet);
|
bool findPaths(int maxSearchSteps, int maxPay, STPathSet& retPathSet, bool bAllowEmpty);
|
||||||
};
|
};
|
||||||
// vim:ts=4
|
// vim:ts=4
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ TER PaymentTransactor::doApply()
|
|||||||
STAmount saDstAmountAct;
|
STAmount saDstAmountAct;
|
||||||
|
|
||||||
terResult = isSetBit(mParams, tapOPEN_LEDGER) && spsPaths.getPathCount() > RIPPLE_PATHS_MAX
|
terResult = isSetBit(mParams, tapOPEN_LEDGER) && spsPaths.getPathCount() > RIPPLE_PATHS_MAX
|
||||||
? telBAD_PATH_COUNT
|
? telBAD_PATH_COUNT // Too many paths for proposed ledger.
|
||||||
: RippleCalc::rippleCalc(
|
: RippleCalc::rippleCalc(
|
||||||
mEngine->getNodes(),
|
mEngine->getNodes(),
|
||||||
saMaxAmountAct,
|
saMaxAmountAct,
|
||||||
@@ -131,7 +131,8 @@ TER PaymentTransactor::doApply()
|
|||||||
spsPaths,
|
spsPaths,
|
||||||
bPartialPayment,
|
bPartialPayment,
|
||||||
bLimitQuality,
|
bLimitQuality,
|
||||||
bNoRippleDirect);
|
bNoRippleDirect, // Always compute for finalizing ledger.
|
||||||
|
false); // Not standalone, delete unfundeds.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -175,3 +176,5 @@ TER PaymentTransactor::doApply()
|
|||||||
|
|
||||||
return terResult;
|
return terResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// vim:ts=4
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "RippleLines.h"
|
#include "RippleLines.h"
|
||||||
#include "Wallet.h"
|
#include "Wallet.h"
|
||||||
#include "RippleAddress.h"
|
#include "RippleAddress.h"
|
||||||
|
#include "RippleCalc.h"
|
||||||
#include "AccountState.h"
|
#include "AccountState.h"
|
||||||
#include "NicknameState.h"
|
#include "NicknameState.h"
|
||||||
#include "InstanceCounter.h"
|
#include "InstanceCounter.h"
|
||||||
@@ -699,7 +700,7 @@ Json::Value RPCHandler::doRipplePathFind(const Json::Value& jvRequest)
|
|||||||
Json::Value jvResult(Json::objectValue);
|
Json::Value jvResult(Json::objectValue);
|
||||||
RippleAddress raSrc;
|
RippleAddress raSrc;
|
||||||
RippleAddress raDst;
|
RippleAddress raDst;
|
||||||
STAmount saDst;
|
STAmount saDstAmount;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
// Parse raSrc.
|
// Parse raSrc.
|
||||||
@@ -720,9 +721,9 @@ Json::Value RPCHandler::doRipplePathFind(const Json::Value& jvRequest)
|
|||||||
jvResult = rpcError(rpcINVALID_PARAMS);
|
jvResult = rpcError(rpcINVALID_PARAMS);
|
||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
// Parse saDst.
|
// Parse saDstAmount.
|
||||||
!jvRequest.isMember("destination_amount")
|
!jvRequest.isMember("destination_amount")
|
||||||
|| !saDst.bSetJson(jvRequest["destination_amount"]))
|
|| !saDstAmount.bSetJson(jvRequest["destination_amount"]))
|
||||||
{
|
{
|
||||||
cLog(lsINFO) << "Bad destination_amount.";
|
cLog(lsINFO) << "Bad destination_amount.";
|
||||||
jvResult = rpcError(rpcINVALID_PARAMS);
|
jvResult = rpcError(rpcINVALID_PARAMS);
|
||||||
@@ -739,9 +740,12 @@ Json::Value RPCHandler::doRipplePathFind(const Json::Value& jvRequest)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Json::Value jvSrcCurrencies = jvRequest.isMember("source_currencies");
|
Json::Value jvSrcCurrencies = jvRequest["source_currencies"];
|
||||||
Json::Value jvArray(Json::arrayValue);
|
Json::Value jvArray(Json::arrayValue);
|
||||||
|
|
||||||
|
Ledger::pointer lpCurrent = mNetOps->getCurrentLedger();
|
||||||
|
LedgerEntrySet lesSnapshot(lpCurrent);
|
||||||
|
|
||||||
for (unsigned int i=0; i != jvSrcCurrencies.size(); ++i) {
|
for (unsigned int i=0; i != jvSrcCurrencies.size(); ++i) {
|
||||||
Json::Value jvSource = jvSrcCurrencies[i];
|
Json::Value jvSource = jvSrcCurrencies[i];
|
||||||
uint160 srcCurrencyID;
|
uint160 srcCurrencyID;
|
||||||
@@ -760,16 +764,80 @@ Json::Value RPCHandler::doRipplePathFind(const Json::Value& jvRequest)
|
|||||||
STPathSet spsPaths;
|
STPathSet spsPaths;
|
||||||
|
|
||||||
// XXX Need to add support for srcIssuerID.
|
// XXX Need to add support for srcIssuerID.
|
||||||
Pathfinder pf(raSrc, raDst, srcCurrencyID, saDst);
|
Pathfinder pf(raSrc, raDst, srcCurrencyID, saDstAmount);
|
||||||
|
|
||||||
if (!spsPaths.isEmpty())
|
pf.findPaths(5, 1, spsPaths, true);
|
||||||
|
|
||||||
|
if (spsPaths.isEmpty())
|
||||||
|
{
|
||||||
|
cLog(lsDEBUG) << "ripple_path_find: No paths found.";
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// XXX Also need to check liquidity.
|
// XXX Also need to check liquidity.
|
||||||
jvSource.append(spsPaths.getJson(0));
|
STAmount saMaxAmountAct;
|
||||||
|
STAmount saDstAmountAct;
|
||||||
|
STAmount saMaxAmount(srcCurrencyID,
|
||||||
|
!!srcIssuerID
|
||||||
|
? srcIssuerID
|
||||||
|
: !!srcCurrencyID
|
||||||
|
? raSrc.getAccountID()
|
||||||
|
: ACCOUNT_XRP,
|
||||||
|
1);
|
||||||
|
saMaxAmount.negate();
|
||||||
|
|
||||||
|
TER terResult =
|
||||||
|
RippleCalc::rippleCalc(
|
||||||
|
lesSnapshot,
|
||||||
|
saMaxAmountAct,
|
||||||
|
saDstAmountAct,
|
||||||
|
saMaxAmount, // --> -1/xxx/yyy unlimited
|
||||||
|
saDstAmount, // --> Amount to deliver.
|
||||||
|
raDst.getAccountID(), // --> Account to deliver to.
|
||||||
|
raSrc.getAccountID(), // --> Account sending from.
|
||||||
|
spsPaths, // --> Path set.
|
||||||
|
false, // --> bPartialPayment - XXX might allow sometimes.
|
||||||
|
// Must achive delivery goal.
|
||||||
|
false, // --> bLimitQuality - XXX might allow sometimes.
|
||||||
|
// Average quality is wanted for normal payments.
|
||||||
|
// XXX TRUE till direct path representation resolved.
|
||||||
|
true, // --> bNoRippleDirect - XXX might allow sometimes.
|
||||||
|
// XXX No reason not to take the direct, unless set is merely direct.
|
||||||
|
true); //--> Stand alone mode, don't delete unfundeds.
|
||||||
|
|
||||||
|
cLog(lsDEBUG)
|
||||||
|
<< boost::str(boost::format("ripple_path_find: saMaxAmount=%s saDstAmount=%s saMaxAmountAct=%s saDstAmountAct=%s")
|
||||||
|
% saMaxAmount
|
||||||
|
% saDstAmount
|
||||||
|
% saMaxAmountAct
|
||||||
|
% saDstAmountAct);
|
||||||
|
|
||||||
|
if (tesSUCCESS == terResult)
|
||||||
|
{
|
||||||
|
Json::Value jvEntry(Json::objectValue);
|
||||||
|
|
||||||
|
jvEntry["source_amount"] = saMaxAmountAct.getJson(0);
|
||||||
|
jvEntry["paths"] = spsPaths.getJson(0);
|
||||||
|
|
||||||
|
jvArray.append(jvEntry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::string strToken;
|
||||||
|
std::string strHuman;
|
||||||
|
|
||||||
|
transResultInfo(terResult, strToken, strHuman);
|
||||||
|
|
||||||
|
cLog(lsDEBUG)
|
||||||
|
<< boost::str(boost::format("ripple_path_find: %s %s %s")
|
||||||
|
% strToken
|
||||||
|
% strHuman
|
||||||
|
% spsPaths.getJson(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jvResult["results"] = jvArray;
|
jvResult["alternatives"] = jvArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
return jvResult;
|
return jvResult;
|
||||||
@@ -872,7 +940,7 @@ Json::Value RPCHandler::handleJSONSubmit(const Json::Value& jvRequest)
|
|||||||
|
|
||||||
Pathfinder pf(srcAddress, dstAccountID, srcCurrencyID, dstAmount);
|
Pathfinder pf(srcAddress, dstAccountID, srcCurrencyID, dstAmount);
|
||||||
|
|
||||||
pf.findPaths(5, 1, spsPaths);
|
pf.findPaths(5, 1, spsPaths, false);
|
||||||
|
|
||||||
if (!spsPaths.isEmpty())
|
if (!spsPaths.isEmpty())
|
||||||
{
|
{
|
||||||
@@ -1067,7 +1135,7 @@ Json::Value RPCHandler::doTxHistory(const Json::Value& params)
|
|||||||
obj["index"]=startIndex;
|
obj["index"]=startIndex;
|
||||||
|
|
||||||
std::string sql =
|
std::string sql =
|
||||||
str(boost::format("SELECT * FROM Transactions ORDER BY LedgerSeq desc LIMIT %u,20")
|
boost::str(boost::format("SELECT * FROM Transactions ORDER BY LedgerSeq desc LIMIT %u,20")
|
||||||
% startIndex);
|
% startIndex);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2126,7 +2126,6 @@ void RippleCalc::pathNext(PathState::ref pspCur, const int iPaths, const LedgerE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX Stand alone calculation not implemented, does not calculate required input.
|
|
||||||
TER RippleCalc::rippleCalc(
|
TER RippleCalc::rippleCalc(
|
||||||
LedgerEntrySet& lesActive, // <-> --> = Fee applied to src balance.
|
LedgerEntrySet& lesActive, // <-> --> = Fee applied to src balance.
|
||||||
STAmount& saMaxAmountAct, // <-- The computed input amount.
|
STAmount& saMaxAmountAct, // <-- The computed input amount.
|
||||||
@@ -2138,7 +2137,8 @@ TER RippleCalc::rippleCalc(
|
|||||||
const STPathSet& spsPaths,
|
const STPathSet& spsPaths,
|
||||||
const bool bPartialPayment,
|
const bool bPartialPayment,
|
||||||
const bool bLimitQuality,
|
const bool bLimitQuality,
|
||||||
const bool bNoRippleDirect
|
const bool bNoRippleDirect,
|
||||||
|
const bool bStandAlone // True, not to delete unfundeds.
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
RippleCalc rc(lesActive);
|
RippleCalc rc(lesActive);
|
||||||
@@ -2240,8 +2240,9 @@ cLog(lsDEBUG) << boost::str(boost::format("rippleCalc: Build path: %d: add: %d s
|
|||||||
terResult = temUNCERTAIN;
|
terResult = temUNCERTAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
STAmount saInAct = STAmount(saMaxAmountReq.getCurrency(), saMaxAmountReq.getIssuer());
|
saMaxAmountAct = STAmount(saMaxAmountReq.getCurrency(), saMaxAmountReq.getIssuer());
|
||||||
STAmount saOutAct = STAmount(saDstAmountReq.getCurrency(), saDstAmountReq.getIssuer());
|
saDstAmountAct = STAmount(saDstAmountReq.getCurrency(), saDstAmountReq.getIssuer());
|
||||||
|
|
||||||
const LedgerEntrySet lesBase = lesActive; // Checkpoint with just fees paid.
|
const LedgerEntrySet lesBase = lesActive; // Checkpoint with just fees paid.
|
||||||
const uint64 uQualityLimit = bLimitQuality ? STAmount::getRate(saDstAmountReq, saMaxAmountReq) : 0;
|
const uint64 uQualityLimit = bLimitQuality ? STAmount::getRate(saDstAmountReq, saMaxAmountReq) : 0;
|
||||||
// When processing, don't want to complicate directory walking with deletion.
|
// When processing, don't want to complicate directory walking with deletion.
|
||||||
@@ -2259,8 +2260,8 @@ int iPass = 0;
|
|||||||
{
|
{
|
||||||
if (pspCur->uQuality)
|
if (pspCur->uQuality)
|
||||||
{
|
{
|
||||||
pspCur->saInAct = saInAct; // Update to current amount processed.
|
pspCur->saInAct = saMaxAmountAct; // Update to current amount processed.
|
||||||
pspCur->saOutAct = saOutAct;
|
pspCur->saOutAct = saDstAmountAct;
|
||||||
|
|
||||||
rc.pathNext(pspCur, vpsPaths.size(), lesCheckpoint, lesActive); // Compute increment.
|
rc.pathNext(pspCur, vpsPaths.size(), lesCheckpoint, lesActive); // Compute increment.
|
||||||
|
|
||||||
@@ -2314,8 +2315,8 @@ cLog(lsDEBUG) << boost::str(boost::format("rippleCalc: Summary: %d quality:%d be
|
|||||||
// Record best pass' LedgerEntrySet to build off of and potentially return.
|
// Record best pass' LedgerEntrySet to build off of and potentially return.
|
||||||
lesActive.swapWith(pspBest->lesEntries);
|
lesActive.swapWith(pspBest->lesEntries);
|
||||||
|
|
||||||
saInAct += pspBest->saInPass;
|
saMaxAmountAct += pspBest->saInPass;
|
||||||
saOutAct += pspBest->saOutPass;
|
saDstAmountAct += pspBest->saOutPass;
|
||||||
|
|
||||||
if (pspBest->bConsumed)
|
if (pspBest->bConsumed)
|
||||||
{
|
{
|
||||||
@@ -2323,13 +2324,13 @@ cLog(lsDEBUG) << boost::str(boost::format("rippleCalc: Summary: %d quality:%d be
|
|||||||
pspBest->uQuality = 0;
|
pspBest->uQuality = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (saOutAct == saDstAmountReq)
|
if (saDstAmountAct == saDstAmountReq)
|
||||||
{
|
{
|
||||||
// Done. Delivered requested amount.
|
// Done. Delivered requested amount.
|
||||||
|
|
||||||
terResult = tesSUCCESS;
|
terResult = tesSUCCESS;
|
||||||
}
|
}
|
||||||
else if (saInAct != saMaxAmountReq && iDry != vpsPaths.size())
|
else if (saMaxAmountAct != saMaxAmountReq && iDry != vpsPaths.size())
|
||||||
{
|
{
|
||||||
// Have not met requested amount or max send, try to do more. Prepare for next pass.
|
// Have not met requested amount or max send, try to do more. Prepare for next pass.
|
||||||
|
|
||||||
@@ -2359,7 +2360,7 @@ cLog(lsDEBUG) << boost::str(boost::format("rippleCalc: Summary: %d quality:%d be
|
|||||||
lesActive = lesBase; // Revert to just fees charged.
|
lesActive = lesBase; // Revert to just fees charged.
|
||||||
}
|
}
|
||||||
// Partial payment ok.
|
// Partial payment ok.
|
||||||
else if (!saOutAct)
|
else if (!saDstAmountAct)
|
||||||
{
|
{
|
||||||
// No payment at all.
|
// No payment at all.
|
||||||
terResult = tepPATH_DRY;
|
terResult = tepPATH_DRY;
|
||||||
@@ -2371,6 +2372,8 @@ cLog(lsDEBUG) << boost::str(boost::format("rippleCalc: Summary: %d quality:%d be
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!bStandAlone)
|
||||||
|
{
|
||||||
if (tesSUCCESS == terResult)
|
if (tesSUCCESS == terResult)
|
||||||
{
|
{
|
||||||
// Delete became unfunded offers.
|
// Delete became unfunded offers.
|
||||||
@@ -2387,6 +2390,7 @@ cLog(lsDEBUG) << boost::str(boost::format("rippleCalc: Summary: %d quality:%d be
|
|||||||
if (tesSUCCESS == terResult)
|
if (tesSUCCESS == terResult)
|
||||||
terResult = lesActive.offerDelete(uOfferIndex);
|
terResult = lesActive.offerDelete(uOfferIndex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return terResult;
|
return terResult;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ protected:
|
|||||||
|
|
||||||
// For offers:
|
// For offers:
|
||||||
|
|
||||||
STAmount saRateMax; // XXX Should rate be sticky for forward too?
|
STAmount saRateMax;
|
||||||
|
|
||||||
// Directory
|
// Directory
|
||||||
uint256 uDirectTip; // Current directory.
|
uint256 uDirectTip; // Current directory.
|
||||||
@@ -186,7 +186,8 @@ public:
|
|||||||
const STPathSet& spsPaths,
|
const STPathSet& spsPaths,
|
||||||
const bool bPartialPayment,
|
const bool bPartialPayment,
|
||||||
const bool bLimitQuality,
|
const bool bLimitQuality,
|
||||||
const bool bNoRippleDirect
|
const bool bNoRippleDirect,
|
||||||
|
const bool bStandAlone
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user