mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Refactor LoadFeeTrack into ILoadFeeTrack, split DatabaseCon out from Application.h
Conflicts: src/cpp/ripple/Application.cpp
This commit is contained in:
@@ -113,6 +113,10 @@ namespace boost {
|
||||
// UInt256
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
// ripple_PlatformMacros.h
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
// VFALCO: TODO, remove this dependency!!!
|
||||
#include <openssl/dh.h> // for DiffieHellmanUtil
|
||||
#include <openssl/ripemd.h> // For HashUtilities
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#if (!defined(FORCE_NO_C11X) && (__cplusplus > 201100L)) || defined(FORCE_C11X)
|
||||
|
||||
// VFALCO: TODO, replace BIND_TYPE with a namespace lift
|
||||
|
||||
#define C11X
|
||||
#include <functional>
|
||||
#define UPTR_T std::unique_ptr
|
||||
@@ -36,8 +38,6 @@
|
||||
|
||||
#else
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#define UPTR_T std::auto_ptr
|
||||
#define MOVE_P(p) (p)
|
||||
#define BIND_TYPE boost::bind
|
||||
|
||||
@@ -124,12 +124,15 @@
|
||||
// New abstract interfaces
|
||||
#include "src/cpp/ripple/ripple_IFeatures.h"
|
||||
#include "src/cpp/ripple/ripple_IFeeVote.h"
|
||||
#include "src/cpp/ripple/ripple_ILoadFeeTrack.h"
|
||||
#include "src/cpp/ripple/FeatureTable.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// main
|
||||
#include "src/cpp/ripple/ripple_DatabaseCon.cpp"
|
||||
#include "src/cpp/ripple/Application.cpp"
|
||||
#include "src/cpp/ripple/LoadManager.cpp"
|
||||
|
||||
// contracts
|
||||
#include "src/cpp/ripple/Contract.cpp" // no log
|
||||
@@ -192,6 +195,7 @@
|
||||
// Implementation of interfaces
|
||||
|
||||
#include "src/cpp/ripple/ripple_FeeVote.cpp"
|
||||
#include "src/cpp/ripple/ripple_LoadFeeTrack.cpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
//#pragma warning (pop)
|
||||
|
||||
@@ -34,9 +34,10 @@
|
||||
#pragma warning (disable: 4535) // call requires /EHa
|
||||
#endif
|
||||
|
||||
#include "src/cpp/ripple/Application.h" // VFALCO: TODO Remove this dependency
|
||||
|
||||
#include "src/cpp/ripple/Config.cpp" // no log
|
||||
#include "src/cpp/ripple/JobQueue.cpp"
|
||||
#include "src/cpp/ripple/LoadManager.cpp"
|
||||
#include "src/cpp/ripple/LoadMonitor.cpp"
|
||||
#include "src/cpp/ripple/UpdateTables.cpp"
|
||||
#include "src/cpp/ripple/main.cpp"
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include "../websocketpp/src/logger/logger.hpp" // for ripple_LogWebSockets.cpp
|
||||
|
||||
#include "src/cpp/ripple/ripple_ILoadFeeTrack.h" // for NetworkOPs
|
||||
|
||||
// VFALCO: TODO, fix these warnings!
|
||||
#ifdef _MSC_VER
|
||||
//#pragma warning (push) // Causes spurious C4503 "decorated name exceeds maximum length"
|
||||
|
||||
@@ -974,12 +974,24 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ripple_DatabaseCon.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ripple_FeeVote.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ripple_LoadFeeTrack.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\rpc.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@@ -1640,8 +1652,10 @@
|
||||
<ClInclude Include="src\cpp\ripple\RegularKeySetTransactor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RippleCalc.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RippleState.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ripple_DatabaseCon.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ripple_IFeatures.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ripple_IFeeVote.h" />
|
||||
<ClInclude Include="src\cpp\ripple\ripple_ILoadFeeTrack.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RPC.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RPCDoor.h" />
|
||||
<ClInclude Include="src\cpp\ripple\RPCErr.h" />
|
||||
|
||||
@@ -612,9 +612,6 @@
|
||||
<ClCompile Include="src\cpp\ripple\JobQueue.cpp">
|
||||
<Filter>1. Modules\ripple_main\_old</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LoadManager.cpp">
|
||||
<Filter>1. Modules\ripple_main\_old</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LoadMonitor.cpp">
|
||||
<Filter>1. Modules\ripple_main\_old</Filter>
|
||||
</ClCompile>
|
||||
@@ -792,6 +789,15 @@
|
||||
<ClCompile Include="src\cpp\ripple\Application.cpp">
|
||||
<Filter>1. Modules\ripple_ledger\main</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ripple_LoadFeeTrack.cpp">
|
||||
<Filter>1. Modules\ripple_ledger\main</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\LoadManager.cpp">
|
||||
<Filter>1. Modules\ripple_ledger\main</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\cpp\ripple\ripple_DatabaseCon.cpp">
|
||||
<Filter>1. Modules\ripple_ledger\main</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="database\sqlite3ext.h">
|
||||
@@ -1253,9 +1259,6 @@
|
||||
<ClInclude Include="src\cpp\ripple\JobQueue.h">
|
||||
<Filter>1. Modules\ripple_main\_old</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LoadManager.h">
|
||||
<Filter>1. Modules\ripple_main\_old</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LoadMonitor.h">
|
||||
<Filter>1. Modules\ripple_main\_old</Filter>
|
||||
</ClInclude>
|
||||
@@ -1472,6 +1475,15 @@
|
||||
<ClInclude Include="src\cpp\ripple\Application.h">
|
||||
<Filter>1. Modules\ripple_ledger\main</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\ripple_ILoadFeeTrack.h">
|
||||
<Filter>1. Modules\ripple_ledger\main</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\LoadManager.h">
|
||||
<Filter>1. Modules\ripple_ledger\main</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\cpp\ripple\ripple_DatabaseCon.h">
|
||||
<Filter>1. Modules\ripple_ledger\main</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="SConstruct" />
|
||||
|
||||
@@ -23,43 +23,42 @@ SETUP_LOG (Application)
|
||||
LogPartition AutoSocketPartition("AutoSocket");
|
||||
Application* theApp = NULL;
|
||||
|
||||
int DatabaseCon::sCount = 0;
|
||||
|
||||
DatabaseCon::DatabaseCon(const std::string& strName, const char *initStrings[], int initCount)
|
||||
Application::Application()
|
||||
: mIOService ((theConfig.NODE_SIZE >= 2) ? 2 : 1)
|
||||
, mIOWork (mIOService)
|
||||
, mAuxWork (mAuxService)
|
||||
, mUNL (mIOService)
|
||||
, mNetOps (mIOService, &mLedgerMaster)
|
||||
, mTempNodeCache ("NodeCache", 16384, 90)
|
||||
, mHashedObjectStore (16384, 300)
|
||||
, mSLECache ("LedgerEntryCache", 4096, 120)
|
||||
, mSNTPClient (mAuxService)
|
||||
, mJobQueue (mIOService)
|
||||
, mFeeVote (IFeeVote::New (10, 50 * SYSTEM_CURRENCY_PARTS, 12.5 * SYSTEM_CURRENCY_PARTS))
|
||||
, mFeeTrack (ILoadFeeTrack::New ())
|
||||
, mFeatureTable (2 * 7 * 24 * 60 * 60, 200) // two weeks, 200/256
|
||||
// VFALCO: TODO replace all NULL with nullptr
|
||||
, mRpcDB (NULL)
|
||||
, mTxnDB (NULL)
|
||||
, mLedgerDB (NULL)
|
||||
, mWalletDB (NULL) // VFALCO: NOTE, are all these 'NULL' ctor params necessary?
|
||||
, mNetNodeDB (NULL)
|
||||
, mPathFindDB (NULL)
|
||||
, mHashNodeDB (NULL)
|
||||
// VFALCO: TODO eliminate USE_LEVELDB macro
|
||||
#ifdef USE_LEVELDB
|
||||
, mHashNodeLDB (NULL)
|
||||
#endif
|
||||
, mConnectionPool (mIOService)
|
||||
, mPeerDoor (NULL)
|
||||
, mRPCDoor (NULL)
|
||||
, mWSPublicDoor (NULL)
|
||||
, mWSPrivateDoor (NULL)
|
||||
, mSweepTimer (mAuxService)
|
||||
, mShutdown (false)
|
||||
{
|
||||
++sCount;
|
||||
boost::filesystem::path pPath = (theConfig.RUN_STANDALONE && (theConfig.START_UP != Config::LOAD))
|
||||
? "" // Use temporary files.
|
||||
: (theConfig.DATA_DIR / strName); // Use regular db files.
|
||||
|
||||
mDatabase = new SqliteDatabase(pPath.string().c_str());
|
||||
mDatabase->connect();
|
||||
for(int i = 0; i < initCount; ++i)
|
||||
mDatabase->executeSQL(initStrings[i], true);
|
||||
}
|
||||
|
||||
DatabaseCon::~DatabaseCon()
|
||||
{
|
||||
mDatabase->disconnect();
|
||||
delete mDatabase;
|
||||
}
|
||||
|
||||
Application::Application() :
|
||||
mIOService((theConfig.NODE_SIZE >= 2) ? 2 : 1),
|
||||
mIOWork(mIOService), mAuxWork(mAuxService), mUNL(mIOService), mNetOps(mIOService, &mLedgerMaster),
|
||||
mTempNodeCache("NodeCache", 16384, 90), mHashedObjectStore(16384, 300), mSLECache("LedgerEntryCache", 4096, 120),
|
||||
mSNTPClient(mAuxService), mJobQueue(mIOService), mFeeTrack(),
|
||||
|
||||
mFeeVote (IFeeVote::New (10, 50 * SYSTEM_CURRENCY_PARTS, 12.5 * SYSTEM_CURRENCY_PARTS)),
|
||||
mFeatureTable(2 * 7 * 24 * 60 * 60, 200), // two weeks, 200/256
|
||||
|
||||
mRpcDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL),
|
||||
mNetNodeDB(NULL), mPathFindDB(NULL), mHashNodeDB(NULL), mHashNodeLDB(NULL), mEphemeralLDB(NULL),
|
||||
mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL), mWSPublicDoor(NULL), mWSPrivateDoor(NULL),
|
||||
mSweepTimer(mAuxService), mShutdown(false)
|
||||
{
|
||||
getRand(mNonce256.begin(), mNonce256.size());
|
||||
getRand(reinterpret_cast<unsigned char *>(&mNonceST), sizeof(mNonceST));
|
||||
getRand (mNonce256.begin(), mNonce256.size());
|
||||
getRand (reinterpret_cast<unsigned char *>(&mNonceST), sizeof(mNonceST));
|
||||
}
|
||||
|
||||
extern const char *RpcDBInit[], *TxnDBInit[], *LedgerDBInit[], *WalletDBInit[], *HashNodeDBInit[],
|
||||
@@ -414,6 +413,7 @@ void Application::sweep()
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
delete mFeeTrack;
|
||||
delete mFeeVote;
|
||||
delete mTxnDB;
|
||||
delete mLedgerDB;
|
||||
|
||||
@@ -27,30 +27,18 @@
|
||||
#include "TransactionQueue.h"
|
||||
#include "OrderBookDB.h"
|
||||
|
||||
#include "ripple_DatabaseCon.h"
|
||||
|
||||
// VFALCO: TODO, Fix forward declares required for header dependency loops
|
||||
class IFeatureTable;
|
||||
class IFeeVote;
|
||||
class ILoadFeeTrack;
|
||||
|
||||
class RPCDoor;
|
||||
class PeerDoor;
|
||||
typedef TaggedCache< uint256, std::vector<unsigned char>, UptimeTimerAdapter> NodeCache;
|
||||
typedef TaggedCache< uint256, SLE, UptimeTimerAdapter> SLECache;
|
||||
|
||||
class DatabaseCon
|
||||
{
|
||||
protected:
|
||||
Database* mDatabase;
|
||||
boost::recursive_mutex mLock;
|
||||
static int sCount;
|
||||
|
||||
public:
|
||||
DatabaseCon(const std::string& name, const char *initString[], int countInit);
|
||||
~DatabaseCon();
|
||||
Database* getDB() { return mDatabase; }
|
||||
boost::recursive_mutex& getDBLock() { return mLock; }
|
||||
static int getCount() { return sCount; }
|
||||
};
|
||||
|
||||
class Application
|
||||
{
|
||||
boost::asio::io_service mIOService, mAuxService;
|
||||
@@ -73,10 +61,10 @@ class Application
|
||||
JobQueue mJobQueue;
|
||||
ProofOfWorkGenerator mPOWGen;
|
||||
LoadManager mLoadMgr;
|
||||
LoadFeeTrack mFeeTrack;
|
||||
TXQueue mTxnQueue;
|
||||
OrderBookDB mOrderBookDB;
|
||||
IFeeVote* mFeeVote;
|
||||
ILoadFeeTrack* mFeeTrack;
|
||||
FeatureTable mFeatureTable;
|
||||
|
||||
DatabaseCon *mRpcDB, *mTxnDB, *mLedgerDB, *mWalletDB, *mNetNodeDB, *mPathFindDB, *mHashNodeDB;
|
||||
@@ -129,7 +117,7 @@ public:
|
||||
boost::recursive_mutex& getMasterLock() { return mMasterLock; }
|
||||
ProofOfWorkGenerator& getPowGen() { return mPOWGen; }
|
||||
LoadManager& getLoadManager() { return mLoadMgr; }
|
||||
LoadFeeTrack& getFeeTrack() { return mFeeTrack; }
|
||||
ILoadFeeTrack& getFeeTrack() { return *mFeeTrack; }
|
||||
TXQueue& getTxnQueue() { return mTxnQueue; }
|
||||
PeerDoor& getPeerDoor() { return *mPeerDoor; }
|
||||
OrderBookDB& getOrderBookDB() { return mOrderBookDB; }
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "HashPrefixes.h"
|
||||
|
||||
// VFALCO: TODO Rename and replace these macros with variables.
|
||||
#define SECTION_ACCOUNT_PROBE_MAX "account_probe_max"
|
||||
#define SECTION_CLUSTER_NODES "cluster_nodes"
|
||||
#define SECTION_DATABASE_PATH "database_path"
|
||||
|
||||
@@ -72,6 +72,8 @@ struct SizedItem
|
||||
int sizes[5];
|
||||
};
|
||||
|
||||
// VFALCO: TODO, rename all fields to not look like macros, and be more verbose
|
||||
// VFALCO: TODO, document every member
|
||||
class Config
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include "Config.h"
|
||||
#include "Application.h"
|
||||
|
||||
SETUP_LOG (JobQueue)
|
||||
|
||||
@@ -229,8 +228,9 @@ void JobQueue::shutdown()
|
||||
mJobCond.wait(sl);
|
||||
}
|
||||
|
||||
// set the number of thread serving the job queue to precisely this number
|
||||
void JobQueue::setThreadCount(int c)
|
||||
{ // set the number of thread serving the job queue to precisely this number
|
||||
{
|
||||
if (theConfig.RUN_STANDALONE)
|
||||
c = 1;
|
||||
else if (c == 0)
|
||||
@@ -287,8 +287,12 @@ void JobQueue::IOThread(boost::mutex::scoped_lock& sl)
|
||||
--mIOThreadCount;
|
||||
}
|
||||
|
||||
// do jobs until asked to stop
|
||||
void JobQueue::threadEntry()
|
||||
{ // do jobs until asked to stop
|
||||
{
|
||||
|
||||
// VFALCO: TODO, Replace this mutex nonsense
|
||||
//
|
||||
boost::mutex::scoped_lock sl(mJobLock);
|
||||
while (1)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -155,49 +155,6 @@ public:
|
||||
void arm() { mArmed = true; }
|
||||
};
|
||||
|
||||
class LoadFeeTrack
|
||||
{ // structure that tracks our current fee/load schedule
|
||||
protected:
|
||||
|
||||
static const int lftNormalFee = 256; // 256 is the minimum/normal load factor
|
||||
static const int lftFeeIncFraction = 16; // increase fee by 1/16
|
||||
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
|
||||
int raiseCount;
|
||||
|
||||
boost::mutex mLock;
|
||||
|
||||
static uint64 mulDiv(uint64 value, uint32 mul, uint64 div);
|
||||
|
||||
public:
|
||||
|
||||
LoadFeeTrack() : mLocalTxnLoadFee(lftNormalFee), mRemoteTxnLoadFee(lftNormalFee), raiseCount(0)
|
||||
{ ; }
|
||||
|
||||
// Scale from fee units to millionths of a ripple
|
||||
uint64 scaleFeeBase(uint64 fee, uint64 baseFee, uint32 referenceFeeUnits);
|
||||
|
||||
// Scale using load as well as base rate
|
||||
uint64 scaleFeeLoad(uint64 fee, uint64 baseFee, uint32 referenceFeeUnits, bool bAdmin);
|
||||
|
||||
uint32 getRemoteFee();
|
||||
uint32 getLocalFee();
|
||||
|
||||
uint32 getLoadBase() { return lftNormalFee; }
|
||||
uint32 getLoadFactor();
|
||||
|
||||
Json::Value getJson(uint64 baseFee, uint32 referenceFeeUnits);
|
||||
|
||||
void setRemoteFee(uint32);
|
||||
bool raiseLocalFee();
|
||||
bool lowerLocalFee();
|
||||
bool isLoaded();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// vim:ts=4
|
||||
|
||||
21
src/cpp/ripple/ripple_DatabaseCon.cpp
Normal file
21
src/cpp/ripple/ripple_DatabaseCon.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
int DatabaseCon::sCount = 0;
|
||||
|
||||
DatabaseCon::DatabaseCon(const std::string& strName, const char *initStrings[], int initCount)
|
||||
{
|
||||
++sCount;
|
||||
boost::filesystem::path pPath = (theConfig.RUN_STANDALONE && (theConfig.START_UP != Config::LOAD))
|
||||
? "" // Use temporary files.
|
||||
: (theConfig.DATA_DIR / strName); // Use regular db files.
|
||||
|
||||
mDatabase = new SqliteDatabase(pPath.string().c_str());
|
||||
mDatabase->connect();
|
||||
for(int i = 0; i < initCount; ++i)
|
||||
mDatabase->executeSQL(initStrings[i], true);
|
||||
}
|
||||
|
||||
DatabaseCon::~DatabaseCon()
|
||||
{
|
||||
mDatabase->disconnect();
|
||||
delete mDatabase;
|
||||
}
|
||||
24
src/cpp/ripple/ripple_DatabaseCon.h
Normal file
24
src/cpp/ripple/ripple_DatabaseCon.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef RIPPLE_DATABASECON_H
|
||||
#define RIPPLE_DATABASECON_H
|
||||
|
||||
// VFALCO: NOTE This looks like a pointless class. Figure out
|
||||
// what purpose it is really trying to serve and do it better.
|
||||
class DatabaseCon
|
||||
{
|
||||
public:
|
||||
DatabaseCon (const std::string& name, const char *initString[], int countInit);
|
||||
~DatabaseCon ();
|
||||
Database* getDB () { return mDatabase; }
|
||||
boost::recursive_mutex& getDBLock() { return mLock; }
|
||||
static int getCount() { return sCount; }
|
||||
|
||||
// VFALCO: TODO, change "protected" to "private" throughout the code
|
||||
private:
|
||||
Database* mDatabase;
|
||||
// VFALCO: TODO replace these with a single atomic counter.
|
||||
boost::recursive_mutex mLock;
|
||||
static int sCount;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
35
src/cpp/ripple/ripple_ILoadFeeTrack.h
Normal file
35
src/cpp/ripple/ripple_ILoadFeeTrack.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef RIPPLE_ILOADFEETRACK_H
|
||||
#define RIPPLE_ILOADFEETRACK_H
|
||||
|
||||
/** Tracks the current fee and load schedule.
|
||||
*/
|
||||
class ILoadFeeTrack
|
||||
{
|
||||
public:
|
||||
static ILoadFeeTrack* New ();
|
||||
|
||||
virtual ~ILoadFeeTrack () { }
|
||||
|
||||
// Scale from fee units to millionths of a ripple
|
||||
virtual uint64 scaleFeeBase (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits) = 0;
|
||||
|
||||
// Scale using load as well as base rate
|
||||
virtual uint64 scaleFeeLoad (uint64 fee, uint64 baseFee, uint32 referenceFeeUnits, bool bAdmin) = 0;
|
||||
|
||||
virtual uint32 getRemoteFee () = 0;
|
||||
virtual uint32 getLocalFee () = 0;
|
||||
|
||||
virtual uint32 getLoadBase () = 0;
|
||||
virtual uint32 getLoadFactor () = 0;
|
||||
|
||||
virtual Json::Value getJson (uint64 baseFee, uint32 referenceFeeUnits) = 0;
|
||||
|
||||
virtual void setRemoteFee (uint32) = 0;
|
||||
virtual bool raiseLocalFee () = 0;
|
||||
virtual bool lowerLocalFee () = 0;
|
||||
virtual bool isLoaded () = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// vim:ts=4
|
||||
205
src/cpp/ripple/ripple_LoadFeeTrack.cpp
Normal file
205
src/cpp/ripple/ripple_LoadFeeTrack.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
//#include <boost/test/unit_test.hpp>
|
||||
//#include <boost/thread.hpp>
|
||||
//#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
//#include "Config.h"
|
||||
//#include "Application.h"
|
||||
|
||||
class LoadFeeTrack : public ILoadFeeTrack
|
||||
{
|
||||
private:
|
||||
static const int lftNormalFee = 256; // 256 is the minimum/normal load factor
|
||||
static const int lftFeeIncFraction = 16; // increase fee by 1/16
|
||||
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
|
||||
int raiseCount;
|
||||
|
||||
boost::mutex mLock;
|
||||
|
||||
// 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)
|
||||
{
|
||||
static uint64 boundary = (0x00000000FFFFFFFF);
|
||||
if (value > boundary) // Large value, avoid overflow
|
||||
return (value / div) * mul;
|
||||
else // Normal value, preserve accuracy
|
||||
return (value * mul) / div;
|
||||
}
|
||||
|
||||
public:
|
||||
LoadFeeTrack()
|
||||
: mLocalTxnLoadFee (lftNormalFee)
|
||||
, mRemoteTxnLoadFee (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
|
||||
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;
|
||||
}
|
||||
|
||||
// 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(mLocalTxnLoadFee, mRemoteTxnLoadFee);
|
||||
}
|
||||
|
||||
bool isLoaded()
|
||||
{
|
||||
boost::mutex::scoped_lock sl(mLock);
|
||||
return (raiseCount != 0) || (mLocalTxnLoadFee != 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;
|
||||
}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
ILoadFeeTrack* ILoadFeeTrack::New ()
|
||||
{
|
||||
return new LoadFeeTrack;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user