Merge branch 'master' of github.com:jedmccaleb/NewCoin

This commit is contained in:
Arthur Britto
2013-01-14 17:00:25 -08:00
19 changed files with 248 additions and 185 deletions

View File

@@ -54,6 +54,7 @@ Application::Application() :
extern const char *RpcDBInit[], *TxnDBInit[], *LedgerDBInit[], *WalletDBInit[], *HashNodeDBInit[], *NetNodeDBInit[];
extern int RpcDBCount, TxnDBCount, LedgerDBCount, WalletDBCount, HashNodeDBCount, NetNodeDBCount;
bool Instance::running = true;
void Application::stop()
{
@@ -65,6 +66,7 @@ void Application::stop()
mAuxService.stop();
cLog(lsINFO) << "Stopped: " << mIOService.stopped();
Instance::shutdown();
}
static void InitDB(DatabaseCon** dbCon, const char *fileName, const char *dbInit[], int dbCount)

View File

@@ -53,7 +53,23 @@ std::string EncodeBase64(const std::string& s)
Json::Value RPCParser::parseAsIs(const Json::Value& jvParams)
{
return Json::Value(Json::objectValue);
Json::Value v(Json::objectValue);
if (jvParams.isArray() && (jvParams.size() > 0))
v["params"] = jvParams;
return v;
}
Json::Value RPCParser::parseInternal(const Json::Value& jvParams)
{
Json::Value v(Json::objectValue);
v["internal_command"] = jvParams[0u];
Json::Value params(Json::arrayValue);
for (unsigned i = 1; i < jvParams.size(); ++i)
params.append(jvParams[i]);
v["params"] = params;
return v;
}
// account_info <account>|<nickname>|<account_public_key>
@@ -496,6 +512,8 @@ Json::Value RPCParser::parseCommand(std::string strMethod, Json::Value jvParams)
{ "wallet_propose", &RPCParser::parseWalletPropose, 0, 1 },
{ "wallet_seed", &RPCParser::parseWalletSeed, 0, 1 },
{ "internal", &RPCParser::parseInternal, 1, -1 },
#if ENABLE_INSECURE
// XXX Unnecessary commands which should be removed.
{ "login", &RPCParser::parseLogin, 2, 2 },

View File

@@ -23,6 +23,7 @@ protected:
Json::Value parseEvented(const Json::Value& jvParams);
Json::Value parseGetCounts(const Json::Value& jvParams);
Json::Value parseLedger(const Json::Value& jvParams);
Json::Value parseInternal(const Json::Value& jvParams);
#if ENABLE_INSECURE
Json::Value parseLogin(const Json::Value& jvParams);
#endif

View File

@@ -86,11 +86,13 @@ public:
class Instance
{
protected:
static bool running;
InstanceType& mType;
public:
Instance(InstanceType& t) : mType(t) { mType.addInstance(); }
~Instance() { mType.decInstance(); }
~Instance() { if (running) mType.decInstance(); }
static void shutdown() { running = false; }
};
#endif

View File

@@ -17,7 +17,7 @@ protected:
const std::string mName;
boost::mutex mNCLock;
map_type mCache;
int mTargetSize, mTargetAge;
unsigned int mTargetSize, mTargetAge;
public:

View File

@@ -18,7 +18,7 @@ DECLARE_INSTANCE(LedgerAcquire);
#define TRUST_NETWORK
PeerSet::PeerSet(const uint256& hash, int interval) : mHash(hash), mTimerInterval(interval), mTimeouts(0),
mComplete(false), mFailed(false), mProgress(true), mTimer(theApp->getIOService())
mComplete(false), mFailed(false), mProgress(true), mAggressive(true), mTimer(theApp->getIOService())
{
mLastAction = time(NULL);
assert((mTimerInterval > 10) && (mTimerInterval < 30000));
@@ -94,9 +94,18 @@ bool LedgerAcquire::tryLocal()
{ // return value: true = no more work to do
HashedObject::pointer node = theApp->getHashedObjectStore().retrieve(mHash);
if (!node)
return false;
mLedger = boost::make_shared<Ledger>(strCopy(node->getData()), true);
{
mLedger = theApp->getLedgerMaster().getLedgerByHash(mHash);
if (!mLedger)
{
cLog(lsDEBUG) << "root ledger node not local";
return false;
}
}
else
{
mLedger = boost::make_shared<Ledger>(strCopy(node->getData()), true);
}
if (mLedger->getHash() != mHash)
{ // We know for a fact the ledger can never be acquired
cLog(lsWARNING) << mHash << " cannot be a ledger";
@@ -106,15 +115,22 @@ bool LedgerAcquire::tryLocal()
mHaveBase = true;
if (!mLedger->getTransHash())
{
cLog(lsDEBUG) << "No TXNs to fetch";
mHaveTransactions = true;
}
else
{
try
{
mLedger->peekTransactionMap()->fetchRoot(mLedger->getTransHash());
cLog(lsDEBUG) << "Got root txn map locally";
std::vector<uint256> h = mLedger->peekTransactionMap()->getNeededHashes(1);
if (h.empty())
{
cLog(lsDEBUG) << "Had full txn map locally";
mHaveTransactions = true;
}
}
catch (SHAMapMissingNode&)
{
@@ -128,9 +144,13 @@ bool LedgerAcquire::tryLocal()
try
{
mLedger->peekAccountStateMap()->fetchRoot(mLedger->getAccountHash());
cLog(lsDEBUG) << "Got root AS map locally";
std::vector<uint256> h = mLedger->peekAccountStateMap()->getNeededHashes(1);
if (h.empty())
{
cLog(lsDEBUG) << "Had full AS map locally";
mHaveState = true;
}
}
catch (SHAMapMissingNode&)
{
@@ -138,7 +158,10 @@ bool LedgerAcquire::tryLocal()
}
if (mHaveTransactions && mHaveState)
{
cLog(lsDEBUG) << "Had everything locally";
mComplete = true;
}
return mComplete;
}
@@ -158,6 +181,7 @@ void LedgerAcquire::onTimer(bool progress)
if (!progress)
{
mAggressive = true;
cLog(lsDEBUG) << "No progress for ledger " << mHash;
if (!getPeerCount())
addPeers();
@@ -172,9 +196,17 @@ void LedgerAcquire::addPeers()
{
std::vector<Peer::pointer> peerList = theApp->getConnectionPool().getPeerVector();
int vSize = peerList.size();
if (vSize == 0)
return;
// We traverse the peer list in random order so as not to favor any particular peer
int firstPeer = rand() & vSize;
bool found = false;
BOOST_FOREACH(Peer::ref peer, peerList)
for (int i = 0; i < vSize; ++i)
{
Peer::ref peer = peerList[(i + firstPeer) % vSize];
if (peer->hasLedger(getHash()))
{
found = true;
@@ -183,10 +215,8 @@ void LedgerAcquire::addPeers()
}
if (!found)
{
BOOST_FOREACH(Peer::ref peer, peerList)
peerHas(peer);
}
for (int i = 0; i < vSize; ++i)
peerHas(peerList[(i + firstPeer) % vSize]);
}
boost::weak_ptr<PeerSet> LedgerAcquire::pmDowncast()
@@ -322,6 +352,7 @@ void LedgerAcquire::trigger(Peer::ref peer)
mHaveBase = true;
mHaveTransactions = true;
mHaveState = true;
mComplete = true;
}
}
}
@@ -368,7 +399,8 @@ void LedgerAcquire::trigger(Peer::ref peer)
}
else
{
filterNodes(nodeIDs, nodeHashes, mRecentTXNodes, 128, !isProgress());
if (!mAggressive)
filterNodes(nodeIDs, nodeHashes, mRecentTXNodes, 128, !isProgress());
if (!nodeIDs.empty())
{
tmGL.set_itype(ripple::liTX_NODE);
@@ -415,7 +447,8 @@ void LedgerAcquire::trigger(Peer::ref peer)
}
else
{
filterNodes(nodeIDs, nodeHashes, mRecentASNodes, 128, !isProgress());
if (!mAggressive)
filterNodes(nodeIDs, nodeHashes, mRecentASNodes, 128, !isProgress());
if (!nodeIDs.empty())
{
tmGL.set_itype(ripple::liAS_NODE);
@@ -489,9 +522,9 @@ void LedgerAcquire::filterNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<ui
std::vector<bool> duplicates;
duplicates.reserve(nodeIDs.size());
int dupCount;
int dupCount=0;
for (int i = 0; i < nodeIDs.size(); ++i)
for (unsigned int i = 0; i < nodeIDs.size(); ++i)
{
bool isDup = recentNodes.count(nodeIDs[i]) != 0;
duplicates.push_back(isDup);
@@ -511,7 +544,7 @@ void LedgerAcquire::filterNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<ui
else if (dupCount > 0)
{ // some, but not all, duplicates
int insertPoint = 0;
for (int i = 0; i < nodeIDs.size(); ++i)
for (unsigned int i = 0; i < nodeIDs.size(); ++i)
if (!duplicates[i])
{ // Keep this node
if (insertPoint != i)
@@ -687,6 +720,8 @@ LedgerAcquire::pointer LedgerAcquireMaster::findCreate(const uint256& hash)
ptr->addPeers();
ptr->setTimer(); // Cannot call in constructor
}
else
cLog(lsINFO) << "LedgerAcquireMaster acquiring ledger we already have";
return ptr;
}
@@ -726,6 +761,39 @@ std::vector<LedgerAcquire::neededHash_t> LedgerAcquire::getNeededHashes()
return ret;
}
Json::Value LedgerAcquire::getJson(int)
{
Json::Value ret(Json::objectValue);
ret["hash"] = mHash.GetHex();
if (mComplete)
ret["complete"] = true;
if (mFailed)
ret["failed"] = true;
ret["have_base"] = mHaveBase;
ret["have_state"] = mHaveState;
ret["have_transactions"] = mHaveTransactions;
if (mAborted)
ret["aborted"] = true;
ret["timeouts"] = getTimeouts();
if (mHaveBase && !mHaveState)
{
Json::Value hv(Json::arrayValue);
std::vector<uint256> v = mLedger->peekAccountStateMap()->getNeededHashes(16);
BOOST_FOREACH(const uint256& h, v)
hv.append(h.GetHex());
ret["needed_state_hashes"] = hv;
}
if (mHaveBase && !mHaveTransactions)
{
Json::Value hv(Json::arrayValue);
std::vector<uint256> v = mLedger->peekTransactionMap()->getNeededHashes(16);
BOOST_FOREACH(const uint256& h, v)
hv.append(h.GetHex());
ret["needed_transaction_hashes"] = hv;
}
return ret;
}
bool LedgerAcquireMaster::hasLedger(const uint256& hash)
{
assert(hash.isNonZero());

View File

@@ -31,7 +31,7 @@ class PeerSet
protected:
uint256 mHash;
int mTimerInterval, mTimeouts;
bool mComplete, mFailed, mProgress;
bool mComplete, mFailed, mProgress, mAggressive;
time_t mLastAction;
boost::recursive_mutex mLock;
@@ -51,7 +51,7 @@ public:
int getTimeouts() const { return mTimeouts; }
bool isActive();
void progress() { mProgress = true; }
void progress() { mProgress = true; mAggressive = false; }
bool isProgress() { return mProgress; }
void touch() { mLastAction = time(NULL); }
time_t getLastAction() { return mLastAction; }
@@ -129,6 +129,8 @@ public:
static void filterNodes(std::vector<SHAMapNode>& nodeIDs, std::vector<uint256>& nodeHashes,
std::set<SHAMapNode>& recentNodes, int max, bool aggressive);
Json::Value getJson(int);
};
class LedgerAcquireMaster

View File

@@ -2534,6 +2534,13 @@ Json::Value RPCHandler::doRpcCommand(const std::string& strMethod, Json::Value&
return jvResult;
}
Json::Value RPCHandler::doInternal(Json::Value jvRequest)
{ // Used for debug or special-purpose RPC commands
if (!jvRequest.isMember("internal_command"))
return rpcError(rpcINVALID_PARAMS);
return RPCInternalHandler::runHandler(jvRequest["internal_command"].asString(), jvRequest["params"]);
}
Json::Value RPCHandler::doCommand(Json::Value& jvRequest, int iRole)
{
if (!jvRequest.isMember("command"))
@@ -2562,6 +2569,7 @@ Json::Value RPCHandler::doCommand(Json::Value& jvRequest, int iRole)
{ "account_tx", &RPCHandler::doAccountTransactions, false, optNetwork },
{ "connect", &RPCHandler::doConnect, true, optNone },
{ "get_counts", &RPCHandler::doGetCounts, true, optNone },
{ "internal", &RPCHandler::doInternal, true, optNone },
{ "ledger", &RPCHandler::doLedger, false, optNetwork },
{ "ledger_accept", &RPCHandler::doLedgerAccept, true, optCurrent },
{ "ledger_closed", &RPCHandler::doLedgerClosed, false, optClosed },
@@ -2674,4 +2682,29 @@ Json::Value RPCHandler::doCommand(Json::Value& jvRequest, int iRole)
}
}
RPCInternalHandler* RPCInternalHandler::sHeadHandler = NULL;
RPCInternalHandler::RPCInternalHandler(const std::string& name, handler_t Handler) : mName(name), mHandler(Handler)
{
mNextHandler = sHeadHandler;
sHeadHandler = this;
}
Json::Value RPCInternalHandler::runHandler(const std::string& name, const Json::Value& params)
{
RPCInternalHandler* h = sHeadHandler;
while (h != NULL)
{
if (name == h->mName)
{
cLog(lsWARNING) << "Internal command " << name << ": " << params;
Json::Value ret = h->mHandler(params);
cLog(lsWARNING) << "Internal command returns: " << ret;
return ret;
}
h = h->mNextHandler;
}
return rpcError(rpcBAD_SYNTAX);
}
// vim:ts=4

View File

@@ -1,8 +1,17 @@
#ifndef __RPCHANDLER__
#define __RPCHANDLER__
#include <boost/unordered_set.hpp>
#include "../json/value.h"
#include "RippleAddress.h"
#include "SerializedTypes.h"
#include "Ledger.h"
// used by the RPCServer or WSDoor to carry out these RPC commands
class NetworkOPs;
class InfoSub;
class RPCHandler
{
@@ -47,6 +56,7 @@ class RPCHandler
Json::Value doDataStore(Json::Value params);
#endif
Json::Value doGetCounts(Json::Value params);
Json::Value doInternal(Json::Value params);
Json::Value doLedger(Json::Value params);
Json::Value doLogLevel(Json::Value params);
Json::Value doLogRotate(Json::Value params);
@@ -108,5 +118,22 @@ public:
Json::Value doRpcCommand(const std::string& strCommand, Json::Value& jvParams, int iRole);
};
class RPCInternalHandler
{
public:
typedef Json::Value (*handler_t)(const Json::Value&);
protected:
static RPCInternalHandler* sHeadHandler;
RPCInternalHandler* mNextHandler;
std::string mName;
handler_t mHandler;
public:
RPCInternalHandler(const std::string& name, handler_t handler);
static Json::Value runHandler(const std::string& name, const Json::Value& params);
};
#endif
// vim:ts=4

View File

@@ -45,7 +45,7 @@ protected:
mutable boost::recursive_mutex mLock;
std::string mName; // Used for logging
int mTargetSize; // Desired number of cache entries (0 = ignore)
unsigned int mTargetSize; // Desired number of cache entries (0 = ignore)
int mTargetAge; // Desired maximum cache age
cache_type mCache; // Hold strong reference to recent objects

View File

@@ -1625,7 +1625,7 @@ void UniqueNodeList::nodeBootstrap()
cLog(lsINFO) << boost::str(boost::format("Bootstrapping UNL: loading from '%s'.")
% theConfig.CONFIG_FILE);
if (processValidators("local", theConfig.CONFIG_FILE.native(), naInvalid, vsConfig, &theConfig.VALIDATORS))
if (processValidators("local", theConfig.CONFIG_FILE.string(), naInvalid, vsConfig, &theConfig.VALIDATORS))
bLoaded = true;
}