mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Merge branch 'master' of github.com:jedmccaleb/NewCoin
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,7 +17,7 @@ protected:
|
||||
const std::string mName;
|
||||
boost::mutex mNCLock;
|
||||
map_type mCache;
|
||||
int mTargetSize, mTargetAge;
|
||||
unsigned int mTargetSize, mTargetAge;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user