diff --git a/src/cpp/ripple/LoadManager.cpp b/src/cpp/ripple/LoadManager.cpp index f8047af15..7956ca141 100644 --- a/src/cpp/ripple/LoadManager.cpp +++ b/src/cpp/ripple/LoadManager.cpp @@ -131,24 +131,83 @@ bool LoadManager::adjust(LoadSource& source, int credits) const 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); - int factor = (mLocalTxnLoadFee > mRemoteTxnLoadFee) ? mLocalTxnLoadFee : mRemoteTxnLoadFee; + bool big = (fee > midrange); - if (fee > midrange) // large fee, divide first - return (fee / lftNormalFee) * factor; - else // small fee, multiply first - return (fee * factor) / lftNormalFee; + { + boost::mutex::scoped_lock sl(mLock); + + 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) { + boost::mutex::scoped_lock sl(mLock); mRemoteTxnLoadFee = f; } void LoadFeeTrack::raiseLocalFee() { + boost::mutex::scoped_lock sl(mLock); if (mLocalTxnLoadFee < mLocalTxnLoadFee) // make sure this fee takes effect mLocalTxnLoadFee = mLocalTxnLoadFee; @@ -160,10 +219,29 @@ void LoadFeeTrack::raiseLocalFee() void LoadFeeTrack::lowerLocalFee() { + boost::mutex::scoped_lock sl(mLock); mLocalTxnLoadFee -= (mLocalTxnLoadFee / lftFeeDecFraction ); // reduce by 1/16th if (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 diff --git a/src/cpp/ripple/LoadManager.h b/src/cpp/ripple/LoadManager.h index 71eb79d39..c96a8b447 100644 --- a/src/cpp/ripple/LoadManager.h +++ b/src/cpp/ripple/LoadManager.h @@ -1,10 +1,12 @@ -#ifndef LOADSOURCE__H -#define LOADSOURCE__H +#ifndef LOADMANAGER__H +#define LOADMANAGER__H #include #include +#include "../json/value.h" + #include "types.h" enum LoadType @@ -121,15 +123,30 @@ protected: static const int lftFeeDecFraction = 16; // decrease fee by 1/16 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 mRemoteTxnLoadFee; // Scale factor, lftNormalFee = normal fee + boost::mutex mLock; + + static uint64 mulDiv(uint64 value, uint32 mul, uint32 div); + public: 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 raiseLocalFee(); void lowerLocalFee();