Refactor LoadFeeTrack into ILoadFeeTrack, split DatabaseCon out from Application.h

Conflicts:
	src/cpp/ripple/Application.cpp
This commit is contained in:
Vinnie Falco
2013-06-01 08:30:46 -07:00
parent f897b17027
commit ec732ed113
18 changed files with 394 additions and 267 deletions

View File

@@ -186,137 +186,6 @@ bool LoadManager::adjust(LoadSource& source, int credits) const
return true;
}
uint64 LoadFeeTrack::mulDiv(uint64 value, uint32 mul, uint64 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, 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
if (bAdmin && (feeFactor > mRemoteTxnLoadFee) && (feeFactor < (4 * mRemoteTxnLoadFee)))
feeFactor = mRemoteTxnLoadFee;
{
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;
}
uint64 LoadFeeTrack::scaleFeeBase(uint64 fee, uint64 baseFee, uint32 referenceFeeUnits)
{
return mulDiv(fee, referenceFeeUnits, baseFee);
}
uint32 LoadFeeTrack::getRemoteFee()
{
boost::mutex::scoped_lock sl(mLock);
return mRemoteTxnLoadFee;
}
uint32 LoadFeeTrack::getLocalFee()
{
boost::mutex::scoped_lock sl(mLock);
return mLocalTxnLoadFee;
}
uint32 LoadFeeTrack::getLoadFactor()
{
boost::mutex::scoped_lock sl(mLock);
return std::max(mLocalTxnLoadFee, mRemoteTxnLoadFee);
}
void LoadFeeTrack::setRemoteFee(uint32 f)
{
boost::mutex::scoped_lock sl(mLock);
mRemoteTxnLoadFee = f;
}
bool LoadFeeTrack::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 LoadFeeTrack::isLoaded()
{
boost::mutex::scoped_lock sl(mLock);
return (raiseCount != 0) || (mLocalTxnLoadFee != lftNormalFee);
}
bool LoadFeeTrack::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 LoadFeeTrack::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;
}
static void LogDeadLock(int dlTime)
{
WriteLog (lsWARNING, LoadManager) << "Server stalled for " << dlTime << " seconds.";
@@ -324,7 +193,9 @@ static void LogDeadLock(int dlTime)
void LoadManager::threadEntry()
{
setCallingThreadName("loadmgr");
setCallingThreadName ("loadmgr");
// VFALCO: TODO replace this with a beast Time object
boost::posix_time::ptime t = boost::posix_time::microsec_clock::universal_time();
while (1)
{
@@ -351,6 +222,8 @@ void LoadManager::threadEntry()
}
// VFALCO: TODO Eliminate the dependence on the Application object by
// constructing with the job queue and the fee tracker.
bool change;
if (theApp->getJobQueue().isOverloaded())
{
@@ -358,9 +231,15 @@ void LoadManager::threadEntry()
change = theApp->getFeeTrack().raiseLocalFee();
}
else
{
change = theApp->getFeeTrack().lowerLocalFee();
if (change)
}
if (change)
{
// VFALCO: TODO replace this with a Listener / observer and subscribe in NetworkOPs or Application
theApp->getOPs().reportFeeChange();
}
t += boost::posix_time::seconds(1);
boost::posix_time::time_duration when = t - boost::posix_time::microsec_clock::universal_time();
@@ -391,30 +270,4 @@ void LoadManager::logDisconnect(const std::string& source) const
WriteLog (lsWARNING, LoadManager) << "Disconnect for: " << source;
}
BOOST_AUTO_TEST_SUITE(LoadManager_test)
BOOST_AUTO_TEST_CASE(LoadFeeTrack_test)
{
WriteLog (lsDEBUG, LoadManager) << "Running load fee track test";
Config d; // get a default configuration object
LoadFeeTrack l;
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(10000, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 10000);
BOOST_REQUIRE_EQUAL(l.scaleFeeLoad(10000, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE, false), 10000);
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(1, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 1);
BOOST_REQUIRE_EQUAL(l.scaleFeeLoad(1, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE, false), 1);
// Check new default fee values give same fees as old defaults
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_DEFAULT, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 10);
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_ACCOUNT_RESERVE, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 200 * SYSTEM_CURRENCY_PARTS);
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_OWNER_RESERVE, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 50 * SYSTEM_CURRENCY_PARTS);
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_NICKNAME_CREATE, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 1000);
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_OFFER, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 10);
BOOST_REQUIRE_EQUAL(l.scaleFeeBase(d.FEE_CONTRACT_OPERATION, d.FEE_DEFAULT, d.TRANSACTION_FEE_BASE), 1);
}
BOOST_AUTO_TEST_SUITE_END()
// vim:ts=4