Charge pathfinding consumers per source currency (RIPD-1019):

The IP address used to perform pathfinding operations is now charged an
additional resource increment for each source currency in the path set.

* NOTE: This charge is a local resource charge, not a transaction fee
  charge.
This commit is contained in:
Miguel Portilla
2016-03-08 13:44:39 -05:00
committed by seelabs
parent 48d28826d0
commit b3f5986c83
11 changed files with 58 additions and 24 deletions

View File

@@ -95,8 +95,9 @@ void startServer (Application& app)
std::cerr << "Startup RPC: " << jvCommand << std::endl; std::cerr << "Startup RPC: " << jvCommand << std::endl;
Resource::Charge loadType = Resource::feeReferenceRPC; Resource::Charge loadType = Resource::feeReferenceRPC;
Resource::Consumer c;
RPC::Context context {app.journal ("RPCHandler"), jvCommand, app, RPC::Context context {app.journal ("RPCHandler"), jvCommand, app,
loadType, app.getOPs (), app.getLedgerMaster(), Role::ADMIN}; loadType, app.getOPs (), app.getLedgerMaster(), c, Role::ADMIN};
Json::Value jvResult; Json::Value jvResult;
RPC::doCommand (context, jvResult); RPC::doCommand (context, jvResult);

View File

@@ -32,6 +32,7 @@
#include <ripple/protocol/UintTypes.h> #include <ripple/protocol/UintTypes.h>
#include <ripple/rpc/impl/Tuning.h> #include <ripple/rpc/impl/Tuning.h>
#include <beast/module/core/text/LexicalCast.h> #include <beast/module/core/text/LexicalCast.h>
#include <boost/algorithm/clamp.hpp>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <tuple> #include <tuple>
@@ -47,6 +48,7 @@ PathRequest::PathRequest (
, m_journal (journal) , m_journal (journal)
, mOwner (owner) , mOwner (owner)
, wpSubscriber (subscriber) , wpSubscriber (subscriber)
, consumer_(subscriber->getConsumer())
, jvStatus (Json::objectValue) , jvStatus (Json::objectValue)
, mLastIndex (0) , mLastIndex (0)
, mInProgress (false) , mInProgress (false)
@@ -62,6 +64,7 @@ PathRequest::PathRequest (
PathRequest::PathRequest ( PathRequest::PathRequest (
Application& app, Application& app,
std::function <void(void)> const& completion, std::function <void(void)> const& completion,
Resource::Consumer& consumer,
int id, int id,
PathRequests& owner, PathRequests& owner,
beast::Journal journal) beast::Journal journal)
@@ -69,6 +72,7 @@ PathRequest::PathRequest (
, m_journal (journal) , m_journal (journal)
, mOwner (owner) , mOwner (owner)
, fCompletion (completion) , fCompletion (completion)
, consumer_ (consumer)
, jvStatus (Json::objectValue) , jvStatus (Json::objectValue)
, mLastIndex (0) , mLastIndex (0)
, mInProgress (false) , mInProgress (false)
@@ -603,6 +607,13 @@ PathRequest::findPaths (std::shared_ptr<RippleLineCache> const& cache,
} }
} }
/* The resource fee is based on the number of source currencies used.
The minimum cost is 50 and the maximum is 400. The cost increases
after four source currencies, 50 - (4 * 4) = 34.
*/
int const size = sourceCurrencies.size();
consumer_.charge({boost::algorithm::clamp(size * size + 34, 50, 400),
"path update"});
return true; return true;
} }

View File

@@ -69,16 +69,16 @@ public:
PathRequest ( PathRequest (
Application& app, Application& app,
std::function <void (void)> const& completion, std::function <void (void)> const& completion,
Resource::Consumer& consumer,
int id, int id,
PathRequests&, PathRequests&,
beast::Journal journal); beast::Journal journal);
~PathRequest (); ~PathRequest ();
bool isNew (); bool isNew ();
bool needsUpdate (bool newOnly, LedgerIndex index); bool needsUpdate (bool newOnly, LedgerIndex index);
void updateComplete (); void updateComplete ();
Json::Value getStatus ();
std::pair<bool, Json::Value> doCreate ( std::pair<bool, Json::Value> doCreate (
std::shared_ptr<RippleLineCache> const&, std::shared_ptr<RippleLineCache> const&,
@@ -121,9 +121,10 @@ private:
std::weak_ptr<InfoSub> wpSubscriber; // Who this request came from std::weak_ptr<InfoSub> wpSubscriber; // Who this request came from
std::function <void (void)> fCompletion; std::function <void (void)> fCompletion;
Resource::Consumer& consumer_; // Charge according to source currencies
Json::Value jvId; Json::Value jvId;
Json::Value jvStatus; // Last result Json::Value jvStatus; // Last result
// Client request parameters // Client request parameters
boost::optional<AccountID> raSrcAccount; boost::optional<AccountID> raSrcAccount;

View File

@@ -96,8 +96,6 @@ void PathRequests::updateAll (std::shared_ptr <ReadView const> const& inLedger,
{ {
if (auto ipSub = request->getSubscriber ()) if (auto ipSub = request->getSubscriber ())
{ {
ipSub->getConsumer ().charge (
Resource::feePathFindUpdate);
if (!ipSub->getConsumer ().warn ()) if (!ipSub->getConsumer ().warn ())
{ {
Json::Value update = request->doUpdate (cache, false); Json::Value update = request->doUpdate (cache, false);
@@ -228,13 +226,15 @@ Json::Value
PathRequests::makeLegacyPathRequest( PathRequests::makeLegacyPathRequest(
PathRequest::pointer& req, PathRequest::pointer& req,
std::function <void (void)> completion, std::function <void (void)> completion,
Resource::Consumer& consumer,
std::shared_ptr<ReadView const> const& inLedger, std::shared_ptr<ReadView const> const& inLedger,
Json::Value const& request) Json::Value const& request)
{ {
// This assignment must take place before the // This assignment must take place before the
// completion function is called // completion function is called
req = std::make_shared<PathRequest> ( req = std::make_shared<PathRequest> (
app_, completion, ++mLastIdentifier, *this, mJournal); app_, completion, consumer, ++mLastIdentifier,
*this, mJournal);
auto result = req->doCreate ( auto result = req->doCreate (
getLineCache (inLedger, false), request); getLineCache (inLedger, false), request);

View File

@@ -57,6 +57,7 @@ public:
Json::Value makeLegacyPathRequest ( Json::Value makeLegacyPathRequest (
PathRequest::pointer& req, PathRequest::pointer& req,
std::function <void (void)> completion, std::function <void (void)> completion,
Resource::Consumer& consumer,
std::shared_ptr<ReadView const> const& inLedger, std::shared_ptr<ReadView const> const& inLedger,
Json::Value const& request); Json::Value const& request);

View File

@@ -266,8 +266,9 @@ public:
auto& app = env.app(); auto& app = env.app();
Resource::Charge loadType = Resource::feeReferenceRPC; Resource::Charge loadType = Resource::feeReferenceRPC;
RPC::Context context {beast::Journal(), {}, app, loadType, app.getOPs(), Resource::Consumer c;
app.getLedgerMaster(), Role::USER, {}}; RPC::Context context {beast::Journal(), {}, app, loadType,
app.getOPs(), app.getLedgerMaster(), c, Role::USER, {}};
Json::Value result; Json::Value result;
gate g; gate g;
// Test RPC::Tuning::max_src_cur source currencies. // Test RPC::Tuning::max_src_cur source currencies.

View File

@@ -36,7 +36,6 @@ Charge const feeLightRPC ( 5, "light RPC" ); // DAVID: C
Charge const feeLowBurdenRPC ( 20, "low RPC" ); Charge const feeLowBurdenRPC ( 20, "low RPC" );
Charge const feeMediumBurdenRPC ( 40, "medium RPC" ); Charge const feeMediumBurdenRPC ( 40, "medium RPC" );
Charge const feeHighBurdenRPC ( 300, "heavy RPC" ); Charge const feeHighBurdenRPC ( 300, "heavy RPC" );
Charge const feePathFindUpdate ( 100, "path update" );
Charge const feeLightPeer (1, "trivial peer request" ); Charge const feeLightPeer (1, "trivial peer request" );
Charge const feeLowBurdenPeer (2, "simple peer request" ); Charge const feeLowBurdenPeer (2, "simple peer request" );

View File

@@ -53,6 +53,7 @@ struct Context
Resource::Charge& loadType; Resource::Charge& loadType;
NetworkOPs& netOps; NetworkOPs& netOps;
LedgerMaster& ledgerMaster; LedgerMaster& ledgerMaster;
Resource::Consumer& consumer;
Role role; Role role;
std::shared_ptr<JobCoro> jobCoro; std::shared_ptr<JobCoro> jobCoro;
InfoSub::pointer infoSub; InfoSub::pointer infoSub;

View File

@@ -76,7 +76,7 @@ Json::Value doRipplePathFind (RPC::Context& context)
jvResult = context.app.getPathRequests().makeLegacyPathRequest ( jvResult = context.app.getPathRequests().makeLegacyPathRequest (
request, std::bind(&JobCoro::post, context.jobCoro), request, std::bind(&JobCoro::post, context.jobCoro),
lpLedger, context.params); context.consumer, lpLedger, context.params);
if (request) if (request)
{ {
context.jobCoro->yield(); context.jobCoro->yield();
@@ -357,14 +357,32 @@ ripplePathFind (std::shared_ptr<RippleLineCache> const& cache,
STPath fullLiquidityPath; STPath fullLiquidityPath;
auto ps = pathfinder->getBestPaths(max_paths, auto ps = pathfinder->getBestPaths(max_paths,
fullLiquidityPath, spsComputed, issue.account); fullLiquidityPath, spsComputed, issue.account);
auto& issuer =
isXRP(srcIssuerID) ? STAmount saMaxAmount;
isXRP(srcCurrencyID) ? // Default to source account. if (saSendMax)
xrpAccount() : {
(raSrc) saMaxAmount = *saSendMax;
: srcIssuerID; // Use specifed issuer. }
STAmount saMaxAmount = saSendMax.value_or( else
STAmount({ srcCurrencyID, issuer}, 1u, 0, true)); {
AccountID issuerID;
if (isXRP(srcIssuerID))
{
// Default to source account.
if(isXRP(srcCurrencyID))
issuerID = xrpAccount();
else
issuerID = raSrc;
}
else
{
// Use specifed issuer.
issuerID = srcIssuerID;
}
saMaxAmount = STAmount(
{srcCurrencyID, issuerID}, 1u, 0, true);
}
boost::optional<PaymentSandbox> sandbox; boost::optional<PaymentSandbox> sandbox;
sandbox.emplace(&*cache->getLedger(), tapNONE); sandbox.emplace(&*cache->getLedger(), tapNONE);

View File

@@ -366,7 +366,7 @@ ServerHandlerImp::processRequest (Port const& port,
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,
app_.getLedgerMaster(), role, jobCoro, InfoSub::pointer(), app_.getLedgerMaster(), usage, role, jobCoro, InfoSub::pointer(),
{user, forwardedFor}}; {user, forwardedFor}};
Json::Value result; Json::Value result;
RPC::doCommand (context, result); RPC::doCommand (context, result);

View File

@@ -286,8 +286,9 @@ Json::Value ConnectionImpl <WebSocket>::invokeCommand (
else else
{ {
RPC::Context context {app_.journal ("RPCHandler"), jvRequest, RPC::Context context {app_.journal ("RPCHandler"), jvRequest,
app_, loadType, m_netOPs, app_.getLedgerMaster(), role, app_, loadType, m_netOPs, app_.getLedgerMaster(), getConsumer(),
jobCoro, this->shared_from_this (), {m_user, m_forwardedFor}}; role, jobCoro, this->shared_from_this(),
{m_user, m_forwardedFor}};
RPC::doCommand (context, jvResult[jss::result]); RPC::doCommand (context, jvResult[jss::result]);
} }