mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
217 lines
6.6 KiB
C++
217 lines
6.6 KiB
C++
//------------------------------------------------------------------------------
|
|
/*
|
|
Copyright (c) 2011-2013, OpenCoin, Inc.
|
|
*/
|
|
//==============================================================================
|
|
|
|
#ifndef RIPPLE_LOADFEETRACK_RIPPLEHEADER
|
|
#define RIPPLE_LOADFEETRACK_RIPPLEHEADER
|
|
|
|
// PRIVATE HEADER
|
|
class LoadManager;
|
|
|
|
class LoadFeeTrack : public ILoadFeeTrack
|
|
{
|
|
public:
|
|
LoadFeeTrack ()
|
|
: mLocalTxnLoadFee (lftNormalFee)
|
|
, mRemoteTxnLoadFee (lftNormalFee)
|
|
, mClusterTxnLoadFee (lftNormalFee)
|
|
, raiseCount (0)
|
|
{
|
|
}
|
|
|
|
// Scale using load as well as base rate
|
|
uint64 scaleFeeLoad (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits, bool bAdmin)
|
|
{
|
|
static uint64 midrange (0x00000000FFFFFFFF);
|
|
|
|
bool big = (fee > midrange);
|
|
|
|
if (big) // big fee, divide first to avoid overflow
|
|
fee /= baseFee;
|
|
else // normal fee, multiply first for accuracy
|
|
fee *= referenceFeeUnits;
|
|
|
|
uint32 feeFactor = std::max (mLocalTxnLoadFee, mRemoteTxnLoadFee);
|
|
|
|
// Let admins pay the normal fee until the local load exceeds four times the remote
|
|
uint32 uRemFee = std::max(mRemoteTxnLoadFee, mClusterTxnLoadFee);
|
|
if (bAdmin && (feeFactor > uRemFee) && (feeFactor < (4 * uRemFee)))
|
|
feeFactor = uRemFee;
|
|
|
|
{
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
fee = mulDiv (fee, feeFactor, lftNormalFee);
|
|
}
|
|
|
|
if (big) // Fee was big to start, must now multiply
|
|
fee *= referenceFeeUnits;
|
|
else // Fee was small to start, mst now divide
|
|
fee /= baseFee;
|
|
|
|
return fee;
|
|
}
|
|
|
|
// Scale from fee units to millionths of a ripple
|
|
uint64 scaleFeeBase (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits)
|
|
{
|
|
return mulDiv (fee, referenceFeeUnits, baseFee);
|
|
}
|
|
|
|
uint32 getRemoteFee ()
|
|
{
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
return mRemoteTxnLoadFee;
|
|
}
|
|
|
|
uint32 getLocalFee ()
|
|
{
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
return mLocalTxnLoadFee;
|
|
}
|
|
|
|
uint32 getLoadBase ()
|
|
{
|
|
return lftNormalFee;
|
|
}
|
|
|
|
uint32 getLoadFactor ()
|
|
{
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
return std::max(mClusterTxnLoadFee, std::max (mLocalTxnLoadFee, mRemoteTxnLoadFee));
|
|
}
|
|
|
|
void setClusterFee (uint32 fee)
|
|
{
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
mClusterTxnLoadFee = fee;
|
|
}
|
|
|
|
uint32 getClusterFee ()
|
|
{
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
return mClusterTxnLoadFee;
|
|
}
|
|
|
|
bool isLoadedLocal ()
|
|
{
|
|
// VFALCO TODO This could be replaced with a SharedData and
|
|
// using a read/write lock instead of a critical section.
|
|
//
|
|
// NOTE This applies to all the locking in this class.
|
|
//
|
|
//
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
return (raiseCount != 0) || (mLocalTxnLoadFee != lftNormalFee);
|
|
}
|
|
|
|
bool isLoadedCluster ()
|
|
{
|
|
// VFALCO TODO This could be replaced with a SharedData and
|
|
// using a read/write lock instead of a critical section.
|
|
//
|
|
// NOTE This applies to all the locking in this class.
|
|
//
|
|
//
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
return (raiseCount != 0) || (mLocalTxnLoadFee != lftNormalFee) || (mClusterTxnLoadFee != lftNormalFee);
|
|
}
|
|
|
|
void setRemoteFee (uint32 f)
|
|
{
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
mRemoteTxnLoadFee = f;
|
|
}
|
|
|
|
bool raiseLocalFee ()
|
|
{
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
|
|
if (++raiseCount < 2)
|
|
return false;
|
|
|
|
uint32 origFee = mLocalTxnLoadFee;
|
|
|
|
if (mLocalTxnLoadFee < mRemoteTxnLoadFee) // make sure this fee takes effect
|
|
mLocalTxnLoadFee = mRemoteTxnLoadFee;
|
|
|
|
mLocalTxnLoadFee += (mLocalTxnLoadFee / lftFeeIncFraction); // increment by 1/16th
|
|
|
|
if (mLocalTxnLoadFee > lftFeeMax)
|
|
mLocalTxnLoadFee = lftFeeMax;
|
|
|
|
if (origFee == mLocalTxnLoadFee)
|
|
return false;
|
|
|
|
WriteLog (lsDEBUG, LoadManager) << "Local load fee raised from " << origFee << " to " << mLocalTxnLoadFee;
|
|
return true;
|
|
}
|
|
|
|
bool lowerLocalFee ()
|
|
{
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
uint32 origFee = mLocalTxnLoadFee;
|
|
raiseCount = 0;
|
|
|
|
mLocalTxnLoadFee -= (mLocalTxnLoadFee / lftFeeDecFraction ); // reduce by 1/4
|
|
|
|
if (mLocalTxnLoadFee < lftNormalFee)
|
|
mLocalTxnLoadFee = lftNormalFee;
|
|
|
|
if (origFee == mLocalTxnLoadFee)
|
|
return false;
|
|
|
|
WriteLog (lsDEBUG, LoadManager) << "Local load fee lowered from " << origFee << " to " << mLocalTxnLoadFee;
|
|
return true;
|
|
}
|
|
|
|
Json::Value getJson (uint64 baseFee, uint32 referenceFeeUnits)
|
|
{
|
|
Json::Value j (Json::objectValue);
|
|
|
|
{
|
|
boost::mutex::scoped_lock sl (mLock);
|
|
|
|
// base_fee = The cost to send a "reference" transaction under no load, in millionths of a Ripple
|
|
j["base_fee"] = Json::Value::UInt (baseFee);
|
|
|
|
// load_fee = The cost to send a "reference" transaction now, in millionths of a Ripple
|
|
j["load_fee"] = Json::Value::UInt (
|
|
mulDiv (baseFee, std::max (mLocalTxnLoadFee, mRemoteTxnLoadFee), lftNormalFee));
|
|
}
|
|
|
|
return j;
|
|
}
|
|
|
|
private:
|
|
// VFALCO TODO Move this function to some "math utilities" file
|
|
// compute (value)*(mul)/(div) - avoid overflow but keep precision
|
|
uint64 mulDiv (uint64 value, uint32 mul, uint64 div)
|
|
{
|
|
// VFALCO TODO replace with beast::literal64bitUnsigned ()
|
|
//
|
|
static uint64 boundary = (0x00000000FFFFFFFF);
|
|
|
|
if (value > boundary) // Large value, avoid overflow
|
|
return (value / div) * mul;
|
|
else // Normal value, preserve accuracy
|
|
return (value * mul) / div;
|
|
}
|
|
|
|
private:
|
|
static const int lftNormalFee = 256; // 256 is the minimum/normal load factor
|
|
static const int lftFeeIncFraction = 4; // increase fee by 1/4
|
|
static const int lftFeeDecFraction = 4; // decrease fee by 1/4
|
|
static const int lftFeeMax = lftNormalFee * 1000000;
|
|
|
|
uint32 mLocalTxnLoadFee; // Scale factor, lftNormalFee = normal fee
|
|
uint32 mRemoteTxnLoadFee; // Scale factor, lftNormalFee = normal fee
|
|
uint32 mClusterTxnLoadFee; // Scale factor, lftNormalFee = normal fee
|
|
int raiseCount;
|
|
|
|
boost::mutex mLock;
|
|
};
|
|
|
|
#endif
|