mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-21 11:35:53 +00:00
Add a default for currencies for ripple_find_path.
This commit is contained in:
@@ -317,7 +317,7 @@ bool Pathfinder::findPaths(const unsigned int iMaxSteps, const unsigned int iMax
|
|||||||
% RippleAddress::createHumanAccountID(rspEntry->getAccountIDPeer().getAccountID())
|
% RippleAddress::createHumanAccountID(rspEntry->getAccountIDPeer().getAccountID())
|
||||||
% STAmount::createHumanCurrency(speEnd.mCurrencyID));
|
% STAmount::createHumanCurrency(speEnd.mCurrencyID));
|
||||||
}
|
}
|
||||||
else if (!rspEntry->getBalance().isPositive() // Have IOUs to send.
|
else if (!rspEntry->getBalance().isPositive() // No IOUs to send.
|
||||||
&& (!rspEntry->getLimitPeer() // Peer does not extend credit.
|
&& (!rspEntry->getLimitPeer() // Peer does not extend credit.
|
||||||
|| *rspEntry->getBalance().negate() >= rspEntry->getLimitPeer())) // No credit left.
|
|| *rspEntry->getBalance().negate() >= rspEntry->getLimitPeer())) // No credit left.
|
||||||
{
|
{
|
||||||
@@ -565,4 +565,28 @@ void Pathfinder::addPathOption(PathOption::pointer pathOption)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
boost::unordered_set<uint160> usAccountSourceCurrencies(const RippleAddress& raAccountID, Ledger::ref lrLedger)
|
||||||
|
{
|
||||||
|
boost::unordered_set<uint160> usCurrencies;
|
||||||
|
|
||||||
|
// List of ripple lines.
|
||||||
|
AccountItems rippleLines(raAccountID.getAccountID(), lrLedger, AccountItem::pointer(new RippleState()));
|
||||||
|
|
||||||
|
BOOST_FOREACH(AccountItem::ref item, rippleLines.getItems())
|
||||||
|
{
|
||||||
|
RippleState* rspEntry = (RippleState*) item.get();
|
||||||
|
STAmount saBalance = rspEntry->getBalance();
|
||||||
|
|
||||||
|
// Filter out non
|
||||||
|
if (saBalance.isPositive() // Have IOUs to send.
|
||||||
|
|| (rspEntry->getLimitPeer() // Peer extends credit.
|
||||||
|
&& *saBalance.negate() < rspEntry->getLimitPeer())) // Credit left.
|
||||||
|
{
|
||||||
|
// Path has no credit left. Ignore it.
|
||||||
|
usCurrencies.insert(saBalance.getCurrency());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return usCurrencies;
|
||||||
|
}
|
||||||
// vim:ts=4
|
// vim:ts=4
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ public:
|
|||||||
|
|
||||||
bool bDefaultPath(const STPath& spPath);
|
bool bDefaultPath(const STPath& spPath);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
boost::unordered_set<uint160> usAccountSourceCurrencies(const RippleAddress& raAccountID, Ledger::ref lrLedger);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// vim:ts=4
|
// vim:ts=4
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ Json::Value rpcError(int iError, Json::Value jvResult)
|
|||||||
{ rpcSRC_ACT_MISSING, "srcActMissing", "Source account not provided." },
|
{ rpcSRC_ACT_MISSING, "srcActMissing", "Source account not provided." },
|
||||||
{ rpcSRC_ACT_NOT_FOUND, "srcActNotFound", "Source amount not found." },
|
{ rpcSRC_ACT_NOT_FOUND, "srcActNotFound", "Source amount not found." },
|
||||||
{ rpcSRC_AMT_MALFORMED, "srcAmtMalformed", "Source amount/currency/issuer is malformed." },
|
{ rpcSRC_AMT_MALFORMED, "srcAmtMalformed", "Source amount/currency/issuer is malformed." },
|
||||||
|
{ rpcSRC_CUR_MALFORMED, "srcCurMalformed", "Source currency is malformed." },
|
||||||
|
{ rpcSRC_ISR_MALFORMED, "srcIsrMalformed", "Source issuer is malformed." },
|
||||||
{ rpcSRC_UNCLAIMED, "srcUnclaimed", "Source account is not claimed." },
|
{ rpcSRC_UNCLAIMED, "srcUnclaimed", "Source account is not claimed." },
|
||||||
{ rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found." },
|
{ rpcTXN_NOT_FOUND, "txnNotFound", "Transaction not found." },
|
||||||
{ rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown command." },
|
{ rpcUNKNOWN_COMMAND, "unknownCmd", "Unknown command." },
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ enum {
|
|||||||
rpcSRC_ACT_MISSING,
|
rpcSRC_ACT_MISSING,
|
||||||
rpcSRC_ACT_NOT_FOUND,
|
rpcSRC_ACT_NOT_FOUND,
|
||||||
rpcSRC_AMT_MALFORMED,
|
rpcSRC_AMT_MALFORMED,
|
||||||
|
rpcSRC_CUR_MALFORMED,
|
||||||
|
rpcSRC_ISR_MALFORMED,
|
||||||
|
|
||||||
// Internal error (should never happen)
|
// Internal error (should never happen)
|
||||||
rpcINTERNAL, // Generic internal error.
|
rpcINTERNAL, // Generic internal error.
|
||||||
|
|||||||
@@ -754,9 +754,9 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest)
|
|||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
// Checks on source_currencies.
|
// Checks on source_currencies.
|
||||||
!jvRequest.isMember("source_currencies")
|
jvRequest.isMember("source_currencies")
|
||||||
|| !jvRequest["source_currencies"].isArray()
|
&& (!jvRequest["source_currencies"].isArray()
|
||||||
|| !jvRequest["source_currencies"].size()
|
|| !jvRequest["source_currencies"].size()) // Don't allow empty currencies.
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
cLog(lsINFO) << "Bad source_currencies.";
|
cLog(lsINFO) << "Bad source_currencies.";
|
||||||
@@ -764,36 +764,63 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Json::Value jvSrcCurrencies = jvRequest["source_currencies"];
|
|
||||||
Json::Value jvArray(Json::arrayValue);
|
|
||||||
|
|
||||||
Ledger::pointer lpCurrent = mNetOps->getCurrentLedger();
|
Ledger::pointer lpCurrent = mNetOps->getCurrentLedger();
|
||||||
|
Json::Value jvSrcCurrencies;
|
||||||
|
|
||||||
|
if (jvRequest.isMember("source_currencies"))
|
||||||
|
{
|
||||||
|
jvSrcCurrencies = jvRequest["source_currencies"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost::unordered_set<uint160> usCurrencies = usAccountSourceCurrencies(raSrc, lpCurrent);
|
||||||
|
|
||||||
|
// Add XRP as a source currency.
|
||||||
|
// YYY Only bother if they are above reserve.
|
||||||
|
usCurrencies.insert(uint160(CURRENCY_XRP));
|
||||||
|
|
||||||
|
jvSrcCurrencies = Json::Value(Json::arrayValue);
|
||||||
|
|
||||||
|
BOOST_FOREACH(const uint160& uCurrency, usCurrencies)
|
||||||
|
{
|
||||||
|
Json::Value jvCurrency(Json::objectValue);
|
||||||
|
|
||||||
|
jvCurrency["currency"] = STAmount::createHumanCurrency(uCurrency);
|
||||||
|
|
||||||
|
jvSrcCurrencies.append(jvCurrency);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LedgerEntrySet lesSnapshot(lpCurrent);
|
||||||
|
|
||||||
ScopedUnlock su(theApp->getMasterLock()); // As long as we have a locked copy of the ledger, we can unlock.
|
ScopedUnlock su(theApp->getMasterLock()); // As long as we have a locked copy of the ledger, we can unlock.
|
||||||
|
|
||||||
LedgerEntrySet lesSnapshot(lpCurrent);
|
Json::Value jvArray(Json::arrayValue);
|
||||||
|
|
||||||
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 uSrcCurrencyID;
|
uint160 uSrcCurrencyID;
|
||||||
uint160 uSrcIssuerID = raSrc.getAccountID();
|
uint160 uSrcIssuerID = raSrc.getAccountID();
|
||||||
|
|
||||||
if (
|
// Parse mandatory currency.
|
||||||
// Parse currency.
|
if (!jvSource.isMember("currency")
|
||||||
!jvSource.isMember("currency")
|
|| !STAmount::currencyFromString(uSrcCurrencyID, jvSource["currency"].asString()))
|
||||||
|| !STAmount::currencyFromString(uSrcCurrencyID, jvSource["currency"].asString())
|
{
|
||||||
|
cLog(lsINFO) << "Bad currency.";
|
||||||
|
|
||||||
// Parse issuer.
|
return rpcError(rpcSRC_CUR_MALFORMED);
|
||||||
|| ((jvSource.isMember("issuer"))
|
}
|
||||||
|
// Parse optional issuer.
|
||||||
|
else if (((jvSource.isMember("issuer"))
|
||||||
&& (!jvSource["issuer"].isString()
|
&& (!jvSource["issuer"].isString()
|
||||||
|| !STAmount::issuerFromString(uSrcIssuerID, jvSource["issuer"].asString())))
|
|| !STAmount::issuerFromString(uSrcIssuerID, jvSource["issuer"].asString())))
|
||||||
|
|
||||||
// Don't allow illegal issuers.
|
// Don't allow illegal issuers.
|
||||||
|| !uSrcIssuerID
|
|| !uSrcIssuerID
|
||||||
|| ACCOUNT_ONE == uSrcIssuerID)
|
|| ACCOUNT_ONE == uSrcIssuerID)
|
||||||
{
|
{
|
||||||
cLog(lsINFO) << "Bad currency/issuer.";
|
cLog(lsINFO) << "Bad issuer.";
|
||||||
return rpcError(rpcINVALID_PARAMS);
|
|
||||||
|
return rpcError(rpcSRC_ISR_MALFORMED);
|
||||||
}
|
}
|
||||||
|
|
||||||
STPathSet spsComputed;
|
STPathSet spsComputed;
|
||||||
@@ -2495,7 +2522,9 @@ Json::Value RPCHandler::doCommand(Json::Value& jvRequest, int iRole)
|
|||||||
{
|
{
|
||||||
return rpcError(rpcNO_PERMISSION);
|
return rpcError(rpcNO_PERMISSION);
|
||||||
}
|
}
|
||||||
else if (commandsA[i].iOptions & optNetwork
|
|
||||||
|
// XXX Need the master lock for getOperatingMode
|
||||||
|
if (commandsA[i].iOptions & optNetwork
|
||||||
&& mNetOps->getOperatingMode() != NetworkOPs::omTRACKING
|
&& mNetOps->getOperatingMode() != NetworkOPs::omTRACKING
|
||||||
&& mNetOps->getOperatingMode() != NetworkOPs::omFULL)
|
&& mNetOps->getOperatingMode() != NetworkOPs::omFULL)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ private:
|
|||||||
bool mViewLowest;
|
bool mViewLowest;
|
||||||
|
|
||||||
RippleState(SerializedLedgerEntry::ref ledgerEntry); // For accounts in a ledger
|
RippleState(SerializedLedgerEntry::ref ledgerEntry); // For accounts in a ledger
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RippleState(){ }
|
RippleState(){ }
|
||||||
AccountItem::pointer makeItem(const uint160& accountID, SerializedLedgerEntry::ref ledgerEntry);
|
AccountItem::pointer makeItem(const uint160& accountID, SerializedLedgerEntry::ref ledgerEntry);
|
||||||
|
|||||||
Reference in New Issue
Block a user