mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
New ResourceManager for managing server load.
* Track abusive endpoints * Gossip across cluster. * Use resource manager's gossip support to share load reporting across a cluster * Swtich from legacy fees to new Resource::Charge fees. * Connect RPC to the new resource manager. * Set load levels where needed in RPC/websocket commands. * Disconnect abusive peer endpoints. * Don't start conversations with abusive peer endpoints. * Move Resource::Consumer to InfoSub and remove LoadSource * Remove port from inbound Consumer keys * Add details in getJson * Fix doAccountCurrencies for the new resource manager.
This commit is contained in:
committed by
Vinnie Falco
parent
a05f33f6a7
commit
58f07a573f
@@ -1926,7 +1926,6 @@
|
||||
<ClInclude Include="..\..\src\ripple_basics\utility\ThreadName.h" />
|
||||
<ClInclude Include="..\..\src\ripple_basics\utility\Time.h" />
|
||||
<ClInclude Include="..\..\src\ripple_basics\utility\UptimeTimer.h" />
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\LoadSource.h" />
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\Config.h" />
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\ConfigSections.h" />
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\LoadFeeTrack.h" />
|
||||
|
||||
@@ -1706,9 +1706,6 @@
|
||||
<ClInclude Include="..\..\src\ripple_app\peers\Peers.h">
|
||||
<Filter>[2] Old Ripple\ripple_app\peers</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple_core\functional\LoadSource.h">
|
||||
<Filter>[2] Old Ripple\ripple_core\functional</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple_app\main\LoadManager.h">
|
||||
<Filter>[2] Old Ripple\ripple_app\main</Filter>
|
||||
</ClInclude>
|
||||
|
||||
@@ -197,11 +197,4 @@
|
||||
#define RIPPLE_USE_RPC_SERVICE_MANAGER 0
|
||||
#endif
|
||||
|
||||
// Here temporarily
|
||||
// Controls whether or not the new Resource manager replaces the BlackList
|
||||
// and LoadManager for measuring and controlling access to the server
|
||||
#ifndef RIPPLE_USE_RESOURCE_MANAGER
|
||||
#define RIPPLE_USE_RESOURCE_MANAGER 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -47,6 +47,9 @@ public:
|
||||
/** Converts this charge into a human readable string. */
|
||||
std::string to_string () const;
|
||||
|
||||
bool operator== (Charge const&) const;
|
||||
bool operator!= (Charge const&) const;
|
||||
|
||||
private:
|
||||
value_type m_cost;
|
||||
std::string m_label;
|
||||
|
||||
@@ -46,6 +46,10 @@ public:
|
||||
/** Extract packaged consumer information for export. */
|
||||
virtual Gossip exportConsumers () = 0;
|
||||
|
||||
/** Extract consumer information for reporting. */
|
||||
virtual Json::Value getJson () = 0;
|
||||
virtual Json::Value getJson (int threshold) = 0;
|
||||
|
||||
/** Import packaged consumer information.
|
||||
@param origin An identifier that unique labels the origin.
|
||||
*/
|
||||
|
||||
@@ -56,5 +56,15 @@ std::ostream& operator<< (std::ostream& os, Charge const& v)
|
||||
return os;
|
||||
}
|
||||
|
||||
bool Charge::operator== (Charge const& c) const
|
||||
{
|
||||
return c.m_cost == m_cost;
|
||||
}
|
||||
|
||||
bool Charge::operator!= (Charge const& c) const
|
||||
{
|
||||
return c.m_cost != m_cost;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,11 +87,15 @@ std::string Consumer::to_string () const
|
||||
|
||||
bool Consumer::admin () const
|
||||
{
|
||||
return m_entry->admin();
|
||||
if (m_entry != nullptr)
|
||||
return m_entry->admin();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Consumer::elevate (std::string const& name)
|
||||
{
|
||||
bassert (m_entry != nullptr);
|
||||
m_entry = &m_logic->elevateToAdminEndpoint (*m_entry, name);
|
||||
}
|
||||
|
||||
@@ -102,26 +106,31 @@ Disposition Consumer::disposition() const
|
||||
|
||||
Disposition Consumer::charge (Charge const& what)
|
||||
{
|
||||
bassert (m_entry != nullptr);
|
||||
return m_logic->charge (*m_entry, what);
|
||||
}
|
||||
|
||||
bool Consumer::warn ()
|
||||
{
|
||||
bassert (m_entry != nullptr);
|
||||
return m_logic->warn (*m_entry);
|
||||
}
|
||||
|
||||
bool Consumer::disconnect ()
|
||||
{
|
||||
bassert (m_entry != nullptr);
|
||||
return m_logic->disconnect (*m_entry);
|
||||
}
|
||||
|
||||
int Consumer::balance()
|
||||
{
|
||||
bassert (m_entry != nullptr);
|
||||
return m_logic->balance (*m_entry);
|
||||
}
|
||||
|
||||
Entry& Consumer::entry()
|
||||
{
|
||||
bassert (m_entry != nullptr);
|
||||
return *m_entry;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
|
||||
Key key;
|
||||
key.kind = kindInbound;
|
||||
key.address = address;
|
||||
key.address = address.withPort (0);
|
||||
|
||||
Entry* entry (nullptr);
|
||||
|
||||
@@ -202,6 +202,61 @@ public:
|
||||
return *entry;
|
||||
}
|
||||
|
||||
Json::Value getJson ()
|
||||
{
|
||||
return getJson (warningThreshold);
|
||||
}
|
||||
|
||||
Json::Value getJson (int threshold)
|
||||
{
|
||||
DiscreteTime const now (m_clock());
|
||||
|
||||
Json::Value ret (Json::objectValue);
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
for (List <Entry>::iterator iter (state->inbound.begin());
|
||||
iter != state->inbound.end(); ++iter)
|
||||
{
|
||||
int localBalance = iter->local_balance.value (now);
|
||||
if ((localBalance + iter->remote_balance) >= threshold)
|
||||
{
|
||||
Json::Value& entry = (ret[iter->to_string()] = Json::objectValue);
|
||||
entry["local"] = localBalance;
|
||||
entry["remote"] = iter->remote_balance;
|
||||
entry["type"] = "outbound";
|
||||
}
|
||||
|
||||
}
|
||||
for (List <Entry>::iterator iter (state->outbound.begin());
|
||||
iter != state->outbound.end(); ++iter)
|
||||
{
|
||||
int localBalance = iter->local_balance.value (now);
|
||||
if ((localBalance + iter->remote_balance) >= threshold)
|
||||
{
|
||||
Json::Value& entry = (ret[iter->to_string()] = Json::objectValue);
|
||||
entry["local"] = localBalance;
|
||||
entry["remote"] = iter->remote_balance;
|
||||
entry["type"] = "outbound";
|
||||
}
|
||||
|
||||
}
|
||||
for (List <Entry>::iterator iter (state->admin.begin());
|
||||
iter != state->admin.end(); ++iter)
|
||||
{
|
||||
int localBalance = iter->local_balance.value (now);
|
||||
if ((localBalance + iter->remote_balance) >= threshold)
|
||||
{
|
||||
Json::Value& entry = (ret[iter->to_string()] = Json::objectValue);
|
||||
entry["local"] = localBalance;
|
||||
entry["remote"] = iter->remote_balance;
|
||||
entry["type"] = "admin";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Gossip exportConsumers ()
|
||||
{
|
||||
DiscreteTime const now (m_clock());
|
||||
@@ -318,8 +373,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
for (Imports::iterator iter (state->import_table.begin());
|
||||
iter != state->import_table.end(); ++iter)
|
||||
Imports::iterator iter (state->import_table.begin());
|
||||
while (iter != state->import_table.end())
|
||||
{
|
||||
Import& import (iter->second);
|
||||
if (iter->second.whenExpires <= now)
|
||||
@@ -332,6 +387,8 @@ public:
|
||||
|
||||
iter = state->import_table.erase (iter);
|
||||
}
|
||||
else
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,18 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
Json::Value getJson ()
|
||||
{
|
||||
return m_logic.getJson ();
|
||||
}
|
||||
|
||||
Json::Value getJson (int threshold)
|
||||
{
|
||||
return m_logic.getJson (threshold);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void onWrite (PropertyStream::Map& map)
|
||||
{
|
||||
m_logic.onWrite (map);
|
||||
|
||||
@@ -26,6 +26,8 @@ namespace ripple {
|
||||
using namespace beast;
|
||||
}
|
||||
|
||||
#include "../json/ripple_json.h"
|
||||
|
||||
# include "api/Types.h"
|
||||
# include "api/Disposition.h"
|
||||
# include "api/Charge.h"
|
||||
|
||||
@@ -130,7 +130,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
if (peer)
|
||||
{
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -147,7 +146,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
{
|
||||
WriteLog (lsWARNING, InboundLedger) << "Got empty base data";
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -155,7 +153,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
{
|
||||
WriteLog (lsWARNING, InboundLedger) << "Got invalid base data";
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -191,7 +188,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
{
|
||||
WriteLog (lsINFO, InboundLedger) << "Got response with no nodes";
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,7 +199,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
{
|
||||
WriteLog (lsWARNING, InboundLedger) << "Got bad node";
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -231,7 +226,6 @@ void InboundLedgers::gotLedgerData (Job&, LedgerHash hash,
|
||||
|
||||
WriteLog (lsWARNING, InboundLedger) << "Not sure what ledger data we got";
|
||||
peer->charge (Resource::feeInvalidRequest);
|
||||
peer->applyLoadCharge (LT_InvalidRequest);
|
||||
}
|
||||
|
||||
void InboundLedgers::sweep ()
|
||||
|
||||
@@ -110,10 +110,10 @@ public:
|
||||
, m_deprecatedUNL (UniqueNodeList::New (*m_jobQueue))
|
||||
|
||||
, m_rpcHTTPServer (RPCHTTPServer::New (*m_networkOPs,
|
||||
LogJournal::get <HTTPServerLog> (), *m_jobQueue, *m_networkOPs))
|
||||
LogJournal::get <HTTPServerLog> (), *m_jobQueue, *m_networkOPs, *m_resourceManager))
|
||||
|
||||
#if ! RIPPLE_USE_RPC_SERVICE_MANAGER
|
||||
, m_rpcServerHandler (*m_networkOPs) // passive object, not a Service
|
||||
, m_rpcServerHandler (*m_networkOPs, *m_resourceManager) // passive object, not a Service
|
||||
#endif
|
||||
|
||||
, m_nodeStoreScheduler (*m_jobQueue, *m_jobQueue)
|
||||
@@ -228,6 +228,11 @@ public:
|
||||
return *m_loadManager;
|
||||
}
|
||||
|
||||
Resource::Manager& getResourceManager ()
|
||||
{
|
||||
return *m_resourceManager;
|
||||
}
|
||||
|
||||
TxQueue& getTxQueue ()
|
||||
{
|
||||
return *m_txQueue;
|
||||
@@ -537,7 +542,7 @@ public:
|
||||
{
|
||||
m_wsPrivateDoor = WSDoor::New (*m_resourceManager,
|
||||
getOPs(), getConfig ().WEBSOCKET_IP,
|
||||
getConfig ().WEBSOCKET_PORT, false,
|
||||
getConfig ().WEBSOCKET_PORT, false, false,
|
||||
m_wsSSLContext->get ());
|
||||
|
||||
if (m_wsPrivateDoor == nullptr)
|
||||
@@ -557,7 +562,7 @@ public:
|
||||
{
|
||||
m_wsPublicDoor = WSDoor::New (*m_resourceManager,
|
||||
getOPs(), getConfig ().WEBSOCKET_PUBLIC_IP,
|
||||
getConfig ().WEBSOCKET_PUBLIC_PORT, true,
|
||||
getConfig ().WEBSOCKET_PUBLIC_PORT, true, false,
|
||||
m_wsSSLContext->get ());
|
||||
|
||||
if (m_wsPublicDoor == nullptr)
|
||||
@@ -570,6 +575,19 @@ public:
|
||||
{
|
||||
m_journal.info << "WebSocket public interface: disabled";
|
||||
}
|
||||
if (!getConfig ().WEBSOCKET_PROXY_IP.empty () && getConfig ().WEBSOCKET_PROXY_PORT)
|
||||
{
|
||||
m_wsProxyDoor = WSDoor::New (*m_resourceManager,
|
||||
getOPs(), getConfig ().WEBSOCKET_PROXY_IP,
|
||||
getConfig ().WEBSOCKET_PROXY_PORT, true, true,
|
||||
m_wsSSLContext->get ());
|
||||
|
||||
if (m_wsProxyDoor == nullptr)
|
||||
{
|
||||
FatalError ("Could not open the WebSocket public interface.",
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
@@ -744,6 +762,7 @@ public:
|
||||
// once the WSDoor cancels its pending I/O correctly
|
||||
//m_wsPublicDoor = nullptr;
|
||||
//m_wsPrivateDoor = nullptr;
|
||||
//m_wsProxyDoor = nullptr;
|
||||
|
||||
// VFALCO TODO Try to not have to do this early, by using observers to
|
||||
// eliminate LoadManager's dependency inversions.
|
||||
@@ -898,6 +917,7 @@ private:
|
||||
ScopedPointer <RPCDoor> m_rpcDoor;
|
||||
ScopedPointer <WSDoor> m_wsPublicDoor;
|
||||
ScopedPointer <WSDoor> m_wsPrivateDoor;
|
||||
ScopedPointer <WSDoor> m_wsProxyDoor;
|
||||
|
||||
WaitableEvent m_stop;
|
||||
};
|
||||
|
||||
@@ -102,6 +102,7 @@ public:
|
||||
virtual TransactionMaster& getMasterTransaction () = 0;
|
||||
virtual TxQueue& getTxQueue () = 0;
|
||||
virtual LocalCredentials& getLocalCredentials () = 0;
|
||||
virtual Resource::Manager& getResourceManager () = 0;
|
||||
|
||||
virtual DatabaseCon* getRpcDB () = 0;
|
||||
virtual DatabaseCon* getTxnDB () = 0;
|
||||
|
||||
@@ -74,13 +74,6 @@ public:
|
||||
typedef LockType::ScopedLockType ScopedLockType;
|
||||
LockType mLock;
|
||||
|
||||
BlackList<UptimeTimerAdapter> mBlackList;
|
||||
|
||||
int mCreditRate; // credits gained/lost per second
|
||||
int mCreditLimit; // the most credits a source can have
|
||||
int mDebitWarn; // when a source drops below this, we warn
|
||||
int mDebitLimit; // when a source drops below this, we cut it off (should be negative)
|
||||
|
||||
bool mArmed;
|
||||
|
||||
int mDeadLock; // Detect server deadlocks
|
||||
@@ -94,52 +87,10 @@ public:
|
||||
, Thread ("loadmgr")
|
||||
, m_journal (journal)
|
||||
, mLock (this, "LoadManagerImp", __FILE__, __LINE__)
|
||||
, mCreditRate (100)
|
||||
, mCreditLimit (500)
|
||||
, mDebitWarn (-500)
|
||||
, mDebitLimit (-1000)
|
||||
, mArmed (false)
|
||||
, mDeadLock (0)
|
||||
, mCosts (LT_MAX)
|
||||
{
|
||||
/** Flags indicating the type of load.
|
||||
|
||||
Utilization may include any combination of:
|
||||
|
||||
- CPU
|
||||
- Storage space
|
||||
- Network transfer
|
||||
*/
|
||||
// VFALCO NOTE These flags are not used...
|
||||
enum
|
||||
{
|
||||
flagDisk = 1,
|
||||
flagCpu = 2,
|
||||
flagNet = 4
|
||||
};
|
||||
|
||||
// VFALCO TODO Replace this with a function that uses a simple switch statement...
|
||||
//
|
||||
addCost (Cost (LT_InvalidRequest, -10, flagCpu | flagNet));
|
||||
addCost (Cost (LT_RequestNoReply, -1, flagCpu | flagDisk));
|
||||
addCost (Cost (LT_InvalidSignature, -100, flagCpu));
|
||||
addCost (Cost (LT_UnwantedData, -5, flagCpu | flagNet));
|
||||
addCost (Cost (LT_BadData, -20, flagCpu));
|
||||
|
||||
addCost (Cost (LT_RPCInvalid, -10, flagCpu | flagNet));
|
||||
addCost (Cost (LT_RPCReference, -10, flagCpu | flagNet));
|
||||
addCost (Cost (LT_RPCException, -20, flagCpu | flagNet));
|
||||
addCost (Cost (LT_RPCBurden, -50, flagCpu | flagNet));
|
||||
|
||||
// VFALCO NOTE Why do these supposedly "good" load types still have a negative cost?
|
||||
//
|
||||
addCost (Cost (LT_NewTrusted, -10, 0));
|
||||
addCost (Cost (LT_NewTransaction, -2, 0));
|
||||
addCost (Cost (LT_NeededData, -10, 0));
|
||||
|
||||
addCost (Cost (LT_RequestData, -5, flagDisk | flagNet));
|
||||
addCost (Cost (LT_CheapQuery, -1, flagCpu));
|
||||
|
||||
UptimeTimer::getInstance ().beginManualUpdates ();
|
||||
}
|
||||
|
||||
@@ -154,6 +105,7 @@ public:
|
||||
//
|
||||
// Stoppable
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void onPrepare ()
|
||||
{
|
||||
@@ -180,136 +132,6 @@ public:
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void canonicalize (LoadSource& source, int now) const
|
||||
{
|
||||
if (source.mLastUpdate != now)
|
||||
{
|
||||
if (source.mLastUpdate < now)
|
||||
{
|
||||
source.mBalance += mCreditRate * (now - source.mLastUpdate);
|
||||
|
||||
if (source.mBalance > mCreditLimit)
|
||||
{
|
||||
source.mBalance = mCreditLimit;
|
||||
source.mLogged = false;
|
||||
}
|
||||
}
|
||||
|
||||
source.mLastUpdate = now;
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldWarn (LoadSource& source)
|
||||
{
|
||||
{
|
||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||
|
||||
int now = UptimeTimer::getInstance ().getElapsedSeconds ();
|
||||
canonicalize (source, now);
|
||||
|
||||
if (source.isPrivileged () || (source.mBalance > mDebitWarn) || (source.mLastWarning == now))
|
||||
return false;
|
||||
|
||||
source.mLastWarning = now;
|
||||
}
|
||||
mBlackList.doWarning(source.getCostName ());
|
||||
logWarning (source.getName ());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool shouldCutoff (LoadSource& source)
|
||||
{
|
||||
bool bLogged;
|
||||
{
|
||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||
int now = UptimeTimer::getInstance ().getElapsedSeconds ();
|
||||
canonicalize (source, now);
|
||||
|
||||
if (source.isPrivileged () || (source.mBalance > mDebitLimit))
|
||||
return false;
|
||||
|
||||
bLogged = source.mLogged;
|
||||
source.mLogged = true;
|
||||
}
|
||||
|
||||
mBlackList.doDisconnect (source.getName ());
|
||||
|
||||
if (!bLogged)
|
||||
logDisconnect (source.getName ());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool shouldAllow (LoadSource& source)
|
||||
{
|
||||
return mBlackList.isAllowed (source.getCostName ());
|
||||
}
|
||||
|
||||
bool applyLoadCharge (LoadSource& source, LoadType loadType) const
|
||||
{
|
||||
// FIXME: Scale by category
|
||||
Cost cost = mCosts[static_cast<int> (loadType)];
|
||||
|
||||
return adjust (source, cost.m_cost);
|
||||
}
|
||||
|
||||
bool adjust (LoadSource& source, int credits) const
|
||||
{
|
||||
// return: true = need to warn/cutoff
|
||||
|
||||
// We do it this way in case we want to add exponential decay later
|
||||
int now = UptimeTimer::getInstance ().getElapsedSeconds ();
|
||||
|
||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||
canonicalize (source, now);
|
||||
source.mBalance += credits;
|
||||
|
||||
if (source.mBalance > mCreditLimit)
|
||||
source.mBalance = mCreditLimit;
|
||||
|
||||
if (source.isPrivileged ()) // privileged sources never warn/cutoff
|
||||
return false;
|
||||
|
||||
if ( (source.mBalance >= mDebitWarn) ||
|
||||
((source.mBalance >= mDebitLimit) && (source.mLastWarning == now)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void logWarning (const std::string& source) const
|
||||
{
|
||||
if (source.empty ())
|
||||
m_journal.debug << "Load warning from empty source";
|
||||
else
|
||||
m_journal.info << "Load warning: " << source;
|
||||
}
|
||||
|
||||
void logDisconnect (const std::string& source) const
|
||||
{
|
||||
if (source.empty ())
|
||||
m_journal.info << "Disconnect for empty source";
|
||||
else
|
||||
m_journal.warning << "Disconnect for: " << source;
|
||||
}
|
||||
|
||||
Json::Value getBlackList (int threshold)
|
||||
{
|
||||
Json::Value ret(Json::objectValue);
|
||||
|
||||
BOOST_FOREACH(const BlackList<UptimeTimerAdapter>::BlackListEntry& entry, mBlackList.getBlackList(threshold))
|
||||
{
|
||||
ret[entry.first] = entry.second;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// VFALCO TODO Implement this and stop accessing the vector directly
|
||||
//Cost const& getCost (LoadType loadType) const;
|
||||
int getCost (LoadType t) const
|
||||
{
|
||||
return mCosts [static_cast <int> (t)].getCost ();
|
||||
}
|
||||
|
||||
void resetDeadlockDetector ()
|
||||
{
|
||||
ScopedLockType sl (mLock, __FILE__, __LINE__);
|
||||
@@ -337,11 +159,6 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
void addCost (const Cost& c)
|
||||
{
|
||||
mCosts [static_cast <int> (c.getLoadType ())] = c;
|
||||
}
|
||||
|
||||
// VFALCO NOTE Where's the thread object? It's not a data member...
|
||||
//
|
||||
void run ()
|
||||
|
||||
@@ -72,23 +72,6 @@ public:
|
||||
time passes it will produce log warnings.
|
||||
*/
|
||||
virtual void resetDeadlockDetector () = 0;
|
||||
|
||||
/** Update an endpoint to reflect an imposed load.
|
||||
|
||||
The balance of the endpoint is adjusted based on the heuristic cost
|
||||
of the indicated load.
|
||||
|
||||
@return `true` if the endpoint should be warned or punished.
|
||||
*/
|
||||
virtual bool applyLoadCharge (LoadSource& sourceToAdjust, LoadType loadToImpose) const = 0;
|
||||
|
||||
// VFALCO TODO Eliminate these two functions and just make applyLoadCharge()
|
||||
// return a LoadSource::Disposition
|
||||
//
|
||||
virtual bool shouldWarn (LoadSource&) = 0;
|
||||
virtual bool shouldCutoff (LoadSource&) = 0;
|
||||
|
||||
virtual Json::Value getBlackList(int threshold = (BlackList<UptimeTimerAdapter>::mCreditLimit / 2)) = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,7 @@ class RPCHTTPServerImp
|
||||
, public HTTP::Handler
|
||||
{
|
||||
public:
|
||||
Resource::Manager& m_resourceManager;
|
||||
Journal m_journal;
|
||||
JobQueue& m_jobQueue;
|
||||
NetworkOPs& m_networkOPs;
|
||||
@@ -34,12 +35,14 @@ public:
|
||||
RPCHTTPServerImp (Stoppable& parent,
|
||||
Journal journal,
|
||||
JobQueue& jobQueue,
|
||||
NetworkOPs& networkOPs)
|
||||
NetworkOPs& networkOPs,
|
||||
Resource::Manager& resourceManager)
|
||||
: RPCHTTPServer (parent)
|
||||
, m_resourceManager (resourceManager)
|
||||
, m_journal (journal)
|
||||
, m_jobQueue (jobQueue)
|
||||
, m_networkOPs (networkOPs)
|
||||
, m_deprecatedHandler (networkOPs)
|
||||
, m_deprecatedHandler (networkOPs, resourceManager)
|
||||
, m_server (*this, journal)
|
||||
{
|
||||
if (getConfig ().RPC_SECURE == 0)
|
||||
@@ -186,6 +189,16 @@ public:
|
||||
|
||||
Config::Role const role (getConfig ().getAdminRole (jvRequest, remoteAddress));
|
||||
|
||||
Resource::Consumer usage;
|
||||
|
||||
if (role == Config::ADMIN)
|
||||
usage = m_resourceManager.newAdminEndpoint(remoteAddress);
|
||||
else
|
||||
usage = m_resourceManager.newInboundEndpoint(IPAddress::from_string(remoteAddress));
|
||||
|
||||
if (usage.disconnect ())
|
||||
return createResponse (503, "Server is overloaded");
|
||||
|
||||
// Parse id now so errors from here on will have the id
|
||||
//
|
||||
// VFALCO NOTE Except that "id" isn't included in the following errors...
|
||||
@@ -241,11 +254,12 @@ public:
|
||||
|
||||
RPCHandler rpcHandler (&m_networkOPs);
|
||||
|
||||
LoadType loadType = LT_RPCReference;
|
||||
Resource::Charge loadType = Resource::feeReferenceRPC;
|
||||
|
||||
Json::Value const result (rpcHandler.doRpcCommand (
|
||||
strMethod, params, role, &loadType));
|
||||
// VFALCO NOTE We discard loadType since there is no endpoint to punish
|
||||
strMethod, params, role, loadType));
|
||||
|
||||
usage.charge (loadType);
|
||||
|
||||
m_journal.debug << "Reply: " << result;
|
||||
|
||||
@@ -267,8 +281,9 @@ RPCHTTPServer::RPCHTTPServer (Stoppable& parent)
|
||||
RPCHTTPServer* RPCHTTPServer::New (Stoppable& parent,
|
||||
Journal journal,
|
||||
JobQueue& jobQueue,
|
||||
NetworkOPs& networkOPs)
|
||||
NetworkOPs& networkOPs,
|
||||
Resource::Manager& resourceManager)
|
||||
{
|
||||
return new RPCHTTPServerImp (parent, journal, jobQueue, networkOPs);
|
||||
return new RPCHTTPServerImp (parent, journal, jobQueue, networkOPs, resourceManager);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ protected:
|
||||
|
||||
public:
|
||||
static RPCHTTPServer* New (Stoppable& parent,
|
||||
Journal journal, JobQueue& jobQueue, NetworkOPs& networkOPs);
|
||||
Journal journal, JobQueue& jobQueue, NetworkOPs& networkOPs, Resource::Manager& resourceManager);
|
||||
|
||||
virtual ~RPCHTTPServer () { }
|
||||
|
||||
|
||||
@@ -60,9 +60,8 @@ void startServer ()
|
||||
|
||||
RPCHandler rhHandler (&getApp().getOPs ());
|
||||
|
||||
// VFALCO TODO Clean up this magic number
|
||||
LoadType loadType = LT_RPCReference;
|
||||
Json::Value jvResult = rhHandler.doCommand (jvCommand, Config::ADMIN, &loadType);
|
||||
Resource::Charge loadType = Resource::feeReferenceRPC;
|
||||
Json::Value jvResult = rhHandler.doCommand (jvCommand, Config::ADMIN, loadType);
|
||||
|
||||
if (!getConfig ().QUIET)
|
||||
Log::out() << "Result: " << jvResult;
|
||||
|
||||
@@ -567,6 +567,14 @@ void NetworkOPsImp::processClusterTimer ()
|
||||
node.set_nodename(it->second.getName());
|
||||
}
|
||||
|
||||
Resource::Gossip gossip = getApp().getResourceManager().exportConsumers();
|
||||
BOOST_FOREACH (Resource::Gossip::Item const& item, gossip.items)
|
||||
{
|
||||
protocol::TMLoadSource& node = *cluster.add_loadsources();
|
||||
node.set_name (item.address);
|
||||
node.set_cost (item.balance);
|
||||
}
|
||||
|
||||
PackedMessage::pointer message = boost::make_shared<PackedMessage>(cluster, protocol::mtCLUSTER);
|
||||
getApp().getPeers().relayMessageCluster (NULL, message);
|
||||
|
||||
|
||||
@@ -76,7 +76,6 @@ public:
|
||||
, mCluster (false)
|
||||
, mPeerId (peerID)
|
||||
, mPrivate (false)
|
||||
, mLoad (std::string(), std::string())
|
||||
, mMinLedger (0)
|
||||
, mMaxLedger (0)
|
||||
, mActivityTimer (io_service)
|
||||
@@ -99,7 +98,6 @@ private:
|
||||
uint256 mCookieHash;
|
||||
uint64 mPeerId;
|
||||
bool mPrivate; // Keep peer IP private.
|
||||
LoadSource mLoad;
|
||||
uint32 mMinLedger, mMaxLedger;
|
||||
|
||||
uint256 mClosedLedgerHash;
|
||||
@@ -165,11 +163,10 @@ public:
|
||||
|
||||
void charge (Resource::Charge const& fee)
|
||||
{
|
||||
m_usage.charge (fee);
|
||||
if ((m_usage.charge (fee) == Resource::drop) && m_usage.disconnect ())
|
||||
detach ("resource", false);
|
||||
}
|
||||
|
||||
void applyLoadCharge (LoadType);
|
||||
|
||||
Json::Value getJson ();
|
||||
bool isConnected () const
|
||||
{
|
||||
@@ -308,6 +305,7 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
bool valid = false;
|
||||
|
||||
if (m_socket->getFlags ().set (MultiSocket::Flag::proxy) && m_isInbound)
|
||||
{
|
||||
@@ -332,11 +330,7 @@ private:
|
||||
else
|
||||
m_usage = m_resourceManager.newOutboundEndpoint (m_remoteAddress);
|
||||
|
||||
getApp ().getPeers ().peerConnected(m_remoteAddress, m_isInbound);
|
||||
|
||||
// Must compute mCookieHash before receiving a hello.
|
||||
sendHello ();
|
||||
startReadHeader ();
|
||||
valid = true;
|
||||
|
||||
WriteLog (lsINFO, Peer) << "Peer: PROXY handshake from " << mIpPort.first;
|
||||
}
|
||||
@@ -380,12 +374,25 @@ private:
|
||||
else
|
||||
m_usage = m_resourceManager.newOutboundEndpoint (m_remoteAddress);
|
||||
|
||||
getApp ().getPeers ().peerConnected(m_remoteAddress, m_isInbound);
|
||||
|
||||
// Must compute mCookieHash before receiving a hello.
|
||||
sendHello ();
|
||||
startReadHeader ();
|
||||
valid = true;
|
||||
}
|
||||
|
||||
if (valid)
|
||||
{
|
||||
if (m_usage.disconnect ())
|
||||
{
|
||||
detach ("resource", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
getApp ().getPeers ().peerConnected(m_remoteAddress, m_isInbound);
|
||||
|
||||
// Must compute mCookieHash before receiving a hello.
|
||||
sendHello ();
|
||||
startReadHeader ();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,7 +476,6 @@ void PeerImp::handleWrite (const boost::system::error_code& error, size_t bytes_
|
||||
void PeerImp::setIpPort (const std::string& strIP, int iPort)
|
||||
{
|
||||
mIpPort = make_pair (strIP, iPort);
|
||||
mLoad.rename (strIP + lexicalCast<std::string>(iPort), strIP);
|
||||
|
||||
WriteLog (lsDEBUG, Peer) << "Peer: Set: "
|
||||
<< addressToString (this) << "> "
|
||||
@@ -1163,16 +1169,10 @@ void PeerImp::recvHello (protocol::TMHello& packet)
|
||||
if (getApp().getUNL ().nodeInCluster (mNodePublic, mNodeName))
|
||||
{
|
||||
mCluster = true;
|
||||
mLoad.setPrivileged ();
|
||||
if (!mNodeName.empty())
|
||||
mLoad.rename (mNodeName, mNodeName);
|
||||
WriteLog (lsINFO, Peer) << "Cluster connection to \"" << (mNodeName.empty () ? getIP () : mNodeName)
|
||||
<< "\" established";
|
||||
}
|
||||
|
||||
if (isOutbound ())
|
||||
mLoad.setOutbound ();
|
||||
|
||||
if (mClientConnect)
|
||||
{
|
||||
// If we connected due to scan, no longer need to scan.
|
||||
@@ -1268,7 +1268,6 @@ static void checkTransaction (Job&, int flags, SerializedTransaction::pointer st
|
||||
{
|
||||
getApp().getHashRouter ().setFlag (stx->getTransactionID (), SF_BAD);
|
||||
Peer::charge (peer, Resource::feeInvalidSignature);
|
||||
Peer::applyLoadCharge (peer, LT_InvalidSignature);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -1282,7 +1281,6 @@ static void checkTransaction (Job&, int flags, SerializedTransaction::pointer st
|
||||
{
|
||||
getApp().getHashRouter ().setFlag (stx->getTransactionID (), SF_BAD);
|
||||
Peer::charge (peer, Resource::feeInvalidRequest);
|
||||
Peer::applyLoadCharge (peer, LT_InvalidRequest);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1310,7 +1308,6 @@ void PeerImp::recvTransaction (protocol::TMTransaction& packet, Application::Sco
|
||||
if (isSetBit (flags, SF_BAD))
|
||||
{
|
||||
charge (Resource::feeInvalidSignature);
|
||||
applyLoadCharge (LT_InvalidSignature);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1375,7 +1372,6 @@ static void checkPropose (Job& job, boost::shared_ptr<protocol::TMProposeSet> pa
|
||||
WriteLog (lsWARNING, Peer) << "proposal with previous ledger fails signature check: " <<
|
||||
(p ? p->getIP () : std::string ("???"));
|
||||
Peer::charge (peer, Resource::feeInvalidSignature);
|
||||
Peer::applyLoadCharge (peer, LT_InvalidSignature);
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -1420,7 +1416,6 @@ void PeerImp::recvPropose (const boost::shared_ptr<protocol::TMProposeSet>& pack
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Received proposal is malformed";
|
||||
charge (Resource::feeInvalidSignature);
|
||||
applyLoadCharge (LT_InvalidSignature);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1428,7 +1423,6 @@ void PeerImp::recvPropose (const boost::shared_ptr<protocol::TMProposeSet>& pack
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Received proposal is malformed";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1490,7 +1484,6 @@ void PeerImp::recvHaveTxSet (protocol::TMHaveTransactionSet& packet)
|
||||
if (packet.hash ().size () != (256 / 8))
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1507,7 +1500,6 @@ void PeerImp::recvHaveTxSet (protocol::TMHaveTransactionSet& packet)
|
||||
if (!getApp().getOPs ().hasTXSet (shared_from_this (), hash, packet.status ()))
|
||||
{
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge (LT_UnwantedData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1524,7 +1516,6 @@ static void checkValidation (Job&, SerializedValidation::pointer val, bool isTru
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Validation is invalid";
|
||||
Peer::charge (peer, Resource::feeInvalidRequest);
|
||||
Peer::applyLoadCharge (peer, LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1563,7 +1554,6 @@ static void checkValidation (Job&, SerializedValidation::pointer val, bool isTru
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Exception processing validation";
|
||||
Peer::charge (peer, Resource::feeInvalidRequest);
|
||||
Peer::applyLoadCharge (peer, LT_InvalidRequest);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1578,7 +1568,6 @@ void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& p
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Too small validation from peer";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1595,7 +1584,6 @@ void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& p
|
||||
{
|
||||
WriteLog (lsTRACE, Peer) << "Validation is more than two minutes old";
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge (LT_UnwantedData);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1619,7 +1607,6 @@ void PeerImp::recvValidation (const boost::shared_ptr<protocol::TMValidation>& p
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Exception processing validation";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1630,7 +1617,6 @@ void PeerImp::recvCluster (protocol::TMCluster& packet)
|
||||
if (!mCluster)
|
||||
{
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge(LT_UnwantedData);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1649,6 +1635,23 @@ void PeerImp::recvCluster (protocol::TMCluster& packet)
|
||||
getApp().getUNL().nodeUpdate(nodePub, s);
|
||||
}
|
||||
|
||||
int loadSources = packet.loadsources().size();
|
||||
if (loadSources != 0)
|
||||
{
|
||||
Resource::Gossip gossip;
|
||||
gossip.items.reserve (loadSources);
|
||||
for (int i = 0; i < packet.loadsources().size(); ++i)
|
||||
{
|
||||
protocol::TMLoadSource const& node = packet.loadsources (i);
|
||||
Resource::Gossip::Item item;
|
||||
item.address = IPAddress::from_string (node.name());
|
||||
item.balance = node.cost();
|
||||
if (item.address != IPAddress())
|
||||
gossip.items.push_back(item);
|
||||
}
|
||||
m_resourceManager.importConsumers (mNodeName, gossip);
|
||||
}
|
||||
|
||||
getApp().getFeeTrack().setClusterFee(getApp().getUNL().getClusterFee());
|
||||
}
|
||||
|
||||
@@ -1926,7 +1929,6 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
|
||||
if (packet.response ().size () != (256 / 8))
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1946,7 +1948,6 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
|
||||
if (r != powTOOEASY)
|
||||
{
|
||||
charge (Resource::feeBadProofOfWork);
|
||||
applyLoadCharge (LT_BadPoW);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -1968,7 +1969,6 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
|
||||
if ((packet.challenge ().size () != (256 / 8)) || (packet.target ().size () != (256 / 8)))
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1980,7 +1980,6 @@ void PeerImp::recvProofWork (protocol::TMProofWork& packet)
|
||||
if (!pow->isValid ())
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2078,7 +2077,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
if ((!packet.has_ledgerhash () || packet.ledgerhash ().size () != 32))
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
WriteLog (lsWARNING, Peer) << "invalid request for TX candidate set data";
|
||||
return;
|
||||
}
|
||||
@@ -2115,7 +2113,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
|
||||
WriteLog (lsERROR, Peer) << "We do not have the map our peer wants " << getIP ();
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2144,7 +2141,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
if (packet.ledgerhash ().size () != 32)
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
WriteLog (lsWARNING, Peer) << "Invalid request";
|
||||
return;
|
||||
}
|
||||
@@ -2201,7 +2197,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
else
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
WriteLog (lsWARNING, Peer) << "Can't figure out what ledger they want";
|
||||
return;
|
||||
}
|
||||
@@ -2209,7 +2204,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
if ((!ledger) || (packet.has_ledgerseq () && (packet.ledgerseq () != ledger->getLedgerSeq ())))
|
||||
{
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
|
||||
if (ShouldLog (lsWARNING, Peer))
|
||||
{
|
||||
@@ -2290,7 +2284,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Can't find map or empty request";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2304,7 +2297,6 @@ void PeerImp::recvGetLedger (protocol::TMGetLedger& packet, Application::ScopedL
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Request for invalid node: " << logMe;
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2366,7 +2358,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Ledger/TXset data with no nodes";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2383,7 +2374,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
{
|
||||
WriteLog (lsINFO, Peer) << "Unable to route TX/ledger data reply";
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge (LT_UnwantedData);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -2395,7 +2385,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "TX candidate reply with invalid hash size";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2415,7 +2404,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "LedgerData request with invalid node ID";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2428,7 +2416,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
if (san.isInvalid ())
|
||||
{
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge (LT_UnwantedData);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -2443,7 +2430,6 @@ void PeerImp::recvLedger (const boost::shared_ptr<protocol::TMLedgerData>& packe
|
||||
else
|
||||
{
|
||||
charge (Resource::feeUnwantedData);
|
||||
applyLoadCharge (LT_UnwantedData);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2589,33 +2575,6 @@ void PeerImp::sendGetPeers ()
|
||||
sendPacket (packet, true);
|
||||
}
|
||||
|
||||
void PeerImp::applyLoadCharge (LoadType loadType)
|
||||
{
|
||||
// IMPLEMENTATION IS INCOMPLETE
|
||||
|
||||
// VFALCO TODO This needs to completed before open sourcing.
|
||||
|
||||
if (getApp().getLoadManager ().applyLoadCharge (mLoad, loadType))
|
||||
{
|
||||
if (mCluster)
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "aLC: " << getDisplayName() << " load from cluster";
|
||||
}
|
||||
else if (getApp().getLoadManager ().shouldCutoff(mLoad))
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "aLC: " << getDisplayName() << " should cutoff";
|
||||
}
|
||||
else if (getApp().getLoadManager ().shouldWarn (mLoad))
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "aLC: " << getDisplayName() << " load warning";
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "aLC: " << getDisplayName() << " cannot figure out";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PeerImp::doProofOfWork (Job&, boost::weak_ptr <Peer> peer, ProofOfWork::pointer pow)
|
||||
{
|
||||
if (peer.expired ())
|
||||
@@ -2658,7 +2617,6 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "FetchPack hash size malformed";
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2671,7 +2629,6 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
|
||||
{
|
||||
WriteLog (lsINFO, Peer) << "Peer requests fetch pack for ledger we don't have: " << hash;
|
||||
charge (Resource::feeRequestNoReply);
|
||||
applyLoadCharge (LT_RequestNoReply);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2679,7 +2636,6 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
|
||||
{
|
||||
WriteLog (lsWARNING, Peer) << "Peer requests fetch pack from open ledger: " << hash;
|
||||
charge (Resource::feeInvalidRequest);
|
||||
applyLoadCharge (LT_InvalidRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2689,7 +2645,6 @@ void PeerImp::doFetchPack (const boost::shared_ptr<protocol::TMGetObjectByHash>&
|
||||
{
|
||||
WriteLog (lsINFO, Peer) << "Peer requests fetch pack for ledger whose predecessor we don't have: " << hash;
|
||||
charge (Resource::feeRequestNoReply);
|
||||
applyLoadCharge (LT_RequestNoReply);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2818,15 +2773,3 @@ void Peer::charge (boost::weak_ptr <Peer>& peer, Resource::Charge const& fee)
|
||||
if (p != nullptr)
|
||||
p->charge (fee);
|
||||
}
|
||||
|
||||
void Peer::applyLoadCharge (boost::weak_ptr <Peer>& peerToPunish,
|
||||
LoadType loadThatWasImposed)
|
||||
{
|
||||
Peer::pointer p = peerToPunish.lock ();
|
||||
|
||||
if (p != nullptr)
|
||||
{
|
||||
p->applyLoadCharge (loadThatWasImposed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,8 +76,6 @@ public:
|
||||
*/
|
||||
virtual void charge (Resource::Charge const& fee) = 0;
|
||||
static void charge (boost::weak_ptr <Peer>& peer, Resource::Charge const& fee);
|
||||
virtual void applyLoadCharge (LoadType) = 0;
|
||||
static void applyLoadCharge (boost::weak_ptr <Peer>& peerTOCharge, LoadType loadThatWasImposed);
|
||||
|
||||
virtual Json::Value getJson () = 0;
|
||||
|
||||
|
||||
@@ -208,7 +208,6 @@ public:
|
||||
PeerFinder::PeerID (peer->getNodePublic()) == id)
|
||||
{
|
||||
peer->charge (Resource::feeUnwantedData);
|
||||
peer->applyLoadCharge (LT_UnwantedData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -575,7 +575,7 @@ Json::Value RPCHandler::accountFromString (Ledger::ref lrLedger, RippleAddress&
|
||||
return Json::Value (Json::objectValue);
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doAccountCurrencies (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doAccountCurrencies (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger (params, lpLedger);
|
||||
@@ -641,7 +641,7 @@ Json::Value RPCHandler::doAccountCurrencies (Json::Value params, LoadType* loadT
|
||||
// ledger_hash : <ledger>
|
||||
// ledger_index : <ledger_index>
|
||||
// }
|
||||
Json::Value RPCHandler::doAccountInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doAccountInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger (params, lpLedger);
|
||||
@@ -682,13 +682,13 @@ Json::Value RPCHandler::doAccountInfo (Json::Value params, LoadType* loadType, A
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doBlackList (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doBlackList (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
masterLockHolder.unlock();
|
||||
if (params.isMember("threshold"))
|
||||
return getApp().getLoadManager().getBlackList(params["threshold"].asInt());
|
||||
return getApp().getResourceManager().getJson(params["threshold"].asInt());
|
||||
else
|
||||
return getApp().getLoadManager().getBlackList();
|
||||
return getApp().getResourceManager().getJson();
|
||||
}
|
||||
|
||||
// {
|
||||
@@ -696,7 +696,7 @@ Json::Value RPCHandler::doBlackList (Json::Value params, LoadType* loadType, App
|
||||
// port: <number>
|
||||
// }
|
||||
// XXX Might allow domain for manual connections.
|
||||
Json::Value RPCHandler::doConnect (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doConnect (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (getConfig ().RUN_STANDALONE)
|
||||
return "cannot connect in standalone mode";
|
||||
@@ -717,7 +717,7 @@ Json::Value RPCHandler::doConnect (Json::Value params, LoadType* loadType, Appli
|
||||
// {
|
||||
// key: <string>
|
||||
// }
|
||||
Json::Value RPCHandler::doDataDelete (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doDataDelete (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("key"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
@@ -743,7 +743,7 @@ Json::Value RPCHandler::doDataDelete (Json::Value params, LoadType* loadType, Ap
|
||||
// {
|
||||
// key: <string>
|
||||
// }
|
||||
Json::Value RPCHandler::doDataFetch (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doDataFetch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("key"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
@@ -767,7 +767,7 @@ Json::Value RPCHandler::doDataFetch (Json::Value params, LoadType* loadType, App
|
||||
// key: <string>
|
||||
// value: <string>
|
||||
// }
|
||||
Json::Value RPCHandler::doDataStore (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doDataStore (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("key")
|
||||
|| !params.isMember ("value"))
|
||||
@@ -828,7 +828,7 @@ Json::Value RPCHandler::doNicknameInfo (Json::Value params)
|
||||
// 'account_index' : <index> // optional
|
||||
// }
|
||||
// XXX This would be better if it took the ledger.
|
||||
Json::Value RPCHandler::doOwnerInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doOwnerInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("account") && !params.isMember ("ident"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
@@ -853,7 +853,7 @@ Json::Value RPCHandler::doOwnerInfo (Json::Value params, LoadType* loadType, App
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doPeers (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doPeers (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Json::Value jvResult (Json::objectValue);
|
||||
|
||||
@@ -864,12 +864,12 @@ Json::Value RPCHandler::doPeers (Json::Value, LoadType* loadType, Application::S
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doPing (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doPing (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
return Json::Value (Json::objectValue);
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doPrint (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doPrint (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
masterLockHolder.unlock ();
|
||||
|
||||
@@ -887,7 +887,7 @@ Json::Value RPCHandler::doPrint (Json::Value params, LoadType* loadType, Applica
|
||||
// issuer is the offering account
|
||||
// --> submit: 'submit|true|false': defaults to false
|
||||
// Prior to running allow each to have a credit line of what they will be getting from the other account.
|
||||
Json::Value RPCHandler::doProfile (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doProfile (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
/* need to fix now that sharedOfferCreate is gone
|
||||
int iArgs = params.size();
|
||||
@@ -979,7 +979,7 @@ Json::Value RPCHandler::doProfile (Json::Value params, LoadType* loadType, Appli
|
||||
// difficulty: <number> // optional
|
||||
// secret: <secret> // optional
|
||||
// }
|
||||
Json::Value RPCHandler::doProofCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doProofCreate (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
masterLockHolder.unlock ();
|
||||
// XXX: Add ability to create proof with arbitrary time
|
||||
@@ -1024,7 +1024,7 @@ Json::Value RPCHandler::doProofCreate (Json::Value params, LoadType* loadType, A
|
||||
// {
|
||||
// token: <token>
|
||||
// }
|
||||
Json::Value RPCHandler::doProofSolve (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doProofSolve (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
masterLockHolder.unlock ();
|
||||
|
||||
@@ -1054,7 +1054,7 @@ Json::Value RPCHandler::doProofSolve (Json::Value params, LoadType* loadType, Ap
|
||||
// difficulty: <number> // optional
|
||||
// secret: <secret> // optional
|
||||
// }
|
||||
Json::Value RPCHandler::doProofVerify (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doProofVerify (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
masterLockHolder.unlock ();
|
||||
// XXX Add ability to check proof against arbitrary time
|
||||
@@ -1124,7 +1124,7 @@ Json::Value RPCHandler::doProofVerify (Json::Value params, LoadType* loadType, A
|
||||
// ledger_hash : <ledger>
|
||||
// ledger_index : <ledger_index>
|
||||
// }
|
||||
Json::Value RPCHandler::doAccountLines (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doAccountLines (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger (params, lpLedger);
|
||||
@@ -1215,6 +1215,7 @@ Json::Value RPCHandler::doAccountLines (Json::Value params, LoadType* loadType,
|
||||
}
|
||||
}
|
||||
|
||||
loadType = Resource::feeMediumBurdenRPC;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1242,7 +1243,7 @@ static void offerAdder (Json::Value& jvLines, SLE::ref offer)
|
||||
// ledger_hash : <ledger>
|
||||
// ledger_index : <ledger_index>
|
||||
// }
|
||||
Json::Value RPCHandler::doAccountOffers (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doAccountOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger (params, lpLedger);
|
||||
@@ -1287,6 +1288,7 @@ Json::Value RPCHandler::doAccountOffers (Json::Value params, LoadType* loadType,
|
||||
|
||||
if (!bUnlocked)
|
||||
masterLockHolder.unlock ();
|
||||
loadType = Resource::feeMediumBurdenRPC;
|
||||
|
||||
return jvResult;
|
||||
}
|
||||
@@ -1301,7 +1303,7 @@ Json::Value RPCHandler::doAccountOffers (Json::Value params, LoadType* loadType,
|
||||
// "limit" : integer, // Optional.
|
||||
// "proof" : boolean // Defaults to false.
|
||||
// }
|
||||
Json::Value RPCHandler::doBookOffers (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doBookOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (getApp().getJobQueue ().getJobCountGE (jtCLIENT) > 200)
|
||||
{
|
||||
@@ -1394,6 +1396,7 @@ Json::Value RPCHandler::doBookOffers (Json::Value params, LoadType* loadType, Ap
|
||||
const Json::Value jvMarker = params.isMember ("marker") ? params["marker"] : Json::Value (Json::nullValue);
|
||||
|
||||
mNetOps->getBookPage (lpLedger, uTakerPaysCurrencyID, uTakerPaysIssuerID, uTakerGetsCurrencyID, uTakerGetsIssuerID, raTakerID.getAccountID (), bProof, iLimit, jvMarker, jvResult);
|
||||
loadType = Resource::feeMediumBurdenRPC;
|
||||
|
||||
return jvResult;
|
||||
}
|
||||
@@ -1402,7 +1405,7 @@ Json::Value RPCHandler::doBookOffers (Json::Value params, LoadType* loadType, Ap
|
||||
// {
|
||||
// random: <uint256>
|
||||
// }
|
||||
Json::Value RPCHandler::doRandom (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doRandom (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
masterLockHolder.unlock ();
|
||||
uint256 uRandom;
|
||||
@@ -1423,7 +1426,7 @@ Json::Value RPCHandler::doRandom (Json::Value params, LoadType* loadType, Applic
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doPathFind (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doPathFind (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Ledger::pointer lpLedger = mNetOps->getClosedLedger();
|
||||
masterLockHolder.unlock();
|
||||
@@ -1438,6 +1441,7 @@ Json::Value RPCHandler::doPathFind (Json::Value params, LoadType* loadType, Appl
|
||||
|
||||
if (sSubCommand == "create")
|
||||
{
|
||||
loadType = Resource::feeHighBurdenRPC;
|
||||
mInfoSub->clearPathRequest ();
|
||||
PathRequest::pointer request = boost::make_shared<PathRequest> (mInfoSub);
|
||||
Json::Value result = request->doCreate (lpLedger, params);
|
||||
@@ -1481,7 +1485,7 @@ Json::Value RPCHandler::doPathFind (Json::Value params, LoadType* loadType, Appl
|
||||
// - Allows clients to verify path exists.
|
||||
// - Return canonicalized path.
|
||||
// - From a trusted server, allows clients to use path without manipulation.
|
||||
Json::Value RPCHandler::doRipplePathFind (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doRipplePathFind (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
int jc = getApp().getJobQueue ().getJobCountGE (jtCLIENT);
|
||||
|
||||
@@ -1490,6 +1494,7 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, LoadType* loadType
|
||||
WriteLog (lsDEBUG, RPCHandler) << "Too busy for RPF: " << jc;
|
||||
return rpcError (rpcTOO_BUSY);
|
||||
}
|
||||
loadType = Resource::feeHighBurdenRPC;
|
||||
|
||||
RippleAddress raSrc;
|
||||
RippleAddress raDst;
|
||||
@@ -1562,7 +1567,7 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, LoadType* loadType
|
||||
}
|
||||
}
|
||||
|
||||
*loadType = LT_RPCBurden;
|
||||
loadType = Resource::feeHighBurdenRPC;
|
||||
Ledger::pointer lSnapShot = boost::make_shared<Ledger> (boost::ref (*lpLedger), false);
|
||||
|
||||
masterLockHolder.unlock (); // As long as we have a locked copy of the ledger, we can unlock.
|
||||
@@ -1730,9 +1735,9 @@ Json::Value RPCHandler::doRipplePathFind (Json::Value params, LoadType* loadType
|
||||
// tx_json: <object>,
|
||||
// secret: <secret>
|
||||
// }
|
||||
Json::Value RPCHandler::doSign (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doSign (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
*loadType = LT_RPCBurden;
|
||||
loadType = Resource::feeHighBurdenRPC;
|
||||
bool bFailHard = params.isMember ("fail_hard") && params["fail_hard"].asBool ();
|
||||
return transactionSign (params, false, bFailHard, masterLockHolder);
|
||||
}
|
||||
@@ -1741,8 +1746,10 @@ Json::Value RPCHandler::doSign (Json::Value params, LoadType* loadType, Applicat
|
||||
// tx_json: <object>,
|
||||
// secret: <secret>
|
||||
// }
|
||||
Json::Value RPCHandler::doSubmit (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doSubmit (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
loadType = Resource::feeMediumBurdenRPC;
|
||||
|
||||
if (!params.isMember ("tx_blob"))
|
||||
{
|
||||
bool bFailHard = params.isMember ("fail_hard") && params["fail_hard"].asBool ();
|
||||
@@ -1758,7 +1765,6 @@ Json::Value RPCHandler::doSubmit (Json::Value params, LoadType* loadType, Applic
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
}
|
||||
|
||||
*loadType = LT_RPCBurden;
|
||||
|
||||
Serializer sTrans (vucBlob);
|
||||
SerializerIterator sitTrans (sTrans);
|
||||
@@ -1834,7 +1840,7 @@ Json::Value RPCHandler::doSubmit (Json::Value params, LoadType* loadType, Applic
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doConsensusInfo (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doConsensusInfo (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Json::Value ret (Json::objectValue);
|
||||
|
||||
@@ -1843,7 +1849,7 @@ Json::Value RPCHandler::doConsensusInfo (Json::Value, LoadType* loadType, Applic
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doFetchInfo (Json::Value jvParams, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doFetchInfo (Json::Value jvParams, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
masterLockHolder.unlock ();
|
||||
|
||||
@@ -1860,7 +1866,7 @@ Json::Value RPCHandler::doFetchInfo (Json::Value jvParams, LoadType* loadType, A
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doServerInfo (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doServerInfo (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Json::Value ret (Json::objectValue);
|
||||
|
||||
@@ -1869,7 +1875,7 @@ Json::Value RPCHandler::doServerInfo (Json::Value, LoadType* loadType, Applicati
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doServerState (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doServerState (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Json::Value ret (Json::objectValue);
|
||||
|
||||
@@ -1881,8 +1887,9 @@ Json::Value RPCHandler::doServerState (Json::Value, LoadType* loadType, Applicat
|
||||
// {
|
||||
// start: <index>
|
||||
// }
|
||||
Json::Value RPCHandler::doTxHistory (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doTxHistory (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
loadType = Resource::feeMediumBurdenRPC;
|
||||
masterLockHolder.unlock ();
|
||||
|
||||
if (!params.isMember ("start"))
|
||||
@@ -1922,7 +1929,7 @@ Json::Value RPCHandler::doTxHistory (Json::Value params, LoadType* loadType, App
|
||||
// {
|
||||
// transaction: <hex>
|
||||
// }
|
||||
Json::Value RPCHandler::doTx (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doTx (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
masterLockHolder.unlock ();
|
||||
|
||||
@@ -1990,7 +1997,7 @@ Json::Value RPCHandler::doTx (Json::Value params, LoadType* loadType, Applicatio
|
||||
return rpcError (rpcNOT_IMPL);
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doLedgerClosed (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doLedgerClosed (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Json::Value jvResult;
|
||||
|
||||
@@ -2003,7 +2010,7 @@ Json::Value RPCHandler::doLedgerClosed (Json::Value, LoadType* loadType, Applica
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doLedgerCurrent (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doLedgerCurrent (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Json::Value jvResult;
|
||||
|
||||
@@ -2017,7 +2024,7 @@ Json::Value RPCHandler::doLedgerCurrent (Json::Value, LoadType* loadType, Applic
|
||||
// ledger: 'current' | 'closed' | <uint256> | <number>, // optional
|
||||
// full: true | false // optional, defaults to false.
|
||||
// }
|
||||
Json::Value RPCHandler::doLedger (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doLedger (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("ledger") && !params.isMember ("ledger_hash") && !params.isMember ("ledger_index"))
|
||||
{
|
||||
@@ -2050,10 +2057,14 @@ Json::Value RPCHandler::doLedger (Json::Value params, LoadType* loadType, Applic
|
||||
| (bTransactions ? LEDGER_JSON_DUMP_TXRP : 0)
|
||||
| (bAccounts ? LEDGER_JSON_DUMP_STATE : 0);
|
||||
|
||||
if ((bFull || bAccounts) && getApp().getFeeTrack().isLoadedLocal() && (mRole != Config::ADMIN))
|
||||
if (bFull || bAccounts)
|
||||
{
|
||||
WriteLog (lsDEBUG, Peer) << "Too busy to give full ledger";
|
||||
return rpcError(rpcTOO_BUSY);
|
||||
if (getApp().getFeeTrack().isLoadedLocal() && (mRole != Config::ADMIN))
|
||||
{
|
||||
WriteLog (lsDEBUG, Peer) << "Too busy to give full ledger";
|
||||
return rpcError(rpcTOO_BUSY);
|
||||
}
|
||||
loadType = Resource::feeHighBurdenRPC;
|
||||
}
|
||||
|
||||
|
||||
@@ -2064,7 +2075,7 @@ Json::Value RPCHandler::doLedger (Json::Value params, LoadType* loadType, Applic
|
||||
}
|
||||
|
||||
// Temporary switching code until the old account_tx is removed
|
||||
Json::Value RPCHandler::doAccountTxSwitch (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doAccountTxSwitch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (params.isMember("offset") || params.isMember("count") || params.isMember("descending") ||
|
||||
params.isMember("ledger_max") || params.isMember("ledger_min"))
|
||||
@@ -2082,7 +2093,7 @@ Json::Value RPCHandler::doAccountTxSwitch (Json::Value params, LoadType* loadTyp
|
||||
// offset: integer, // optional, defaults to 0
|
||||
// limit: integer // optional
|
||||
// }
|
||||
Json::Value RPCHandler::doAccountTxOld (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doAccountTxOld (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
RippleAddress raAccount;
|
||||
uint32 offset = params.isMember ("offset") ? params["offset"].asUInt () : 0;
|
||||
@@ -2102,6 +2113,8 @@ Json::Value RPCHandler::doAccountTxOld (Json::Value params, LoadType* loadType,
|
||||
if (!raAccount.setAccountID (params["account"].asString ()))
|
||||
return rpcError (rpcACT_MALFORMED);
|
||||
|
||||
loadType = Resource::feeHighBurdenRPC;
|
||||
|
||||
// DEPRECATED
|
||||
if (params.isMember ("ledger_min"))
|
||||
{
|
||||
@@ -2231,7 +2244,7 @@ Json::Value RPCHandler::doAccountTxOld (Json::Value params, LoadType* loadType,
|
||||
// limit: integer, // optional
|
||||
// marker: opaque // optional, resume previous query
|
||||
// }
|
||||
Json::Value RPCHandler::doAccountTx (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doAccountTx (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
RippleAddress raAccount;
|
||||
int limit = params.isMember ("limit") ? params["limit"].asUInt () : -1;
|
||||
@@ -2255,6 +2268,8 @@ Json::Value RPCHandler::doAccountTx (Json::Value params, LoadType* loadType, App
|
||||
if (!raAccount.setAccountID (params["account"].asString ()))
|
||||
return rpcError (rpcACT_MALFORMED);
|
||||
|
||||
loadType = Resource::feeMediumBurdenRPC;
|
||||
|
||||
if (params.isMember ("ledger_index_min") || params.isMember ("ledger_index_max"))
|
||||
{
|
||||
int64 iLedgerMin = params.isMember ("ledger_index_min") ? params["ledger_index_min"].asInt () : -1;
|
||||
@@ -2364,7 +2379,7 @@ Json::Value RPCHandler::doAccountTx (Json::Value params, LoadType* loadType, App
|
||||
// }
|
||||
//
|
||||
// This command requires Config::ADMIN access because it makes no sense to ask an untrusted server for this.
|
||||
Json::Value RPCHandler::doValidationCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doValidationCreate (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
RippleAddress raSeed;
|
||||
Json::Value obj (Json::objectValue);
|
||||
@@ -2390,7 +2405,7 @@ Json::Value RPCHandler::doValidationCreate (Json::Value params, LoadType* loadTy
|
||||
// {
|
||||
// secret: <string>
|
||||
// }
|
||||
Json::Value RPCHandler::doValidationSeed (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doValidationSeed (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Json::Value obj (Json::objectValue);
|
||||
|
||||
@@ -2461,7 +2476,7 @@ Json::Value RPCHandler::accounts (Ledger::ref lrLedger, const RippleAddress& naM
|
||||
// ledger_hash : <ledger>
|
||||
// ledger_index : <ledger_index>
|
||||
// }
|
||||
Json::Value RPCHandler::doWalletAccounts (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doWalletAccounts (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger (params, lpLedger);
|
||||
@@ -2504,7 +2519,7 @@ Json::Value RPCHandler::doWalletAccounts (Json::Value params, LoadType* loadType
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doLogRotate (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doLogRotate (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
return LogSink::get()->rotateLog ();
|
||||
}
|
||||
@@ -2512,7 +2527,7 @@ Json::Value RPCHandler::doLogRotate (Json::Value, LoadType* loadType, Applicatio
|
||||
// {
|
||||
// passphrase: <string>
|
||||
// }
|
||||
Json::Value RPCHandler::doWalletPropose (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doWalletPropose (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
masterLockHolder.unlock ();
|
||||
|
||||
@@ -2544,7 +2559,7 @@ Json::Value RPCHandler::doWalletPropose (Json::Value params, LoadType* loadType,
|
||||
// {
|
||||
// secret: <string>
|
||||
// }
|
||||
Json::Value RPCHandler::doWalletSeed (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doWalletSeed (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
RippleAddress raSeed;
|
||||
bool bSecret = params.isMember ("secret");
|
||||
@@ -2583,7 +2598,7 @@ Json::Value RPCHandler::doWalletSeed (Json::Value params, LoadType* loadType, Ap
|
||||
// username: <string>,
|
||||
// password: <string>
|
||||
// }
|
||||
Json::Value RPCHandler::doLogin (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doLogin (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("username")
|
||||
|| !params.isMember ("password"))
|
||||
@@ -2621,7 +2636,7 @@ static void textTime (std::string& text, int& seconds, const char* unitName, int
|
||||
text += "s";
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doFeature (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh)
|
||||
Json::Value RPCHandler::doFeature (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh)
|
||||
{
|
||||
if (!params.isMember ("feature"))
|
||||
{
|
||||
@@ -2650,7 +2665,7 @@ Json::Value RPCHandler::doFeature (Json::Value params, LoadType* loadType, Appli
|
||||
// {
|
||||
// min_count: <number> // optional, defaults to 10
|
||||
// }
|
||||
Json::Value RPCHandler::doGetCounts (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doGetCounts (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
int minCount = 10;
|
||||
|
||||
@@ -2702,7 +2717,7 @@ Json::Value RPCHandler::doGetCounts (Json::Value params, LoadType* loadType, App
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doLogLevel (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doLogLevel (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
// log_level
|
||||
if (!params.isMember ("severity"))
|
||||
@@ -2755,7 +2770,7 @@ Json::Value RPCHandler::doLogLevel (Json::Value params, LoadType* loadType, Appl
|
||||
// node: <domain>|<node_public>,
|
||||
// comment: <comment> // optional
|
||||
// }
|
||||
Json::Value RPCHandler::doUnlAdd (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doUnlAdd (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
std::string strNode = params.isMember ("node") ? params["node"].asString () : "";
|
||||
std::string strComment = params.isMember ("comment") ? params["comment"].asString () : "";
|
||||
@@ -2779,7 +2794,7 @@ Json::Value RPCHandler::doUnlAdd (Json::Value params, LoadType* loadType, Applic
|
||||
// {
|
||||
// node: <domain>|<public_key>
|
||||
// }
|
||||
Json::Value RPCHandler::doUnlDelete (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doUnlDelete (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("node"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
@@ -2802,7 +2817,7 @@ Json::Value RPCHandler::doUnlDelete (Json::Value params, LoadType* loadType, App
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doUnlList (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doUnlList (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Json::Value obj (Json::objectValue);
|
||||
|
||||
@@ -2812,7 +2827,7 @@ Json::Value RPCHandler::doUnlList (Json::Value, LoadType* loadType, Application:
|
||||
}
|
||||
|
||||
// Populate the UNL from a local validators.txt file.
|
||||
Json::Value RPCHandler::doUnlLoad (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doUnlLoad (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (getConfig ().VALIDATORS_FILE.empty () || !getApp().getUNL ().nodeLoad (getConfig ().VALIDATORS_FILE))
|
||||
{
|
||||
@@ -2824,7 +2839,7 @@ Json::Value RPCHandler::doUnlLoad (Json::Value, LoadType* loadType, Application:
|
||||
|
||||
|
||||
// Populate the UNL from ripple.com's validators.txt file.
|
||||
Json::Value RPCHandler::doUnlNetwork (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doUnlNetwork (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
getApp().getUNL ().nodeNetwork ();
|
||||
|
||||
@@ -2832,7 +2847,7 @@ Json::Value RPCHandler::doUnlNetwork (Json::Value params, LoadType* loadType, Ap
|
||||
}
|
||||
|
||||
// unl_reset
|
||||
Json::Value RPCHandler::doUnlReset (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doUnlReset (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
getApp().getUNL ().nodeReset ();
|
||||
|
||||
@@ -2840,14 +2855,14 @@ Json::Value RPCHandler::doUnlReset (Json::Value params, LoadType* loadType, Appl
|
||||
}
|
||||
|
||||
// unl_score
|
||||
Json::Value RPCHandler::doUnlScore (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doUnlScore (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
getApp().getUNL ().nodeScore ();
|
||||
|
||||
return "scoring requested";
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doSMS (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doSMS (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
if (!params.isMember ("text"))
|
||||
return rpcError (rpcINVALID_PARAMS);
|
||||
@@ -2856,14 +2871,14 @@ Json::Value RPCHandler::doSMS (Json::Value params, LoadType* loadType, Applicati
|
||||
|
||||
return "sms dispatched";
|
||||
}
|
||||
Json::Value RPCHandler::doStop (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doStop (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
getApp().signalStop ();
|
||||
|
||||
return SYSTEM_NAME " server stopping";
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doLedgerAccept (Json::Value, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doLedgerAccept (Json::Value, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Json::Value jvResult;
|
||||
|
||||
@@ -2886,7 +2901,7 @@ Json::Value RPCHandler::doLedgerAccept (Json::Value, LoadType* loadType, Applica
|
||||
// ledger_index : <ledger_index>
|
||||
// }
|
||||
// XXX In this case, not specify either ledger does not mean ledger current. It means any ledger.
|
||||
Json::Value RPCHandler::doTransactionEntry (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doTransactionEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger (params, lpLedger);
|
||||
@@ -3059,7 +3074,7 @@ Json::Value RPCHandler::lookupLedger (Json::Value params, Ledger::pointer& lpLed
|
||||
// ledger_index : <ledger_index>
|
||||
// ...
|
||||
// }
|
||||
Json::Value RPCHandler::doLedgerEntry (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doLedgerEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger (params, lpLedger);
|
||||
@@ -3275,7 +3290,7 @@ Json::Value RPCHandler::doLedgerEntry (Json::Value params, LoadType* loadType, A
|
||||
// ledger_hash : <ledger>
|
||||
// ledger_index : <ledger_index>
|
||||
// }
|
||||
Json::Value RPCHandler::doLedgerHeader (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doLedgerHeader (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
Ledger::pointer lpLedger;
|
||||
Json::Value jvResult = lookupLedger (params, lpLedger);
|
||||
@@ -3317,7 +3332,7 @@ boost::unordered_set<RippleAddress> RPCHandler::parseAccountIds (const Json::Val
|
||||
return usnaResult;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doSubscribe (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doSubscribe (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
InfoSub::pointer ispSub;
|
||||
Json::Value jvResult (Json::objectValue);
|
||||
@@ -3583,6 +3598,7 @@ Json::Value RPCHandler::doSubscribe (Json::Value params, LoadType* loadType, App
|
||||
|
||||
if (bSnapshot)
|
||||
{
|
||||
loadType = Resource::feeMediumBurdenRPC;
|
||||
Ledger::pointer lpLedger = getApp().getLedgerMaster ().getPublishedLedger ();
|
||||
if (lpLedger)
|
||||
{
|
||||
@@ -3614,7 +3630,7 @@ Json::Value RPCHandler::doSubscribe (Json::Value params, LoadType* loadType, App
|
||||
}
|
||||
|
||||
// FIXME: This leaks RPCSub objects for JSON-RPC. Shouldn't matter for anyone sane.
|
||||
Json::Value RPCHandler::doUnsubscribe (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doUnsubscribe (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
InfoSub::pointer ispSub;
|
||||
Json::Value jvResult (Json::objectValue);
|
||||
@@ -3804,7 +3820,7 @@ Json::Value RPCHandler::doUnsubscribe (Json::Value params, LoadType* loadType, A
|
||||
//
|
||||
// JSON-RPC provides a method and an array of params. JSON-RPC is used as a transport for a command and a request object. The
|
||||
// command is the method. The request object is supplied as the first element of the params.
|
||||
Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value const& jvParams, int iRole, LoadType* loadType)
|
||||
Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value const& jvParams, int iRole, Resource::Charge& loadType)
|
||||
{
|
||||
WriteLog (lsTRACE, RPCHandler) << "doRpcCommand:" << strMethod << ":" << jvParams;
|
||||
|
||||
@@ -3845,7 +3861,7 @@ Json::Value RPCHandler::doRpcCommand (const std::string& strMethod, Json::Value
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doInternal (Json::Value params, LoadType* loadType, Application::ScopedLockType& masterLockHolder)
|
||||
Json::Value RPCHandler::doInternal (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& masterLockHolder)
|
||||
{
|
||||
// Used for debug or special-purpose RPC commands
|
||||
if (!params.isMember ("internal_command"))
|
||||
@@ -3854,7 +3870,7 @@ Json::Value RPCHandler::doInternal (Json::Value params, LoadType* loadType, Appl
|
||||
return RPCInternalHandler::runHandler (params["internal_command"].asString (), params["params"]);
|
||||
}
|
||||
|
||||
Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadType* loadType)
|
||||
Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, Resource::Charge& loadType)
|
||||
{
|
||||
if (iRole != Config::ADMIN)
|
||||
{
|
||||
@@ -4016,8 +4032,8 @@ Json::Value RPCHandler::doCommand (const Json::Value& params, int iRole, LoadTyp
|
||||
{
|
||||
WriteLog (lsINFO, RPCHandler) << "Caught throw: " << e.what ();
|
||||
|
||||
if (*loadType == LT_RPCReference)
|
||||
*loadType = LT_RPCException;
|
||||
if (loadType == Resource::feeReferenceRPC)
|
||||
loadType = Resource::feeExceptionRPC;
|
||||
|
||||
return rpcError (rpcINTERNAL);
|
||||
}
|
||||
|
||||
@@ -37,14 +37,14 @@ public:
|
||||
|
||||
RPCHandler (NetworkOPs* netOps, InfoSub::pointer infoSub);
|
||||
|
||||
Json::Value doCommand (const Json::Value& jvRequest, int role, LoadType* loadType);
|
||||
Json::Value doCommand (const Json::Value& jvRequest, int role, Resource::Charge& loadType);
|
||||
|
||||
Json::Value doRpcCommand (const std::string& strCommand, Json::Value const& jvParams, int iRole, LoadType* loadType);
|
||||
Json::Value doRpcCommand (const std::string& strCommand, Json::Value const& jvParams, int iRole, Resource::Charge& loadType);
|
||||
|
||||
private:
|
||||
typedef Json::Value (RPCHandler::*doFuncPtr) (
|
||||
Json::Value params,
|
||||
LoadType* loadType,
|
||||
Resource::Charge& loadType,
|
||||
Application::ScopedLockType& MasterLockHolder);
|
||||
|
||||
// VFALCO TODO Document these and give the enumeration a label.
|
||||
@@ -94,76 +94,76 @@ private:
|
||||
const int iIndex,
|
||||
const bool bStrict);
|
||||
|
||||
Json::Value doAccountCurrencies (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountLines (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountOffers (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountTx (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountTxSwitch (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountTxOld (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doBookOffers (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doBlackList (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doConnect (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doConsensusInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doFeature (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doFetchInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doGetCounts (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doInternal (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedger (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedgerAccept (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedgerClosed (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedgerCurrent (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedgerEntry (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedgerHeader (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLogLevel (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLogRotate (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doNicknameInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doOwnerInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doPathFind (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doPeers (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doPing (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doPrint (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doProfile (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doProofCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doProofSolve (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doProofVerify (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doRandom (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doRipplePathFind (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doSMS (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doServerInfo (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); // for humans
|
||||
Json::Value doServerState (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh); // for machines
|
||||
Json::Value doSessionClose (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doSessionOpen (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doSign (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doStop (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doSubmit (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doSubscribe (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doTransactionEntry (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doTx (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doTxHistory (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlAdd (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlDelete (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlFetch (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlList (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlLoad (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlNetwork (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlReset (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlScore (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnsubscribe (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doValidationCreate (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doValidationSeed (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletAccounts (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletLock (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletPropose (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletSeed (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletUnlock (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletVerify (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountCurrencies (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountLines (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountTx (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountTxSwitch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doAccountTxOld (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doBookOffers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doBlackList (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doConnect (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doConsensusInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doFeature (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doFetchInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doGetCounts (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doInternal (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedger (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedgerAccept (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedgerClosed (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedgerCurrent (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedgerEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLedgerHeader (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLogLevel (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLogRotate (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doNicknameInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doOwnerInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doPathFind (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doPeers (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doPing (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doPrint (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doProfile (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doProofCreate (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doProofSolve (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doProofVerify (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doRandom (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doRipplePathFind (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doSMS (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doServerInfo (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh); // for humans
|
||||
Json::Value doServerState (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh); // for machines
|
||||
Json::Value doSessionClose (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doSessionOpen (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doSign (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doStop (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doSubmit (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doSubscribe (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doTransactionEntry (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doTx (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doTxHistory (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlAdd (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlDelete (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlFetch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlList (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlLoad (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlNetwork (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlReset (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnlScore (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doUnsubscribe (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doValidationCreate (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doValidationSeed (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletAccounts (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletLock (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletPropose (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletSeed (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletUnlock (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doWalletVerify (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
|
||||
#if ENABLE_INSECURE
|
||||
Json::Value doDataDelete (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doDataFetch (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doDataStore (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLogin (Json::Value params, LoadType* loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doDataDelete (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doDataFetch (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doDataStore (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
Json::Value doLogin (Json::Value params, Resource::Charge& loadType, Application::ScopedLockType& mlh);
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
@@ -18,8 +18,9 @@
|
||||
//==============================================================================
|
||||
|
||||
|
||||
RPCServerHandler::RPCServerHandler (NetworkOPs& networkOPs)
|
||||
RPCServerHandler::RPCServerHandler (NetworkOPs& networkOPs, Resource::Manager& resourceManager)
|
||||
: m_networkOPs (networkOPs)
|
||||
, m_resourceManager (resourceManager)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -52,6 +53,16 @@ std::string RPCServerHandler::processRequest (std::string const& request, std::s
|
||||
|
||||
Config::Role const role (getConfig ().getAdminRole (jvRequest, remoteAddress));
|
||||
|
||||
Resource::Consumer usage;
|
||||
|
||||
if (role == Config::ADMIN)
|
||||
usage = m_resourceManager.newAdminEndpoint (remoteAddress);
|
||||
else
|
||||
usage = m_resourceManager.newInboundEndpoint (IPAddress::from_string (remoteAddress));
|
||||
|
||||
if (usage.disconnect ())
|
||||
return createResponse (503, "Server is overloaded");
|
||||
|
||||
// Parse id now so errors from here on will have the id
|
||||
//
|
||||
// VFALCO NOTE Except that "id" isn't included in the following errors...
|
||||
@@ -107,10 +118,11 @@ std::string RPCServerHandler::processRequest (std::string const& request, std::s
|
||||
|
||||
RPCHandler rpcHandler (&m_networkOPs);
|
||||
|
||||
LoadType loadType = LT_RPCReference;
|
||||
Resource::Charge loadType = Resource::feeReferenceRPC;
|
||||
|
||||
Json::Value const result = rpcHandler.doRpcCommand (strMethod, params, role, &loadType);
|
||||
// VFALCO NOTE We discard loadType since there is no endpoint to punish
|
||||
Json::Value const result = rpcHandler.doRpcCommand (strMethod, params, role, loadType);
|
||||
|
||||
usage.charge (loadType);
|
||||
|
||||
WriteLog (lsDEBUG, RPCServer) << "Reply: " << result;
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class NetworkOPs;
|
||||
class RPCServerHandler : public RPCServer::Handler
|
||||
{
|
||||
public:
|
||||
explicit RPCServerHandler (NetworkOPs& networkOPs);
|
||||
explicit RPCServerHandler (NetworkOPs& networkOPs, Resource::Manager& resourceManager);
|
||||
|
||||
std::string createResponse (int statusCode, std::string const& description);
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
|
||||
private:
|
||||
NetworkOPs& m_networkOPs;
|
||||
Resource::Manager& m_resourceManager;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,35 +17,27 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
SETUP_LOGN (WSConnection, "WSConnection")
|
||||
|
||||
static std::string trimIP(const std::string& ip)
|
||||
{ // Make sure there's no port
|
||||
size_t pos = ip.find(':');
|
||||
return (pos == std::string::npos) ? ip : ip.substr(0, pos - 1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
WSConnection::WSConnection (Resource::Manager& resourceManager,
|
||||
Resource::Consumer usage, InfoSub::Source& source, bool isPublic,
|
||||
std::string const& remoteIP, boost::asio::io_service& io_service)
|
||||
: InfoSub (source)
|
||||
IPAddress const& remoteAddress, boost::asio::io_service& io_service)
|
||||
: InfoSub (source, usage)
|
||||
, m_resourceManager (resourceManager)
|
||||
, m_usage (usage)
|
||||
, m_isPublic (isPublic)
|
||||
, m_remoteIP (remoteIP)
|
||||
, m_remoteAddress (remoteAddress)
|
||||
, m_receiveQueueMutex (this, "WSConnection", __FILE__, __LINE__)
|
||||
, m_netOPs (getApp ().getOPs ())
|
||||
, m_loadSource (m_remoteIP, trimIP(m_remoteIP))
|
||||
, m_pingTimer (io_service)
|
||||
, m_sentPing (false)
|
||||
, m_receiveQueueRunning (false)
|
||||
, m_isDead (false)
|
||||
, m_io_service (io_service)
|
||||
{
|
||||
WriteLog (lsDEBUG, WSConnection) << "Websocket connection from " << m_remoteIP;
|
||||
WriteLog (lsDEBUG, WSConnection) <<
|
||||
"Websocket connection from " << remoteAddress;
|
||||
}
|
||||
|
||||
WSConnection::~WSConnection ()
|
||||
@@ -113,19 +105,11 @@ void WSConnection::returnMessage (message_ptr ptr)
|
||||
|
||||
Json::Value WSConnection::invokeCommand (Json::Value& jvRequest)
|
||||
{
|
||||
#if RIPPLE_USE_RESOURCE_MANAGER
|
||||
if (m_usage.disconnect ())
|
||||
if (getConsumer().disconnect ())
|
||||
{
|
||||
disconnect ();
|
||||
return rpcError (rpcSLOW_DOWN);
|
||||
}
|
||||
#else
|
||||
if (getApp().getLoadManager ().shouldCutoff (m_loadSource))
|
||||
{
|
||||
disconnect ();
|
||||
return rpcError (rpcSLOW_DOWN);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Requests without "command" are invalid.
|
||||
//
|
||||
@@ -143,22 +127,19 @@ Json::Value WSConnection::invokeCommand (Json::Value& jvRequest)
|
||||
jvResult["id"] = jvRequest["id"];
|
||||
}
|
||||
|
||||
#if RIPPLE_USE_RESOURCE_MANAGER
|
||||
m_usage.charge (Resource::feeInvalidRPC);
|
||||
#else
|
||||
getApp().getLoadManager ().applyLoadCharge (m_loadSource, LT_RPCInvalid);
|
||||
#endif
|
||||
getConsumer().charge (Resource::feeInvalidRPC);
|
||||
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
LoadType loadType = LT_RPCReference;
|
||||
Resource::Charge loadType = Resource::feeReferenceRPC;
|
||||
RPCHandler mRPCHandler (&this->m_netOPs, boost::dynamic_pointer_cast<InfoSub> (this->shared_from_this ()));
|
||||
Json::Value jvResult (Json::objectValue);
|
||||
|
||||
Config::Role const role = m_isPublic
|
||||
? Config::GUEST // Don't check on the public interface.
|
||||
: getConfig ().getAdminRole (jvRequest, m_remoteIP);
|
||||
: getConfig ().getAdminRole (
|
||||
jvRequest, m_remoteAddress.withPort(0).to_string());
|
||||
|
||||
if (Config::FORBID == role)
|
||||
{
|
||||
@@ -166,24 +147,14 @@ Json::Value WSConnection::invokeCommand (Json::Value& jvRequest)
|
||||
}
|
||||
else
|
||||
{
|
||||
jvResult["result"] = mRPCHandler.doCommand (jvRequest, role, &loadType);
|
||||
jvResult["result"] = mRPCHandler.doCommand (jvRequest, role, loadType);
|
||||
}
|
||||
|
||||
#if RIPPLE_USE_RESOURCE_MANAGER
|
||||
m_usage.charge (Resource::legacyFee (loadType));
|
||||
if (m_usage.warn ())
|
||||
getConsumer().charge (loadType);
|
||||
if (getConsumer().warn ())
|
||||
{
|
||||
jvResult["warning"] = "load";
|
||||
}
|
||||
#else
|
||||
// Debit/credit the load and see if we should include a warning.
|
||||
//
|
||||
if (getApp().getLoadManager ().applyLoadCharge (m_loadSource, loadType) &&
|
||||
getApp().getLoadManager ().shouldWarn (m_loadSource))
|
||||
{
|
||||
jvResult["warning"] = "load";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Currently we will simply unwrap errors returned by the RPC
|
||||
// API, in the future maybe we can make the responses
|
||||
|
||||
@@ -39,7 +39,7 @@ protected:
|
||||
|
||||
WSConnection (Resource::Manager& resourceManager,
|
||||
Resource::Consumer usage, InfoSub::Source& source, bool isPublic,
|
||||
std::string const& remoteIP, boost::asio::io_service& io_service);
|
||||
IPAddress const& remoteAddress, boost::asio::io_service& io_service);
|
||||
|
||||
virtual ~WSConnection ();
|
||||
|
||||
@@ -57,11 +57,10 @@ protected:
|
||||
Resource::Manager& m_resourceManager;
|
||||
Resource::Consumer m_usage;
|
||||
bool const m_isPublic;
|
||||
std::string const m_remoteIP;
|
||||
IPAddress const m_remoteAddress;
|
||||
LockType m_receiveQueueMutex;
|
||||
std::deque <message_ptr> m_receiveQueue;
|
||||
NetworkOPs& m_netOPs;
|
||||
LoadSource m_loadSource;
|
||||
boost::asio::deadline_timer m_pingTimer;
|
||||
bool m_sentPing;
|
||||
bool m_receiveQueueRunning;
|
||||
@@ -96,11 +95,10 @@ public:
|
||||
connection_ptr const& cpConnection)
|
||||
: WSConnection (
|
||||
resourceManager,
|
||||
resourceManager.newInboundEndpoint (IPAddressConversion::from_asio (
|
||||
cpConnection->get_socket ().lowest_layer ().remote_endpoint ().address ())),
|
||||
resourceManager.newInboundEndpoint (cpConnection->get_socket ().remote_endpoint ()),
|
||||
source,
|
||||
serverHandler.getPublic (),
|
||||
cpConnection->get_socket ().lowest_layer ().remote_endpoint ().address ().to_string (),
|
||||
cpConnection->get_socket ().remote_endpoint (),
|
||||
cpConnection->get_io_service ())
|
||||
, m_serverHandler (serverHandler)
|
||||
, m_connection (cpConnection)
|
||||
|
||||
@@ -41,7 +41,7 @@ class WSDoorImp : public WSDoor, protected Thread, LeakChecked <WSDoorImp>
|
||||
public:
|
||||
WSDoorImp (Resource::Manager& resourceManager,
|
||||
InfoSub::Source& source, std::string const& strIp,
|
||||
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context)
|
||||
int iPort, bool bPublic, bool bProxy, boost::asio::ssl::context& ssl_context)
|
||||
: WSDoor (source)
|
||||
, Thread ("websocket")
|
||||
, m_resourceManager (resourceManager)
|
||||
@@ -49,6 +49,7 @@ public:
|
||||
, m_ssl_context (ssl_context)
|
||||
, m_endpointLock (this, "WSDoor", __FILE__, __LINE__)
|
||||
, mPublic (bPublic)
|
||||
, mProxy (bProxy)
|
||||
, mIp (strIp)
|
||||
, mPort (iPort)
|
||||
{
|
||||
@@ -67,14 +68,14 @@ private:
|
||||
boost::format ("Websocket: %s: Listening: %s %d ") %
|
||||
(mPublic ? "Public" : "Private") % mIp % mPort);
|
||||
|
||||
websocketpp::server_autotls::handler::ptr handler (
|
||||
new WSServerHandler <websocketpp::server_autotls> (
|
||||
m_resourceManager, m_source, m_ssl_context, mPublic));
|
||||
websocketpp::server_multitls::handler::ptr handler (
|
||||
new WSServerHandler <websocketpp::server_multitls> (
|
||||
m_resourceManager, m_source, m_ssl_context, mPublic, mProxy));
|
||||
|
||||
{
|
||||
ScopedLockType lock (m_endpointLock, __FILE__, __LINE__);
|
||||
|
||||
m_endpoint = new websocketpp::server_autotls (handler);
|
||||
m_endpoint = new websocketpp::server_multitls (handler);
|
||||
}
|
||||
|
||||
// Call the main-event-loop of the websocket server.
|
||||
@@ -137,8 +138,9 @@ private:
|
||||
boost::asio::ssl::context& m_ssl_context;
|
||||
LockType m_endpointLock;
|
||||
|
||||
ScopedPointer <websocketpp::server_autotls> m_endpoint;
|
||||
ScopedPointer <websocketpp::server_multitls> m_endpoint;
|
||||
bool mPublic;
|
||||
bool mProxy;
|
||||
std::string mIp;
|
||||
int mPort;
|
||||
};
|
||||
@@ -154,14 +156,14 @@ WSDoor::WSDoor (Stoppable& parent)
|
||||
|
||||
WSDoor* WSDoor::New (Resource::Manager& resourceManager,
|
||||
InfoSub::Source& source, std::string const& strIp,
|
||||
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context)
|
||||
int iPort, bool bPublic, bool bProxy, boost::asio::ssl::context& ssl_context)
|
||||
{
|
||||
ScopedPointer <WSDoor> door;
|
||||
|
||||
try
|
||||
{
|
||||
door = new WSDoorImp (resourceManager,
|
||||
source, strIp, iPort, bPublic, ssl_context);
|
||||
source, strIp, iPort, bPublic, bProxy, ssl_context);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
|
||||
static WSDoor* New (Resource::Manager& resourceManager,
|
||||
InfoSub::Source& source, std::string const& strIp,
|
||||
int iPort, bool bPublic, boost::asio::ssl::context& ssl_context);
|
||||
int iPort, bool bPublic, bool bProxy, boost::asio::ssl::context& ssl_context);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -72,15 +72,17 @@ protected:
|
||||
boost::unordered_map <connection_ptr,
|
||||
boost::shared_ptr <WSConnectionType <endpoint_type> > > mMap;
|
||||
bool const mPublic;
|
||||
bool const mProxy;
|
||||
|
||||
public:
|
||||
WSServerHandler (Resource::Manager& resourceManager,
|
||||
InfoSub::Source& source, boost::asio::ssl::context& ssl_context, bool bPublic)
|
||||
InfoSub::Source& source, boost::asio::ssl::context& ssl_context, bool bPublic, bool bProxy)
|
||||
: m_resourceManager (resourceManager)
|
||||
, m_source (source)
|
||||
, mLock (static_cast <WSServerHandlerBase*> (this), "WSServerHandler", __FILE__, __LINE__)
|
||||
, m_ssl_context (ssl_context)
|
||||
, mPublic (bPublic)
|
||||
, mProxy (bProxy)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -249,7 +251,7 @@ public:
|
||||
try
|
||||
{
|
||||
WriteLog (lsDEBUG, WSServerHandlerLog) << "Ws:: Rejected("
|
||||
<< cpClient->get_socket ().lowest_layer ().remote_endpoint ().address ().to_string ()
|
||||
<< cpClient->get_socket ().remote_endpoint ().to_string ()
|
||||
<< ") '" << mpMessage->get_payload () << "'";
|
||||
}
|
||||
catch (...)
|
||||
@@ -301,7 +303,7 @@ public:
|
||||
try
|
||||
{
|
||||
WriteLog (lsDEBUG, WSServerHandlerLog) << "Ws:: Receiving("
|
||||
<< cpClient->get_socket ().lowest_layer ().remote_endpoint ().address ().to_string ()
|
||||
<< cpClient->get_socket ().remote_endpoint ().to_string ()
|
||||
<< ") '" << mpMessage->get_payload () << "'";
|
||||
}
|
||||
catch (...)
|
||||
@@ -345,6 +347,10 @@ public:
|
||||
{
|
||||
return m_ssl_context;
|
||||
}
|
||||
bool get_proxy ()
|
||||
{
|
||||
return mProxy;
|
||||
}
|
||||
|
||||
// Respond to http requests.
|
||||
bool http (connection_ptr cpClient)
|
||||
|
||||
@@ -60,6 +60,8 @@ Config::Config ()
|
||||
WEBSOCKET_PORT = SYSTEM_WEBSOCKET_PORT;
|
||||
WEBSOCKET_PUBLIC_PORT = SYSTEM_WEBSOCKET_PUBLIC_PORT;
|
||||
WEBSOCKET_PUBLIC_SECURE = 1;
|
||||
WEBSOCKET_PROXY_PORT = 0;
|
||||
WEBSOCKET_PROXY_SECURE = 1;
|
||||
WEBSOCKET_SECURE = 0;
|
||||
WEBSOCKET_PING_FREQ = (5 * 60);
|
||||
NUMBER_CONNECTIONS = 30;
|
||||
@@ -408,12 +410,20 @@ void Config::load ()
|
||||
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PUBLIC_PORT, strTemp))
|
||||
WEBSOCKET_PUBLIC_PORT = lexicalCastThrow <int> (strTemp);
|
||||
|
||||
(void) SectionSingleB (secConfig, SECTION_WEBSOCKET_PROXY_IP, WEBSOCKET_PROXY_IP);
|
||||
|
||||
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PROXY_PORT, strTemp))
|
||||
WEBSOCKET_PROXY_PORT = lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_SECURE, strTemp))
|
||||
WEBSOCKET_SECURE = lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PUBLIC_SECURE, strTemp))
|
||||
WEBSOCKET_PUBLIC_SECURE = lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PROXY_SECURE, strTemp))
|
||||
WEBSOCKET_PROXY_SECURE = lexicalCastThrow <int> (strTemp);
|
||||
|
||||
if (SectionSingleB (secConfig, SECTION_WEBSOCKET_PING_FREQ, strTemp))
|
||||
WEBSOCKET_PING_FREQ = lexicalCastThrow <int> (strTemp);
|
||||
|
||||
|
||||
@@ -401,6 +401,10 @@ public:
|
||||
int WEBSOCKET_PUBLIC_PORT;
|
||||
int WEBSOCKET_PUBLIC_SECURE;
|
||||
|
||||
std::string WEBSOCKET_PROXY_IP; // XXX Going away. Merge with the inbound peer connction.
|
||||
int WEBSOCKET_PROXY_PORT;
|
||||
int WEBSOCKET_PROXY_SECURE;
|
||||
|
||||
std::string WEBSOCKET_IP;
|
||||
int WEBSOCKET_PORT;
|
||||
int WEBSOCKET_SECURE;
|
||||
|
||||
@@ -92,6 +92,9 @@ struct ConfigSection
|
||||
#define SECTION_WEBSOCKET_PUBLIC_IP "websocket_public_ip"
|
||||
#define SECTION_WEBSOCKET_PUBLIC_PORT "websocket_public_port"
|
||||
#define SECTION_WEBSOCKET_PUBLIC_SECURE "websocket_public_secure"
|
||||
#define SECTION_WEBSOCKET_PROXY_IP "websocket_proxy_ip"
|
||||
#define SECTION_WEBSOCKET_PROXY_PORT "websocket_proxy_port"
|
||||
#define SECTION_WEBSOCKET_PROXY_SECURE "websocket_proxy_secure"
|
||||
#define SECTION_WEBSOCKET_PING_FREQ "websocket_ping_frequency"
|
||||
#define SECTION_WEBSOCKET_IP "websocket_ip"
|
||||
#define SECTION_WEBSOCKET_PORT "websocket_port"
|
||||
|
||||
@@ -1,176 +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 RIPPLE_CORE_FUNCTIONAL_LOADSOURCE_H_INCLUDED
|
||||
#define RIPPLE_CORE_FUNCTIONAL_LOADSOURCE_H_INCLUDED
|
||||
|
||||
/** Tracks the consumption of resources at an endpoint.
|
||||
|
||||
To prevent monopolization of server resources or attacks on servers,
|
||||
resource consumption is monitored at each endpoint. When consumption
|
||||
exceeds certain thresholds, costs are imposed. Costs include charging
|
||||
additional XRP for transactions, requiring a proof of work to be
|
||||
performed, or simply disconnecting the endpoint.
|
||||
|
||||
Currently, consumption endpoints include websocket connections used to
|
||||
service clients, and peer connections used to create the peer to peer
|
||||
overlay network implementing the Ripple protcool.
|
||||
|
||||
The current "balance" of a LoadSource represents resource consumption
|
||||
debt or credit. Debt is accrued when bad loads are imposed. Credit is
|
||||
granted when good loads are imposed. When the balance crosses heuristic
|
||||
thresholds, costs are increased on the endpoint.
|
||||
|
||||
The balance is represented as a unitless relative quantity.
|
||||
|
||||
@note Although RPC connections consume resources, they are transient and
|
||||
cannot be rate limited. It is advised not to expose RPC interfaces
|
||||
to the general public.
|
||||
*/
|
||||
class LoadSource
|
||||
{
|
||||
public:
|
||||
/** Construct a load source.
|
||||
|
||||
Sources with admin privileges have relaxed or no restrictions
|
||||
on resource consumption.
|
||||
|
||||
@param admin `true` if the source should have admin privileges.
|
||||
*/
|
||||
// VFALCO TODO See who is constructing this with a parameter
|
||||
explicit LoadSource (bool admin)
|
||||
: mBalance (0)
|
||||
, mFlags (admin ? lsfPrivileged : 0)
|
||||
, mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ())
|
||||
, mLastWarning (0)
|
||||
, mLogged (false)
|
||||
{
|
||||
}
|
||||
|
||||
/** Construct a load source with a given name.
|
||||
The endpoint is considered non-privileged.
|
||||
*/
|
||||
explicit LoadSource (std::string const& name, std::string const& costName)
|
||||
: mName (name)
|
||||
, mCostName (costName)
|
||||
, mBalance (0)
|
||||
, mFlags (0)
|
||||
, mLastUpdate (UptimeTimer::getInstance ().getElapsedSeconds ())
|
||||
, mLastWarning (0)
|
||||
, mLogged (false)
|
||||
{
|
||||
}
|
||||
|
||||
/** Change the name of the source.
|
||||
|
||||
An endpoint can be created before it's name is known. For example,
|
||||
on an incoming connection before the IP and port have been determined.
|
||||
*/
|
||||
// VFALCO TODO Figure out a way to construct the LoadSource object with
|
||||
// the proper name instead of renaming it later.
|
||||
//
|
||||
void rename (std::string const& name, std::string const& costName) noexcept
|
||||
{
|
||||
mName = name;
|
||||
mCostName = costName;
|
||||
}
|
||||
|
||||
/** Retrieve the name of this endpoint.
|
||||
*/
|
||||
std::string const& getName () const noexcept
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
std::string const& getCostName () const noexcept
|
||||
{
|
||||
return mCostName;
|
||||
}
|
||||
|
||||
/** Determine if this endpoint is privileged.
|
||||
*/
|
||||
bool isPrivileged () const noexcept
|
||||
{
|
||||
return (mFlags & lsfPrivileged) != 0;
|
||||
}
|
||||
|
||||
/** Grant the privileged attribute on this endpoint.
|
||||
*/
|
||||
void setPrivileged () noexcept
|
||||
{
|
||||
mFlags |= lsfPrivileged;
|
||||
}
|
||||
|
||||
/** Retrieve the load debit or credit associated with the endpoint.
|
||||
|
||||
The balance is represented in a unitless relative quantity
|
||||
indicating the heuristically weighted amount of resource consumption.
|
||||
*/
|
||||
int getBalance () const noexcept
|
||||
{
|
||||
return mBalance;
|
||||
}
|
||||
|
||||
/** Returns true if the endpoint received a log warning.
|
||||
*/
|
||||
bool isLogged () const noexcept
|
||||
{
|
||||
return mLogged;
|
||||
}
|
||||
|
||||
/** Reset the flag indicating the endpoint received a log warning.
|
||||
*/
|
||||
void clearLogged () noexcept
|
||||
{
|
||||
mLogged = false;
|
||||
}
|
||||
|
||||
/** Indicate that this endpoint is an outgoing connection.
|
||||
*/
|
||||
void setOutbound () noexcept
|
||||
{
|
||||
mFlags |= lsfOutbound;
|
||||
}
|
||||
|
||||
/** Returns true if this endpoint is an outgoing connection.
|
||||
*/
|
||||
bool isOutbound () const
|
||||
{
|
||||
return (mFlags & lsfOutbound) != 0;
|
||||
}
|
||||
|
||||
private:
|
||||
// VFALCO Make this not a friend
|
||||
friend class LoadManagerImp;
|
||||
|
||||
// VFALCO TODO Rename these for clarity
|
||||
static const int lsfPrivileged = 1;
|
||||
static const int lsfOutbound = 2;
|
||||
|
||||
private:
|
||||
std::string mName; // Name of this particular load source, can include details like ports
|
||||
std::string mCostName; // The name to "charge" for load from this connection
|
||||
int mBalance;
|
||||
int mFlags;
|
||||
int mLastUpdate;
|
||||
int mLastWarning;
|
||||
bool mLogged;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -41,7 +41,6 @@ namespace ripple
|
||||
# include "functional/LoadMonitor.h"
|
||||
# include "functional/Job.h"
|
||||
#include "functional/JobQueue.h"
|
||||
#include "functional/LoadSource.h"
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -90,10 +90,19 @@ message TMClusterNode
|
||||
optional string address = 5;
|
||||
}
|
||||
|
||||
// Sources that are placing load on the server
|
||||
message TMLoadSource
|
||||
{
|
||||
required string name = 1;
|
||||
required uint32 cost = 2;
|
||||
optional uint32 count = 3; // number of connections
|
||||
}
|
||||
|
||||
// The status of all nodes in the cluster
|
||||
message TMCluster
|
||||
{
|
||||
repeated TMClusterNode clusterNodes = 1;
|
||||
repeated TMLoadSource loadSources = 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,12 +25,14 @@
|
||||
|
||||
#include "beast/modules/beast_asio/beast_asio.h"
|
||||
|
||||
#include "../ripple/resource/ripple_resource.h"
|
||||
|
||||
#include "../ripple_basics/ripple_basics.h"
|
||||
#include "../ripple_core/ripple_core.h"
|
||||
#include "../ripple_data/ripple_data.h"
|
||||
#include "../ripple_websocket/autosocket/AutoSocket.h"
|
||||
|
||||
namespace ripple
|
||||
{
|
||||
namespace ripple {
|
||||
|
||||
#include "basics/RippleSSLContext.h"
|
||||
#include "basics/MultiSocket.h"
|
||||
|
||||
@@ -38,8 +38,9 @@ InfoSub::Source::Source (char const* name, Stoppable& parent)
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
InfoSub::InfoSub (Source& source)
|
||||
InfoSub::InfoSub (Source& source, Consumer consumer)
|
||||
: mLock (this, "InfoSub", __FILE__, __LINE__)
|
||||
, m_consumer (consumer)
|
||||
, m_source (source)
|
||||
{
|
||||
static Atomic <int> s_seq_id;
|
||||
@@ -56,6 +57,11 @@ InfoSub::~InfoSub ()
|
||||
m_source.unsubAccount (mSeq, mSubAccountInfo, false);
|
||||
}
|
||||
|
||||
Resource::Consumer& InfoSub::getConsumer()
|
||||
{
|
||||
return m_consumer;
|
||||
}
|
||||
|
||||
void InfoSub::send (const Json::Value& jvObj, const std::string& sObj, bool broadcast)
|
||||
{
|
||||
send (jvObj, broadcast);
|
||||
|
||||
@@ -40,6 +40,8 @@ public:
|
||||
|
||||
typedef const boost::shared_ptr<InfoSub>& ref;
|
||||
|
||||
typedef Resource::Consumer Consumer;
|
||||
|
||||
public:
|
||||
/** Abstracts the source of subscription data.
|
||||
*/
|
||||
@@ -95,10 +97,12 @@ public:
|
||||
};
|
||||
|
||||
public:
|
||||
explicit InfoSub (Source& source);
|
||||
InfoSub (Source& source, Consumer consumer);
|
||||
|
||||
virtual ~InfoSub ();
|
||||
|
||||
Consumer& getConsumer();
|
||||
|
||||
virtual void send (const Json::Value & jvObj, bool broadcast) = 0;
|
||||
|
||||
// VFALCO NOTE Why is this virtual?
|
||||
@@ -122,6 +126,7 @@ protected:
|
||||
LockType mLock;
|
||||
|
||||
private:
|
||||
Consumer m_consumer;
|
||||
Source& m_source;
|
||||
boost::unordered_set <RippleAddress> mSubAccountInfo;
|
||||
boost::unordered_set <RippleAddress> mSubAccountTransaction;
|
||||
|
||||
@@ -195,7 +195,7 @@ private:
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
RPCSub::RPCSub (InfoSub::Source& source)
|
||||
: InfoSub (source)
|
||||
: InfoSub (source, Consumer())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
#ifndef RIPPLE_NET_RPC_RPCSUB_H_INCLUDED
|
||||
#define RIPPLE_NET_RPC_RPCSUB_H_INCLUDED
|
||||
|
||||
/** Subscription object for JSON RPC.
|
||||
*/
|
||||
/** Subscription object for JSON RPC. */
|
||||
class RPCSub : public InfoSub
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#endif
|
||||
|
||||
#include "../ripple_basics/ripple_basics.h"
|
||||
#include "../ripple_net/ripple_net.h"
|
||||
|
||||
#include "beast/modules/beast_core/system/BeforeBoost.h"
|
||||
#include <boost/asio.hpp>
|
||||
@@ -33,8 +33,7 @@
|
||||
|
||||
#include "websocket/src/common.hpp"
|
||||
#include "websocket/src/sockets/socket_base.hpp"
|
||||
#include "autosocket/AutoSocket.h" // must come before autotls.hpp
|
||||
#include "websocket/src/sockets/autotls.hpp"
|
||||
#include "websocket/src/sockets/multitls.hpp"
|
||||
#include "websocket/src/websocketpp.hpp"
|
||||
#include "websocket/src/logger/logger.hpp"
|
||||
|
||||
|
||||
@@ -900,7 +900,8 @@ public:
|
||||
{
|
||||
// TODO: read timeout timer?
|
||||
|
||||
socket_type::get_socket().async_read(
|
||||
async_read(
|
||||
socket_type::get_socket(),
|
||||
m_buf,
|
||||
boost::asio::transfer_at_least(std::min(
|
||||
m_read_threshold,
|
||||
@@ -1209,7 +1210,7 @@ public:
|
||||
|
||||
//m_endpoint.alog().at(log::alevel::DEVEL) << "write header: " << zsutil::to_hex(m_write_queue.front()->get_header()) << log::endl;
|
||||
|
||||
socket_type::get_socket().async_write(
|
||||
async_write(socket_type::get_socket(),
|
||||
m_write_buf,
|
||||
m_strand.wrap(boost::bind(
|
||||
&type::handle_write,
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#define WEBSOCKETPP_ENDPOINT_HPP
|
||||
|
||||
#include "connection.hpp"
|
||||
#include "sockets/autotls.hpp" // should this be here?
|
||||
#include "sockets/multitls.hpp" // should this be here?
|
||||
#include "logger/logger.hpp"
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
@@ -74,7 +74,7 @@ protected:
|
||||
*/
|
||||
template <
|
||||
template <class> class role,
|
||||
template <class> class socket = socket::autotls,
|
||||
template <class> class socket = socket::multitls,
|
||||
template <class> class logger = log::logger>
|
||||
class endpoint
|
||||
: public endpoint_base,
|
||||
|
||||
@@ -410,7 +410,7 @@ void server<endpoint>::start_accept() {
|
||||
}
|
||||
|
||||
m_acceptor.async_accept(
|
||||
con->get_raw_socket(),
|
||||
con->get_native_socket (),
|
||||
boost::bind(
|
||||
&type::handle_accept,
|
||||
this,
|
||||
@@ -427,7 +427,7 @@ template <class endpoint>
|
||||
void server<endpoint>::handle_accept(connection_ptr con,
|
||||
const boost::system::error_code& error)
|
||||
{
|
||||
bool delay = false;
|
||||
bool delay = false;
|
||||
|
||||
boost::lock_guard<boost::recursive_mutex> lock(m_endpoint.m_lock);
|
||||
|
||||
@@ -554,18 +554,19 @@ void server<endpoint>::connection<connection_type>::async_init() {
|
||||
static boost::arg<1> pl1;
|
||||
static boost::arg<2> pl2;
|
||||
|
||||
boost::shared_ptr<std::string> stringPtr = boost::make_shared<std::string>();
|
||||
m_connection.get_socket().async_read_until(
|
||||
m_connection.buffer(),
|
||||
boost::bind(&match_header, stringPtr, pl1, pl2),
|
||||
m_connection.get_strand().wrap(boost::bind(
|
||||
&type::handle_read_request,
|
||||
m_connection.shared_from_this(),
|
||||
stringPtr,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred
|
||||
))
|
||||
);
|
||||
boost::shared_ptr<std::string> stringPtr = boost::make_shared<std::string>();
|
||||
async_read_until(
|
||||
m_connection.get_socket(),
|
||||
m_connection.buffer(),
|
||||
boost::bind(&match_header, stringPtr, pl1, pl2),
|
||||
m_connection.get_strand().wrap(boost::bind(
|
||||
&type::handle_read_request,
|
||||
m_connection.shared_from_this(),
|
||||
stringPtr,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
/// processes the response from an async read for an HTTP header
|
||||
@@ -598,13 +599,14 @@ void server<endpoint>::connection<connection_type>::handle_read_request(
|
||||
std::string reply =
|
||||
"<?xml version=\"1.0\"?><cross-domain-policy>"
|
||||
"<allow-access-from domain=\"*\" to-ports=\"";
|
||||
reply += beast::lexicalCastThrow <std::string>(m_connection.get_raw_socket().local_endpoint().port());
|
||||
reply += "\"/></cross-domain-policy>";
|
||||
reply.append("\0", 1);
|
||||
reply += beast::lexicalCastThrow <std::string>(m_connection.get_native_socket().local_endpoint().port());
|
||||
reply += "\"/></cross-domain-policy>";
|
||||
reply.append("\0", 1);
|
||||
|
||||
m_version = -1;
|
||||
shared_const_buffer buffer(reply);
|
||||
m_connection.get_socket().async_write(
|
||||
async_write(
|
||||
m_connection.get_socket(),
|
||||
shared_const_buffer(reply),
|
||||
boost::bind(
|
||||
&type::handle_write_response,
|
||||
@@ -862,7 +864,8 @@ void server<endpoint>::connection<connection_type>::write_response() {
|
||||
|
||||
m_endpoint.m_alog->at(log::alevel::DEBUG_HANDSHAKE) << raw << log::endl;
|
||||
|
||||
m_connection.get_socket().async_write(
|
||||
async_write(
|
||||
m_connection.get_socket(),
|
||||
//boost::asio::buffer(raw),
|
||||
buffer,
|
||||
boost::bind(
|
||||
@@ -928,8 +931,8 @@ void server<endpoint>::connection<connection_type>::log_open_result() {
|
||||
version << "v" << m_version << " ";
|
||||
|
||||
std::string remote;
|
||||
boost::system::error_code ec;
|
||||
boost::asio::ip::tcp::endpoint ep = m_connection.get_raw_socket().remote_endpoint(ec);
|
||||
boost::system::error_code ec; // FIXME: proxy
|
||||
boost::asio::ip::tcp::endpoint ep = m_connection.get_native_socket().remote_endpoint(ec);
|
||||
if (ec) {
|
||||
m_endpoint.m_elog->at(log::elevel::WARN)
|
||||
<< "Error getting remote endpoint. code: " << ec << log::endl;
|
||||
|
||||
173
src/websocket/src/sockets/multitls.hpp
Normal file
173
src/websocket/src/sockets/multitls.hpp
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Peter Thorson. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of the WebSocket++ Project nor the
|
||||
* names of its contributors may be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBSOCKETPP_SOCKET_MULTITLS_HPP
|
||||
#define WEBSOCKETPP_SOCKET_MULTITLS_HPP
|
||||
|
||||
namespace websocketpp {
|
||||
namespace socket {
|
||||
|
||||
template <typename endpoint_type>
|
||||
class multitls {
|
||||
public:
|
||||
typedef multitls<endpoint_type> type;
|
||||
typedef ripple::MultiSocket multitls_socket;
|
||||
typedef boost::asio::ip::tcp::socket native_socket_t;
|
||||
typedef boost::shared_ptr<multitls_socket> multitls_socket_ptr;
|
||||
|
||||
// should be private friended
|
||||
boost::asio::io_service& get_io_service() {
|
||||
return m_io_service;
|
||||
}
|
||||
|
||||
static void handle_shutdown(multitls_socket_ptr, const boost::system::error_code&) {
|
||||
}
|
||||
|
||||
void set_secure_only() {
|
||||
m_secure_only = true;
|
||||
}
|
||||
|
||||
void set_plain_only() {
|
||||
m_plain_only = true;
|
||||
}
|
||||
|
||||
// should be private friended?
|
||||
multitls_socket::handshake_type get_handshake_type() {
|
||||
if (static_cast< endpoint_type* >(this)->is_server()) {
|
||||
return boost::asio::ssl::stream_base::server;
|
||||
} else {
|
||||
return boost::asio::ssl::stream_base::client;
|
||||
}
|
||||
}
|
||||
|
||||
class handler_interface {
|
||||
public:
|
||||
virtual ~handler_interface() {}
|
||||
|
||||
virtual void on_tcp_init() {};
|
||||
virtual boost::asio::ssl::context& get_ssl_context () = 0;
|
||||
virtual bool get_proxy() = 0;
|
||||
};
|
||||
|
||||
// Connection specific details
|
||||
template <typename connection_type>
|
||||
class connection {
|
||||
public:
|
||||
|
||||
multitls_socket& get_socket() {
|
||||
return *m_socket_ptr;
|
||||
}
|
||||
|
||||
native_socket_t& get_native_socket() {
|
||||
return m_socket_ptr->next_layer<native_socket_t> ();
|
||||
}
|
||||
|
||||
bool is_secure() {
|
||||
return m_socket_ptr->ssl_handle() != NULL;
|
||||
}
|
||||
protected:
|
||||
connection(multitls<endpoint_type>& e)
|
||||
: m_endpoint(e)
|
||||
, m_connection(static_cast< connection_type& >(*this)) {}
|
||||
|
||||
void init() {
|
||||
boost::asio::ssl::context& ssl_context (
|
||||
m_connection.get_handler()->get_ssl_context());
|
||||
|
||||
int flags = multitls_socket::Flag::server_role |
|
||||
(m_endpoint.m_secure_only ? multitls_socket::Flag::ssl_required : 0) |
|
||||
(m_endpoint.m_plain_only ? 0 : multitls_socket::Flag::ssl);
|
||||
if (m_connection.get_handler()->get_proxy ())
|
||||
flags |= multitls_socket::Flag::proxy;
|
||||
|
||||
m_socket_ptr = multitls_socket_ptr (multitls_socket::New (
|
||||
m_endpoint.get_io_service(), ssl_context, flags ) );
|
||||
}
|
||||
|
||||
void async_init(boost::function<void(const boost::system::error_code&)> callback)
|
||||
{
|
||||
m_connection.get_handler()->on_tcp_init();
|
||||
|
||||
// wait for TLS handshake
|
||||
// TODO: configurable value
|
||||
m_connection.register_timeout(5000,
|
||||
fail::status::TIMEOUT_TLS,
|
||||
"Timeout on TLS handshake");
|
||||
|
||||
m_socket_ptr->async_handshake(
|
||||
m_endpoint.get_handshake_type(),
|
||||
boost::bind(
|
||||
&connection<connection_type>::handle_init,
|
||||
this,
|
||||
callback,
|
||||
boost::asio::placeholders::error
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
void handle_init(socket_init_callback callback,const boost::system::error_code& error) {
|
||||
m_connection.cancel_timeout();
|
||||
callback(error);
|
||||
}
|
||||
|
||||
// note, this function for some reason shouldn't/doesn't need to be
|
||||
// called for plain HTTP connections. not sure why.
|
||||
bool shutdown() {
|
||||
boost::system::error_code ignored_ec;
|
||||
|
||||
m_socket_ptr->async_shutdown( // Don't block on connection shutdown DJS
|
||||
boost::bind(
|
||||
&multitls<endpoint_type>::handle_shutdown,
|
||||
m_socket_ptr,
|
||||
boost::asio::placeholders::error
|
||||
)
|
||||
);
|
||||
|
||||
if (ignored_ec) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
private:
|
||||
boost::shared_ptr<boost::asio::ssl::context> m_context_ptr;
|
||||
multitls_socket_ptr m_socket_ptr;
|
||||
multitls<endpoint_type>& m_endpoint;
|
||||
connection_type& m_connection;
|
||||
};
|
||||
protected:
|
||||
multitls (boost::asio::io_service& m) : m_io_service(m), m_secure_only(false), m_plain_only(false) {}
|
||||
private:
|
||||
boost::asio::io_service& m_io_service;
|
||||
bool m_secure_only;
|
||||
bool m_plain_only;
|
||||
};
|
||||
|
||||
} // namespace socket
|
||||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_SOCKET_MULTITLS_HPP
|
||||
@@ -41,9 +41,9 @@ namespace websocketpp {
|
||||
typedef websocketpp::endpoint<websocketpp::role::server,
|
||||
websocketpp::socket::tls> server_tls;
|
||||
#endif
|
||||
#ifdef WEBSOCKETPP_SOCKET_AUTOTLS_HPP
|
||||
#ifdef WEBSOCKETPP_SOCKET_MULTITLS_HPP
|
||||
typedef websocketpp::endpoint<websocketpp::role::server,
|
||||
websocketpp::socket::autotls> server_autotls;
|
||||
websocketpp::socket::multitls> server_multitls;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user