Fee tracking both that scales with load and that doesn't (for the reserve). Get fees as json.

Locks for the fee manager.
This commit is contained in:
JoelKatz
2012-12-17 04:36:58 -08:00
parent 4032f9351a
commit a25a9831f1
2 changed files with 104 additions and 9 deletions

View File

@@ -131,24 +131,83 @@ bool LoadManager::adjust(LoadSource& source, int credits) const
return false; return false;
} }
uint64 LoadFeeTrack::scaleFee(uint64 fee) uint64 LoadFeeTrack::mulDiv(uint64 value, uint32 mul, uint32 div)
{ // compute (value)*(mul)/(div) - avoid overflow but keep precision
static uint64 boundary = (0x00000000FFFFFFFF);
if (value > boundary) // Large value, avoid overflow
return (value / div) * mul;
else // Normal value, preserve accuracy
return (value * mul) / div;
}
uint64 LoadFeeTrack::scaleFeeLoad(uint64 fee)
{ {
static uint64 midrange(0x00000000FFFFFFFF); static uint64 midrange(0x00000000FFFFFFFF);
int factor = (mLocalTxnLoadFee > mRemoteTxnLoadFee) ? mLocalTxnLoadFee : mRemoteTxnLoadFee; bool big = (fee > midrange);
if (fee > midrange) // large fee, divide first {
return (fee / lftNormalFee) * factor; boost::mutex::scoped_lock sl(mLock);
else // small fee, multiply first
return (fee * factor) / lftNormalFee; if (big) // big fee, divide first to avoid overflow
fee /= mBaseFee;
else // normal fee, multiply first for accuracy
fee *= mBaseRef;
fee = mulDiv(fee, std::max(mLocalTxnLoadFee, mRemoteTxnLoadFee), lftNormalFee);
if (big) // Fee was big to start, must now multiply
fee *= mBaseRef;
else // Fee was small to start, mst now divide
fee /= mBaseFee;
}
return fee;
}
uint64 LoadFeeTrack::scaleFeeBase(uint64 fee)
{
{
boost::mutex::scoped_lock sl(mLock);
fee = mulDiv(fee, mBaseRef, mBaseFee);
}
return fee;
}
uint32 LoadFeeTrack::getBaseFee()
{
boost::mutex::scoped_lock sl(mLock);
return mBaseFee;
}
uint32 LoadFeeTrack::getRemoteFee()
{
boost::mutex::scoped_lock sl(mLock);
return mRemoteTxnLoadFee;
}
uint32 LoadFeeTrack::getLocalFee()
{
boost::mutex::scoped_lock sl(mLock);
return mLocalTxnLoadFee;
}
uint32 LoadFeeTrack::getBaseRef()
{
boost::mutex::scoped_lock sl(mLock);
return mBaseRef;
} }
void LoadFeeTrack::setRemoteFee(uint32 f) void LoadFeeTrack::setRemoteFee(uint32 f)
{ {
boost::mutex::scoped_lock sl(mLock);
mRemoteTxnLoadFee = f; mRemoteTxnLoadFee = f;
} }
void LoadFeeTrack::raiseLocalFee() void LoadFeeTrack::raiseLocalFee()
{ {
boost::mutex::scoped_lock sl(mLock);
if (mLocalTxnLoadFee < mLocalTxnLoadFee) // make sure this fee takes effect if (mLocalTxnLoadFee < mLocalTxnLoadFee) // make sure this fee takes effect
mLocalTxnLoadFee = mLocalTxnLoadFee; mLocalTxnLoadFee = mLocalTxnLoadFee;
@@ -160,10 +219,29 @@ void LoadFeeTrack::raiseLocalFee()
void LoadFeeTrack::lowerLocalFee() void LoadFeeTrack::lowerLocalFee()
{ {
boost::mutex::scoped_lock sl(mLock);
mLocalTxnLoadFee -= (mLocalTxnLoadFee / lftFeeDecFraction ); // reduce by 1/16th mLocalTxnLoadFee -= (mLocalTxnLoadFee / lftFeeDecFraction ); // reduce by 1/16th
if (mLocalTxnLoadFee < lftNormalFee) if (mLocalTxnLoadFee < lftNormalFee)
mLocalTxnLoadFee = lftNormalFee; mLocalTxnLoadFee = lftNormalFee;
} }
Json::Value LoadFeeTrack::getJson(int)
{
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(mBaseFee);
// load_fee = The cost to send a "reference" transaction now, in millionths of a Ripple
j["load_fee"] = Json::Value::UInt(
mulDiv(mBaseFee, std::max(mLocalTxnLoadFee, mRemoteTxnLoadFee), lftNormalFee));
}
return j;
}
// vim:ts=4 // vim:ts=4

View File

@@ -1,10 +1,12 @@
#ifndef LOADSOURCE__H #ifndef LOADMANAGER__H
#define LOADSOURCE__H #define LOADMANAGER__H
#include <vector> #include <vector>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include "../json/value.h"
#include "types.h" #include "types.h"
enum LoadType enum LoadType
@@ -121,15 +123,30 @@ protected:
static const int lftFeeDecFraction = 16; // decrease fee by 1/16 static const int lftFeeDecFraction = 16; // decrease fee by 1/16
static const int lftFeeMax = lftNormalFee * 1000000; static const int lftFeeMax = lftNormalFee * 1000000;
uint32 mBaseRef; // The number of fee units a reference transaction costs
uint32 mBaseFee; // The cost in millionths of a ripple of a reference transaction
uint32 mLocalTxnLoadFee; // Scale factor, lftNormalFee = normal fee uint32 mLocalTxnLoadFee; // Scale factor, lftNormalFee = normal fee
uint32 mRemoteTxnLoadFee; // Scale factor, lftNormalFee = normal fee uint32 mRemoteTxnLoadFee; // Scale factor, lftNormalFee = normal fee
boost::mutex mLock;
static uint64 mulDiv(uint64 value, uint32 mul, uint32 div);
public: public:
LoadFeeTrack() : mLocalTxnLoadFee(lftNormalFee), mRemoteTxnLoadFee(lftNormalFee) { ; } LoadFeeTrack() : mLocalTxnLoadFee(lftNormalFee), mRemoteTxnLoadFee(lftNormalFee) { ; }
uint64 scaleFee(uint64 fee); uint64 scaleFeeBase(uint64 fee); // Scale from fee units to millionths of a ripple
uint64 scaleFeeLoad(uint64 fee); // Scale using load as well as base rate
uint32 getRemoteFee();
uint32 getLocalFee();
uint32 getBaseRef();
uint32 getBaseFee();
Json::Value getJson(int);
void setBaseFee(uint32);
void setRemoteFee(uint32); void setRemoteFee(uint32);
void raiseLocalFee(); void raiseLocalFee();
void lowerLocalFee(); void lowerLocalFee();