diff --git a/ripple2010.vcxproj b/ripple2010.vcxproj
index dbb3dd84b..085035df9 100644
--- a/ripple2010.vcxproj
+++ b/ripple2010.vcxproj
@@ -109,6 +109,7 @@
+
@@ -295,8 +296,9 @@
Designer
-
+
+
Document
@@ -307,7 +309,7 @@
-
+
diff --git a/src/cpp/database/SqliteDatabase.cpp b/src/cpp/database/SqliteDatabase.cpp
index 1033dcf4e..7db0a623f 100644
--- a/src/cpp/database/SqliteDatabase.cpp
+++ b/src/cpp/database/SqliteDatabase.cpp
@@ -234,6 +234,7 @@ void SqliteDatabase::runWal()
std::set walSet;
std::string name = sqlite3_db_filename(mConnection, "main");
+ int pass = 1;
while (1)
{
{
@@ -255,8 +256,11 @@ void SqliteDatabase::runWal()
cLog((ret == SQLITE_LOCKED) ? lsTRACE : lsWARNING) << "WAL " << mHost << ":"
<< db << " error " << ret;
}
+ else
+ cLog(lsTRACE) << "WAL(" << mHost << "): pass=" << pass << ", frames=" << log << ", written=" << ckpt;
}
walSet.clear();
+ ++pass;
}
}
diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp
index cc417257c..f0c360265 100644
--- a/src/cpp/ripple/Application.cpp
+++ b/src/cpp/ripple/Application.cpp
@@ -26,9 +26,9 @@ Application* theApp = NULL;
DatabaseCon::DatabaseCon(const std::string& strName, const char *initStrings[], int initCount)
{
- boost::filesystem::path pPath = theConfig.RUN_STANDALONE && !Config::LOAD
+ boost::filesystem::path pPath = (theConfig.RUN_STANDALONE && (!theConfig.START_UP != Config::LOAD))
? "" // Use temporary files.
- : theConfig.DATA_DIR / strName; // Use regular db files.
+ : (theConfig.DATA_DIR / strName); // Use regular db files.
mDatabase = new SqliteDatabase(pPath.string().c_str());
mDatabase->connect();
@@ -45,7 +45,7 @@ DatabaseCon::~DatabaseCon()
Application::Application() :
mIOWork(mIOService), mAuxWork(mAuxService), mUNL(mIOService), mNetOps(mIOService, &mLedgerMaster),
mTempNodeCache("NodeCache", 16384, 90), mHashedObjectStore(16384, 300), mSLECache("LedgerEntryCache", 4096, 120),
- mSNTPClient(mAuxService), mRPCHandler(&mNetOps), mFeeTrack(),
+ mSNTPClient(mAuxService), mFeeTrack(),
mRpcDB(NULL), mTxnDB(NULL), mLedgerDB(NULL), mWalletDB(NULL), mHashNodeDB(NULL), mNetNodeDB(NULL),
mConnectionPool(mIOService), mPeerDoor(NULL), mRPCDoor(NULL), mWSPublicDoor(NULL), mWSPrivateDoor(NULL),
mSweepTimer(mAuxService), mShutdown(false)
diff --git a/src/cpp/ripple/Application.h b/src/cpp/ripple/Application.h
index cafa5b7c7..48e58d97a 100644
--- a/src/cpp/ripple/Application.h
+++ b/src/cpp/ripple/Application.h
@@ -64,7 +64,6 @@ class Application
SLECache mSLECache;
SNTPClient mSNTPClient;
JobQueue mJobQueue;
- RPCHandler mRPCHandler;
ProofOfWorkGenerator mPOWGen;
LoadManager mLoadMgr;
LoadFeeTrack mFeeTrack;
@@ -114,7 +113,6 @@ public:
ValidationCollection& getValidations() { return mValidations; }
JobQueue& getJobQueue() { return mJobQueue; }
SuppressionTable& getSuppression() { return mSuppressions; }
- RPCHandler& getRPCHandler() { return mRPCHandler; }
boost::recursive_mutex& getMasterLock() { return mMasterLock; }
ProofOfWorkGenerator& getPowGen() { return mPOWGen; }
LoadManager& getLoadManager() { return mLoadMgr; }
diff --git a/src/cpp/ripple/LoadManager.cpp b/src/cpp/ripple/LoadManager.cpp
index 87b2237a4..1eaad6c6b 100644
--- a/src/cpp/ripple/LoadManager.cpp
+++ b/src/cpp/ripple/LoadManager.cpp
@@ -132,24 +132,31 @@ void LoadManager::canonicalize(LoadSource& source, int now) const
bool LoadManager::shouldWarn(LoadSource& source) const
{
- boost::mutex::scoped_lock sl(mLock);
+ {
+ boost::mutex::scoped_lock sl(mLock);
- int now = upTime();
- canonicalize(source, now);
- if (source.isPrivileged() || (source.mBalance < mDebitWarn) || (source.mLastWarning == now))
- return false;
+ int now = upTime();
+ canonicalize(source, now);
+ if (source.isPrivileged() || (source.mBalance < mDebitWarn) || (source.mLastWarning == now))
+ return false;
- source.mLastWarning = now;
+ source.mLastWarning = now;
+ }
+ logWarning(source.getName());
return true;
}
bool LoadManager::shouldCutoff(LoadSource& source) const
{
- boost::mutex::scoped_lock sl(mLock);
-
- int now = upTime();
- canonicalize(source, now);
- return !source.isPrivileged() && (source.mBalance < mDebitLimit);
+ {
+ boost::mutex::scoped_lock sl(mLock);
+ int now = upTime();
+ canonicalize(source, now);
+ if (!source.isPrivileged() || (source.mBalance > mDebitLimit))
+ return false;
+ }
+ logDisconnect(source.getName());
+ return true;
}
bool LoadManager::adjust(LoadSource& source, LoadType t) const
@@ -160,7 +167,6 @@ bool LoadManager::adjust(LoadSource& source, LoadType t) const
bool LoadManager::adjust(LoadSource& source, int credits) const
{ // return: true = need to warn/cutoff
- boost::mutex::scoped_lock sl(mLock);
// We do it this way in case we want to add exponential decay later
int now = upTime();
@@ -172,13 +178,10 @@ bool LoadManager::adjust(LoadSource& source, int credits) const
if (source.isPrivileged()) // privileged sources never warn/cutoff
return false;
- if (source.mBalance < mDebitLimit) // over-limit
- return true;
+ if ((source.mBalance >= mDebitLimit) && (source.mLastWarning == now)) // no need to warn
+ return false;
- if ((source.mBalance < mDebitWarn) && (source.mLastWarning != now)) // need to warn
- return true;
-
- return false;
+ return true;
}
uint64 LoadFeeTrack::mulDiv(uint64 value, uint32 mul, uint64 div)
@@ -345,6 +348,22 @@ void LoadManager::threadEntry()
}
}
+void LoadManager::logWarning(const std::string& source) const
+{
+ if (source.empty())
+ cLog(lsDEBUG) << "Load warning from empty source";
+ else
+ cLog(lsINFO) << "Load warning: " << source;
+}
+
+void LoadManager::logDisconnect(const std::string& source) const
+{
+ if (source.empty())
+ cLog(lsINFO) << "Disconnect for empty source";
+ else
+ cLog(lsWARNING) << "Disconnect for: " << source;
+}
+
BOOST_AUTO_TEST_SUITE(LoadManager_test)
BOOST_AUTO_TEST_CASE(LoadFeeTrack_test)
diff --git a/src/cpp/ripple/LoadManager.h b/src/cpp/ripple/LoadManager.h
index 55796ea02..070384d70 100644
--- a/src/cpp/ripple/LoadManager.h
+++ b/src/cpp/ripple/LoadManager.h
@@ -61,14 +61,20 @@ public:
static const int lsfOutbound = 2; // outbound connection
protected:
- int mBalance;
- int mFlags;
- int mLastUpdate;
- int mLastWarning;
+ std::string mName;
+ int mBalance;
+ int mFlags;
+ int mLastUpdate;
+ int mLastWarning;
public:
- LoadSource() : mBalance(0), mFlags(0), mLastWarning(0)
- { mLastUpdate = upTime(); }
+ LoadSource(bool admin) : mBalance(0), mFlags(admin ? lsfPrivileged : 0), mLastUpdate(upTime()), mLastWarning(0)
+ { ; }
+ LoadSource(const std::string& name) : mName(name), mBalance(0), mFlags(0), mLastUpdate(upTime()), mLastWarning(0)
+ { ; }
+
+ void rename(const std::string& name) { mName = name; }
+ const std::string& getName() { return mName; }
bool isPrivileged() const { return (mFlags & lsfPrivileged) != 0; }
void setPrivileged() { mFlags |= lsfPrivileged; }
@@ -106,7 +112,7 @@ protected:
public:
- LoadManager(int creditRate = 10, int creditLimit = 50, int debitWarn = -50, int debitLimit = -100);
+ LoadManager(int creditRate = 100, int creditLimit = 500, int debitWarn = -500, int debitLimit = -1000);
~LoadManager();
void init();
@@ -124,6 +130,9 @@ public:
bool adjust(LoadSource&, int credits) const; // return value: false=balance okay, true=warn/cutoff
bool adjust(LoadSource&, LoadType l) const;
+ void logWarning(const std::string&) const;
+ void logDisconnect(const std::string&) const;
+
int getCost(LoadType t) { return mCosts[static_cast(t)].mCost; }
int getUptime();
};
diff --git a/src/cpp/ripple/Peer.cpp b/src/cpp/ripple/Peer.cpp
index 62bc160cf..991afb52d 100644
--- a/src/cpp/ripple/Peer.cpp
+++ b/src/cpp/ripple/Peer.cpp
@@ -34,6 +34,8 @@ Peer::Peer(boost::asio::io_service& io_service, boost::asio::ssl::context& ctx,
mActive(2),
mCluster(false),
mPeerId(peerID),
+ mPrivate(false),
+ mLoad(""),
mSocketSsl(io_service, ctx),
mActivityTimer(io_service)
{
@@ -77,6 +79,7 @@ void Peer::handleWrite(const boost::system::error_code& error, size_t bytes_tran
void Peer::setIpPort(const std::string& strIP, int iPort)
{
mIpPort = make_pair(strIP, iPort);
+ mLoad.rename(strIP);
cLog(lsDEBUG) << "Peer: Set: "
<< ADDRESS(this) << "> "
diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp
index 43916603f..76d135017 100644
--- a/src/cpp/ripple/RPCHandler.cpp
+++ b/src/cpp/ripple/RPCHandler.cpp
@@ -25,6 +25,10 @@
SETUP_LOG();
+static const int rpcCOST_DEFAULT = 10;
+static const int rpcCOST_EXCEPTION = 20;
+static const int rpcCOST_EXPENSIVE = 50;
+
int iAdminGet(const Json::Value& jvRequest, const std::string& strRemoteIp)
{
int iRole;
@@ -63,15 +67,11 @@ int iAdminGet(const Json::Value& jvRequest, const std::string& strRemoteIp)
return iRole;
}
-RPCHandler::RPCHandler(NetworkOPs* netOps)
-{
- mNetOps = netOps;
-}
+RPCHandler::RPCHandler(NetworkOPs* netOps) : mNetOps(netOps)
+{ ; }
-RPCHandler::RPCHandler(NetworkOPs* netOps, InfoSub::pointer infoSub) : mInfoSub(infoSub)
-{
- mNetOps = netOps;
-}
+RPCHandler::RPCHandler(NetworkOPs* netOps, InfoSub::pointer infoSub) : mNetOps(netOps), mInfoSub(infoSub)
+{ ; }
Json::Value RPCHandler::transactionSign(Json::Value jvRequest, bool bSubmit)
{
@@ -565,7 +565,7 @@ Json::Value RPCHandler::accountFromString(Ledger::ref lrLedger, RippleAddress& n
// ledger_hash :
// ledger_index :
// }
-Json::Value RPCHandler::doAccountInfo(Json::Value jvRequest)
+Json::Value RPCHandler::doAccountInfo(Json::Value jvRequest, int& cost)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger(jvRequest, lpLedger);
@@ -610,7 +610,7 @@ Json::Value RPCHandler::doAccountInfo(Json::Value jvRequest)
// port:
// }
// XXX Might allow domain for manual connections.
-Json::Value RPCHandler::doConnect(Json::Value jvRequest)
+Json::Value RPCHandler::doConnect(Json::Value jvRequest, int& cost)
{
if (theConfig.RUN_STANDALONE)
return "cannot connect in standalone mode";
@@ -631,7 +631,7 @@ Json::Value RPCHandler::doConnect(Json::Value jvRequest)
// {
// key:
// }
-Json::Value RPCHandler::doDataDelete(Json::Value jvRequest)
+Json::Value RPCHandler::doDataDelete(Json::Value jvRequest, int& cost)
{
if (!jvRequest.isMember("key"))
return rpcError(rpcINVALID_PARAMS);
@@ -657,7 +657,7 @@ Json::Value RPCHandler::doDataDelete(Json::Value jvRequest)
// {
// key:
// }
-Json::Value RPCHandler::doDataFetch(Json::Value jvRequest)
+Json::Value RPCHandler::doDataFetch(Json::Value jvRequest, int& cost)
{
if (!jvRequest.isMember("key"))
return rpcError(rpcINVALID_PARAMS);
@@ -680,7 +680,7 @@ Json::Value RPCHandler::doDataFetch(Json::Value jvRequest)
// key:
// value:
// }
-Json::Value RPCHandler::doDataStore(Json::Value jvRequest)
+Json::Value RPCHandler::doDataStore(Json::Value jvRequest, int& cost)
{
if (!jvRequest.isMember("key")
|| !jvRequest.isMember("value"))
@@ -740,7 +740,7 @@ Json::Value RPCHandler::doNicknameInfo(Json::Value params)
// 'account_index' : // optional
// }
// XXX This would be better if it took the ledger.
-Json::Value RPCHandler::doOwnerInfo(Json::Value jvRequest)
+Json::Value RPCHandler::doOwnerInfo(Json::Value jvRequest, int& cost)
{
if (!jvRequest.isMember("account") && !jvRequest.isMember("ident"))
return rpcError(rpcINVALID_PARAMS);
@@ -765,7 +765,7 @@ Json::Value RPCHandler::doOwnerInfo(Json::Value jvRequest)
return ret;
}
-Json::Value RPCHandler::doPeers(Json::Value)
+Json::Value RPCHandler::doPeers(Json::Value, int& cost)
{
Json::Value jvResult(Json::objectValue);
@@ -774,7 +774,7 @@ Json::Value RPCHandler::doPeers(Json::Value)
return jvResult;
}
-Json::Value RPCHandler::doPing(Json::Value)
+Json::Value RPCHandler::doPing(Json::Value, int& cost)
{
return Json::Value(Json::objectValue);
}
@@ -784,7 +784,7 @@ Json::Value RPCHandler::doPing(Json::Value)
// issuer is the offering account
// --> submit: 'submit|true|false': defaults to false
// Prior to running allow each to have a credit line of what they will be getting from the other account.
-Json::Value RPCHandler::doProfile(Json::Value jvRequest)
+Json::Value RPCHandler::doProfile(Json::Value jvRequest, int& cost)
{
/* need to fix now that sharedOfferCreate is gone
int iArgs = jvRequest.size();
@@ -877,7 +877,7 @@ Json::Value RPCHandler::doProfile(Json::Value jvRequest)
// ledger_hash :
// ledger_index :
// }
-Json::Value RPCHandler::doAccountLines(Json::Value jvRequest)
+Json::Value RPCHandler::doAccountLines(Json::Value jvRequest, int& cost)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger(jvRequest, lpLedger);
@@ -956,7 +956,7 @@ Json::Value RPCHandler::doAccountLines(Json::Value jvRequest)
// ledger_hash :
// ledger_index :
// }
-Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest)
+Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest, int& cost)
{
Ledger::pointer lpLedger;
Json::Value jvResult = lookupLedger(jvRequest, lpLedger);
@@ -1027,7 +1027,7 @@ Json::Value RPCHandler::doAccountOffers(Json::Value jvRequest)
// "limit" : integer, // Optional.
// "proof" : boolean // Defaults to false.
// }
-Json::Value RPCHandler::doBookOffers(Json::Value jvRequest)
+Json::Value RPCHandler::doBookOffers(Json::Value jvRequest, int& cost)
{
if (theApp->getJobQueue().getJobCountGE(jtCLIENT) > 200)
{
@@ -1124,7 +1124,7 @@ Json::Value RPCHandler::doBookOffers(Json::Value jvRequest)
// {
// random:
// }
-Json::Value RPCHandler::doRandom(Json::Value jvRequest)
+Json::Value RPCHandler::doRandom(Json::Value jvRequest, int& cost)
{
uint256 uRandom;
@@ -1150,7 +1150,7 @@ Json::Value RPCHandler::doRandom(Json::Value jvRequest)
// - Allows clients to verify path exists.
// - Return canonicalized path.
// - From a trusted server, allows clients to use path without manipulation.
-Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest)
+Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest, int& cost)
{
RippleAddress raSrc;
RippleAddress raDst;
@@ -1230,6 +1230,7 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest)
}
}
+ cost = rpcCOST_EXPENSIVE;
Ledger::pointer lSnapShot = boost::make_shared(boost::ref(*lpLedger), false);
LedgerEntrySet lesSnapshot(lSnapShot);
@@ -1363,8 +1364,9 @@ Json::Value RPCHandler::doRipplePathFind(Json::Value jvRequest)
// tx_json: