mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
277 lines
8.4 KiB
C++
277 lines
8.4 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
Copyright (c) 2011-2013, OpenCoin, Inc.
|
|
*/
|
|
//==============================================================================
|
|
|
|
#ifndef RIPPLE_ILOADMANAGER_H
|
|
#define RIPPLE_ILOADMANAGER_H
|
|
|
|
// types of load that can be placed on the server
|
|
// VFALCO TODO replace LT_ with loadType in constants
|
|
enum LoadType
|
|
{
|
|
// Bad things
|
|
LT_InvalidRequest, // A request that we can immediately tell is invalid
|
|
LT_RequestNoReply, // A request that we cannot satisfy
|
|
LT_InvalidSignature, // An object whose signature we had to check and it failed
|
|
LT_UnwantedData, // Data we have no use for
|
|
LT_BadPoW, // Proof of work not valid
|
|
LT_BadData, // Data we have to verify before rejecting
|
|
|
|
// RPC loads
|
|
LT_RPCInvalid, // An RPC request that we can immediately tell is invalid.
|
|
LT_RPCReference, // A default "reference" unspecified load
|
|
LT_RPCException, // An RPC load that causes an exception
|
|
LT_RPCBurden, // A particularly burdensome RPC load
|
|
|
|
// Good things
|
|
LT_NewTrusted, // A new transaction/validation/proposal we trust
|
|
LT_NewTransaction, // A new, valid transaction
|
|
LT_NeededData, // Data we requested
|
|
|
|
// Requests
|
|
LT_RequestData, // A request that is hard to satisfy, disk access
|
|
LT_CheapQuery, // A query that is trivial, cached data
|
|
|
|
LT_MAX // MUST BE LAST
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
/** 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:
|
|
// VFALCO TODO Use these dispositions
|
|
/*
|
|
enum Disposition
|
|
{
|
|
none,
|
|
shouldWarn,
|
|
shouldDrop,
|
|
};
|
|
*/
|
|
|
|
/** 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)
|
|
: mName (name)
|
|
, 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)
|
|
{
|
|
mName = name;
|
|
}
|
|
|
|
/** Retrieve the name of this endpoint.
|
|
*/
|
|
std::string const& getName () const
|
|
{
|
|
return mName;
|
|
}
|
|
|
|
/** Determine if this endpoint is privileged.
|
|
*/
|
|
bool isPrivileged () const
|
|
{
|
|
return (mFlags & lsfPrivileged) != 0;
|
|
}
|
|
|
|
/** Grant the privileged attribute on this endpoint.
|
|
*/
|
|
void setPrivileged ()
|
|
{
|
|
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
|
|
{
|
|
return mBalance;
|
|
}
|
|
|
|
/** Returns true if the endpoint received a log warning.
|
|
*/
|
|
bool isLogged () const
|
|
{
|
|
return mLogged;
|
|
}
|
|
|
|
/** Reset the flag indicating the endpoint received a log warning.
|
|
*/
|
|
void clearLogged ()
|
|
{
|
|
mLogged = false;
|
|
}
|
|
|
|
/** Indicate that this endpoint is an outgoing connection.
|
|
*/
|
|
void setOutbound ()
|
|
{
|
|
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 LoadManager;
|
|
|
|
static const int lsfPrivileged = 1;
|
|
static const int lsfOutbound = 2;
|
|
|
|
private:
|
|
std::string mName;
|
|
int mBalance;
|
|
int mFlags;
|
|
int mLastUpdate;
|
|
int mLastWarning;
|
|
bool mLogged;
|
|
};
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
/** Manages load sources.
|
|
|
|
This object creates an associated thread to maintain a clock.
|
|
|
|
When the server is overloaded by a particular peer it issues a warning
|
|
first. This allows friendly peers to reduce their consumption of resources,
|
|
or disconnect from the server.
|
|
|
|
The warning system is used instead of merely dropping, because hostile
|
|
peers can just reconnect anyway.
|
|
|
|
@see LoadSource, LoadType
|
|
*/
|
|
class ILoadManager
|
|
{
|
|
public:
|
|
/** Create a new manager.
|
|
|
|
The manager thread begins running immediately.
|
|
|
|
@note The thresholds for warnings and punishments are in
|
|
the ctor-initializer
|
|
*/
|
|
static ILoadManager* New ();
|
|
|
|
/** Destroy the manager.
|
|
|
|
The destructor returns only after the thread has stopped.
|
|
*/
|
|
virtual ~ILoadManager () { }
|
|
|
|
/** Start the associated thread.
|
|
|
|
This is here to prevent the deadlock detector from activating during
|
|
a lengthy program initialization.
|
|
*/
|
|
// VFALCO TODO Simplify the two stage initialization to one stage (construction).
|
|
// NOTE In stand-alone mode the load manager thread isn't started
|
|
virtual void startThread () = 0;
|
|
|
|
/** Turn on deadlock detection.
|
|
|
|
The deadlock detector begins in a disabled state. After this function
|
|
is called, it will report deadlocks using a separate thread whenever
|
|
the reset function is not called at least once per 10 seconds.
|
|
|
|
@see resetDeadlockDetector
|
|
*/
|
|
// VFALCO NOTE it seems that the deadlock detector has an "armed" state to prevent it
|
|
// from going off during program startup if there's a lengthy initialization
|
|
// operation taking place?
|
|
//
|
|
virtual void activateDeadlockDetector () = 0;
|
|
|
|
/** Reset the deadlock detection timer.
|
|
|
|
A dedicated thread monitors the deadlock timer, and if too much
|
|
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&) const = 0;
|
|
virtual bool shouldCutoff (LoadSource&) const = 0;
|
|
};
|
|
|
|
#endif
|