Pathfinding cleanup

This commit is contained in:
Miguel Portilla
2016-03-03 17:24:42 -05:00
committed by seelabs
parent 122a5cdf89
commit 48d28826d0
5 changed files with 115 additions and 119 deletions

View File

@@ -343,9 +343,9 @@ int PathRequest::parseJson (Json::Value const& jvParams)
if (jvParams.isMember (jss::source_currencies)) if (jvParams.isMember (jss::source_currencies))
{ {
Json::Value const& jvSrcCur = jvParams[jss::source_currencies]; Json::Value const& jvSrcCurrencies = jvParams[jss::source_currencies];
if (! jvSrcCurrencies.isArray() || jvSrcCurrencies.size() == 0 ||
if (! jvSrcCur.isArray() || jvSrcCur.size() > RPC::Tuning::max_src_cur) jvSrcCurrencies.size() > RPC::Tuning::max_src_cur)
{ {
jvStatus = rpcError (rpcSRC_CUR_MALFORMED); jvStatus = rpcError (rpcSRC_CUR_MALFORMED);
return PFR_PJ_INVALID; return PFR_PJ_INVALID;
@@ -353,44 +353,51 @@ int PathRequest::parseJson (Json::Value const& jvParams)
sciSourceCurrencies.clear (); sciSourceCurrencies.clear ();
for (unsigned i = 0; i < jvSrcCur.size (); ++i) for (auto const& c : jvSrcCurrencies)
{ {
Json::Value const& jvCur = jvSrcCur[i]; // Mandatory currency
Currency uCur; Currency srcCurrencyID;
if (! jvCur.isObject() || if (! c.isObject() ||
! jvCur.isMember (jss::currency) || ! c.isMember(jss::currency) ||
! to_currency (uCur, jvCur[jss::currency].asString ())) ! to_currency(srcCurrencyID, c[jss::currency].asString()))
{ {
jvStatus = rpcError (rpcSRC_CUR_MALFORMED); jvStatus = rpcError (rpcSRC_CUR_MALFORMED);
return PFR_PJ_INVALID; return PFR_PJ_INVALID;
} }
AccountID uIss; // Optional issuer
if (jvCur.isMember (jss::issuer) && AccountID srcIssuerID;
!to_issuer (uIss, jvCur[jss::issuer].asString ())) if (c.isMember (jss::issuer) &&
(! c[jss::issuer].isString() ||
! to_issuer(srcIssuerID, c[jss::issuer].asString())))
{ {
jvStatus = rpcError (rpcSRC_ISR_MALFORMED); jvStatus = rpcError (rpcSRC_ISR_MALFORMED);
}
if (uCur.isZero () && uIss.isNonZero ())
{
jvStatus = rpcError (rpcSRC_CUR_MALFORMED);
return PFR_PJ_INVALID; return PFR_PJ_INVALID;
} }
if (uCur.isNonZero() && uIss.isZero()) if (srcCurrencyID.isZero())
uIss = *raSrcAccount; {
if (srcIssuerID.isNonZero())
{
jvStatus = rpcError(rpcSRC_CUR_MALFORMED);
return PFR_PJ_INVALID;
}
}
else if (srcIssuerID.isZero())
{
srcIssuerID = *raSrcAccount;
}
if (saSendMax) if (saSendMax)
{ {
// If the currencies don't match, ignore the source currency. // If the currencies don't match, ignore the source currency.
if (uCur == saSendMax->getCurrency()) if (srcCurrencyID == saSendMax->getCurrency())
{ {
// If neither is the source and they are not equal, then the // If neither is the source and they are not equal, then the
// source issuer is illegal. // source issuer is illegal.
if (uIss != *raSrcAccount && if (srcIssuerID != *raSrcAccount &&
saSendMax->getIssuer() != *raSrcAccount && saSendMax->getIssuer() != *raSrcAccount &&
uIss != saSendMax->getIssuer()) srcIssuerID != saSendMax->getIssuer())
{ {
jvStatus = rpcError (rpcSRC_ISR_MALFORMED); jvStatus = rpcError (rpcSRC_ISR_MALFORMED);
return PFR_PJ_INVALID; return PFR_PJ_INVALID;
@@ -398,17 +405,26 @@ int PathRequest::parseJson (Json::Value const& jvParams)
// If both are the source, use the source. // If both are the source, use the source.
// Otherwise, use the one that's not the source. // Otherwise, use the one that's not the source.
if (uIss != *raSrcAccount) if (srcIssuerID != *raSrcAccount)
sciSourceCurrencies.insert({uCur, uIss}); {
sciSourceCurrencies.insert(
{srcCurrencyID, srcIssuerID});
}
else if (saSendMax->getIssuer() != *raSrcAccount) else if (saSendMax->getIssuer() != *raSrcAccount)
sciSourceCurrencies.insert({uCur, saSendMax->getIssuer()}); {
sciSourceCurrencies.insert(
{srcCurrencyID, saSendMax->getIssuer()});
}
else else
sciSourceCurrencies.insert({uCur, *raSrcAccount}); {
sciSourceCurrencies.insert(
{srcCurrencyID, *raSrcAccount});
}
} }
} }
else else
{ {
sciSourceCurrencies.insert({uCur, uIss}); sciSourceCurrencies.insert({srcCurrencyID, srcIssuerID});
} }
} }
} }
@@ -454,15 +470,15 @@ PathRequest::getPathFinder(std::shared_ptr<RippleLineCache> const& cache,
} }
bool bool
PathRequest::findPaths (std::shared_ptr<RippleLineCache> const& cache, int const level, PathRequest::findPaths (std::shared_ptr<RippleLineCache> const& cache,
Json::Value& jvArray) int const level, Json::Value& jvArray)
{ {
auto sourceCurrencies = sciSourceCurrencies; auto sourceCurrencies = sciSourceCurrencies;
if (sourceCurrencies.empty ()) if (sourceCurrencies.empty ())
{ {
auto usCurrencies = accountSourceCurrencies(*raSrcAccount, cache, true); auto currencies = accountSourceCurrencies(*raSrcAccount, cache, true);
bool const sameAccount = *raSrcAccount == *raDstAccount; bool const sameAccount = *raSrcAccount == *raDstAccount;
for (auto const& c : usCurrencies) for (auto const& c : currencies)
{ {
if (! sameAccount || c != saDstAmount.getCurrency()) if (! sameAccount || c != saDstAmount.getCurrency())
{ {
@@ -590,7 +606,8 @@ PathRequest::findPaths (std::shared_ptr<RippleLineCache> const& cache, int const
return true; return true;
} }
Json::Value PathRequest::doUpdate (std::shared_ptr<RippleLineCache> const& cache, bool fast) Json::Value PathRequest::doUpdate(
std::shared_ptr<RippleLineCache> const& cache, bool fast)
{ {
using namespace std::chrono; using namespace std::chrono;
m_journal.debug << iIdentifier << " update " << (fast ? "fast" : "normal"); m_journal.debug << iIdentifier << " update " << (fast ? "fast" : "normal");

View File

@@ -17,7 +17,7 @@ performed, or simply disconnecting the endpoint.
Currently, consumption endpoints include websocket connections used to Currently, consumption endpoints include websocket connections used to
service clients, and peer connections used to create the peer to peer service clients, and peer connections used to create the peer to peer
overlay network implementing the Ripple protcool. overlay network implementing the Ripple protocol.
The current "balance" of a Consumer represents resource consumption The current "balance" of a Consumer represents resource consumption
debt or credit. Debt is accrued when bad loads are imposed. Credit is debt or credit. Debt is accrued when bad loads are imposed. Credit is

View File

@@ -49,24 +49,6 @@ namespace ripple {
static unsigned int const max_paths = 4; static unsigned int const max_paths = 4;
static
Json::Value
buildSrcCurrencies(AccountID const& account,
std::shared_ptr<RippleLineCache> const& cache)
{
auto currencies = accountSourceCurrencies(account, cache, true);
auto jvSrcCurrencies = Json::Value(Json::arrayValue);
for (auto const& uCurrency : currencies)
{
Json::Value jvCurrency(Json::objectValue);
jvCurrency[jss::currency] = to_string(uCurrency);
jvSrcCurrencies.append(jvCurrency);
}
return jvSrcCurrencies;
}
// This interface is deprecated. // This interface is deprecated.
Json::Value doRipplePathFind (RPC::Context& context) Json::Value doRipplePathFind (RPC::Context& context)
{ {
@@ -75,24 +57,13 @@ Json::Value doRipplePathFind (RPC::Context& context)
context.loadType = Resource::feeHighBurdenRPC; context.loadType = Resource::feeHighBurdenRPC;
AccountID raSrc;
AccountID raDst;
STAmount saDstAmount;
std::shared_ptr <ReadView const> lpLedger; std::shared_ptr <ReadView const> lpLedger;
Json::Value jvResult; Json::Value jvResult;
if (context.app.config().RUN_STANDALONE || if (! context.app.config().RUN_STANDALONE &&
context.params.isMember(jss::ledger) || ! context.params.isMember(jss::ledger) &&
context.params.isMember(jss::ledger_index) || ! context.params.isMember(jss::ledger_index) &&
context.params.isMember(jss::ledger_hash)) ! context.params.isMember(jss::ledger_hash))
{
// The caller specified a ledger
jvResult = RPC::lookupLedger (lpLedger, context);
if (!lpLedger)
return jvResult;
}
else
{ {
if (context.app.getLedgerMaster().getValidatedLedgerAge() > if (context.app.getLedgerMaster().getValidatedLedgerAge() >
RPC::Tuning::maxValidatedLedgerAge) RPC::Tuning::maxValidatedLedgerAge)
@@ -115,10 +86,18 @@ Json::Value doRipplePathFind (RPC::Context& context)
return jvResult; return jvResult;
} }
// The caller specified a ledger
jvResult = RPC::lookupLedger (lpLedger, context);
if (! lpLedger)
return jvResult;
RPC::LegacyPathFind lpf (isUnlimited (context.role), context.app); RPC::LegacyPathFind lpf (isUnlimited (context.role), context.app);
if (! lpf.isOk ()) if (! lpf.isOk ())
return rpcError (rpcTOO_BUSY); return rpcError (rpcTOO_BUSY);
AccountID raSrc;
AccountID raDst;
STAmount saDstAmount;
if (! context.params.isMember (jss::source_account)) if (! context.params.isMember (jss::source_account))
{ {
jvResult = rpcError (rpcSRC_ACT_MISSING); jvResult = rpcError (rpcSRC_ACT_MISSING);
@@ -152,14 +131,14 @@ Json::Value doRipplePathFind (RPC::Context& context)
} }
else if ( else if (
// Checks on source_currencies. // Checks on source_currencies.
context.params.isMember (jss::source_currencies) context.params.isMember(jss::source_currencies) &&
&& (!context.params[jss::source_currencies].isArray () (! context.params[jss::source_currencies].isArray() ||
|| !context.params[jss::source_currencies].size ()) context.params[jss::source_currencies].size() == 0 ||
// Don't allow empty currencies. context.params[jss::source_currencies].size() >
) RPC::Tuning::max_src_cur))
{ {
JLOG (context.j.info) << "Bad source_currencies."; JLOG (context.j.info) << "Bad source_currencies.";
jvResult = rpcError (rpcINVALID_PARAMS); jvResult = rpcError(rpcINVALID_PARAMS);
} }
else else
{ {
@@ -182,15 +161,19 @@ Json::Value doRipplePathFind (RPC::Context& context)
if (context.params.isMember (jss::source_currencies)) if (context.params.isMember (jss::source_currencies))
{ {
jvSrcCurrencies = context.params[jss::source_currencies]; jvSrcCurrencies = context.params[jss::source_currencies];
if (! jvSrcCurrencies.isArray() ||
jvSrcCurrencies.size() > RPC::Tuning::max_src_cur)
return rpcError(rpcSRC_CUR_MALFORMED);
} }
else else
{ {
jvSrcCurrencies = buildSrcCurrencies(raSrc, cache); auto currencies = accountSourceCurrencies(raSrc, cache, true);
if (jvSrcCurrencies.size() > RPC::Tuning::max_auto_src_cur) if (currencies.size() > RPC::Tuning::max_auto_src_cur)
return rpcError(rpcINTERNAL); return rpcError(rpcINTERNAL);
auto jvSrcCurrencies = Json::Value(Json::arrayValue);
for (auto const& c : currencies)
{
Json::Value jvCurrency(Json::objectValue);
jvCurrency[jss::currency] = to_string(c);
jvSrcCurrencies.append(jvCurrency);
}
} }
// Fill in currencies destination will accept // Fill in currencies destination will accept
@@ -296,57 +279,53 @@ ripplePathFind (std::shared_ptr<RippleLineCache> const& cache,
auto j = app.journal ("RPCHandler"); auto j = app.journal ("RPCHandler");
for (unsigned int i = 0; i != jvSrcCurrencies.size(); ++i) for (auto const& c : jvSrcCurrencies)
{ {
Json::Value jvSource = jvSrcCurrencies[i]; if (! c.isObject())
Currency uSrcCurrencyID;
AccountID uSrcIssuerID;
if (!jvSource.isObject())
return std::make_pair(false, rpcError(rpcINVALID_PARAMS)); return std::make_pair(false, rpcError(rpcINVALID_PARAMS));
// Parse mandatory currency. // Mandatory currency
if (!jvSource.isMember(jss::currency) Currency srcCurrencyID;
|| !to_currency( if (! c.isMember(jss::currency) ||
uSrcCurrencyID, jvSource[jss::currency].asString())) ! to_currency(srcCurrencyID, c[jss::currency].asString()))
{ {
JLOG (j.info) << "Bad currency."; JLOG (j.info) << "Bad currency.";
return std::make_pair(false, rpcError(rpcSRC_CUR_MALFORMED)); return std::make_pair(false, rpcError(rpcSRC_CUR_MALFORMED));
} }
if (uSrcCurrencyID.isNonZero()) // Optional issuer
uSrcIssuerID = raSrc; AccountID srcIssuerID;
if (c.isMember (jss::issuer) &&
// Parse optional issuer. (! c[jss::issuer].isString() ||
if (jvSource.isMember(jss::issuer) && ! to_issuer(srcIssuerID, c[jss::issuer].asString()) ||
((!jvSource[jss::issuer].isString() || srcIssuerID.isZero() != srcCurrencyID.isZero() ||
!to_issuer(uSrcIssuerID, jvSource[jss::issuer].asString())) || noAccount() == srcIssuerID))
(uSrcIssuerID.isZero() != uSrcCurrencyID.isZero()) ||
(noAccount() == uSrcIssuerID)))
{ {
JLOG (j.info) << "Bad issuer."; JLOG (j.info) << "Bad issuer.";
return std::make_pair(false, rpcError(rpcSRC_ISR_MALFORMED)); return std::make_pair(false, rpcError(rpcSRC_ISR_MALFORMED));
} }
auto issue = Issue(uSrcCurrencyID, uSrcIssuerID); if (srcIssuerID.isZero())
srcIssuerID = raSrc;
auto issue = Issue(srcCurrencyID, srcIssuerID);
if (saSendMax) if (saSendMax)
{ {
// If the currencies don't match, ignore the source currency. // If the currencies don't match, ignore the source currency.
if (uSrcCurrencyID != saSendMax->getCurrency()) if (srcCurrencyID != saSendMax->getCurrency())
continue; continue;
// If neither is the source and they are not equal, then the // If neither is the source and they are not equal, then the
// source issuer is illegal. // source issuer is illegal.
if (uSrcIssuerID != raSrc && saSendMax->getIssuer() != raSrc && if (srcIssuerID != raSrc && saSendMax->getIssuer() != raSrc &&
uSrcIssuerID != saSendMax->getIssuer()) srcIssuerID != saSendMax->getIssuer())
{ {
return std::make_pair(false, rpcError(rpcSRC_ISR_MALFORMED)); return std::make_pair(false, rpcError(rpcSRC_ISR_MALFORMED));
} }
// If both are the source, use the source. // If both are the source, use the source.
// Otherwise, use the one that's not the source. // Otherwise, use the one that's not the source.
if (uSrcIssuerID == raSrc) if (srcIssuerID == raSrc)
{ {
issue.account = saSendMax->getIssuer() != raSrc ? issue.account = saSendMax->getIssuer() != raSrc ?
saSendMax->getIssuer() : raSrc; saSendMax->getIssuer() : raSrc;
@@ -379,13 +358,13 @@ ripplePathFind (std::shared_ptr<RippleLineCache> const& cache,
auto ps = pathfinder->getBestPaths(max_paths, auto ps = pathfinder->getBestPaths(max_paths,
fullLiquidityPath, spsComputed, issue.account); fullLiquidityPath, spsComputed, issue.account);
auto& issuer = auto& issuer =
isXRP(uSrcIssuerID) ? isXRP(srcIssuerID) ?
isXRP(uSrcCurrencyID) ? // Default to source account. isXRP(srcCurrencyID) ? // Default to source account.
xrpAccount() : xrpAccount() :
(raSrc) (raSrc)
: uSrcIssuerID; // Use specifed issuer. : srcIssuerID; // Use specifed issuer.
STAmount saMaxAmount = saSendMax.value_or( STAmount saMaxAmount = saSendMax.value_or(
STAmount({uSrcCurrencyID, issuer}, 1u, 0, true)); STAmount({ srcCurrencyID, issuer}, 1u, 0, true));
boost::optional<PaymentSandbox> sandbox; boost::optional<PaymentSandbox> sandbox;
sandbox.emplace(&*cache->getLedger(), tapNONE); sandbox.emplace(&*cache->getLedger(), tapNONE);

View File

@@ -296,17 +296,19 @@ ServerHandlerImp::processRequest (Port const& port,
} }
Resource::Consumer usage; Resource::Consumer usage;
if (isUnlimited(role))
if (isUnlimited (role))
usage = m_resourceManager.newUnlimitedEndpoint (
remoteIPAddress.to_string());
else
usage = m_resourceManager.newInboundEndpoint(remoteIPAddress);
if (usage.disconnect ())
{ {
HTTPReply (503, "Server is overloaded", output, rpcJ); usage = m_resourceManager.newUnlimitedEndpoint(
return; remoteIPAddress.to_string());
}
else
{
usage = m_resourceManager.newInboundEndpoint(remoteIPAddress);
if (usage.disconnect())
{
HTTPReply(503, "Server is overloaded", output, rpcJ);
return;
}
} }
std::string strMethod = method.asString (); std::string strMethod = method.asString ();
@@ -353,8 +355,6 @@ ServerHandlerImp::processRequest (Port const& port,
return; return;
} }
Resource::Charge loadType = Resource::feeReferenceRPC;
JLOG(m_journal.debug) << "Query: " << strMethod << params; JLOG(m_journal.debug) << "Query: " << strMethod << params;
// Provide the JSON-RPC method as the field "command" in the request. // Provide the JSON-RPC method as the field "command" in the request.
@@ -362,6 +362,7 @@ ServerHandlerImp::processRequest (Port const& port,
JLOG (m_journal.trace) JLOG (m_journal.trace)
<< "doRpcCommand:" << strMethod << ":" << params; << "doRpcCommand:" << strMethod << ":" << params;
Resource::Charge loadType = Resource::feeReferenceRPC;
auto const start (std::chrono::high_resolution_clock::now ()); auto const start (std::chrono::high_resolution_clock::now ());
RPC::Context context {m_journal, params, app_, loadType, m_networkOPs, RPC::Context context {m_journal, params, app_, loadType, m_networkOPs,

View File

@@ -106,7 +106,6 @@ private:
Application& app_; Application& app_;
Port const& m_port; Port const& m_port;
Resource::Manager& m_resourceManager; Resource::Manager& m_resourceManager;
Resource::Consumer m_usage;
beast::IP::Endpoint const m_remoteAddress; beast::IP::Endpoint const m_remoteAddress;
std::string const m_forwardedFor; std::string const m_forwardedFor;
std::string const m_user; std::string const m_user;