diff --git a/.gitignore b/.gitignore index 8a9dbd0daf..c7a5cec4b2 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,10 @@ tmp db/*.db db/*.db-journal +# Ignore obj files +Debug/*.* +Release/*.* + # Ignore customized configs rippled.cfg validators.txt diff --git a/deploy/newcoind.cfg b/deploy/newcoind.cfg deleted file mode 100644 index ee991ea679..0000000000 --- a/deploy/newcoind.cfg +++ /dev/null @@ -1,149 +0,0 @@ -# -# Sample newcoind.cfg -# -# This file should be named newcoind.cfg. This file is UTF-8 with Dos, UNIX, -# or Mac style end of lines. Blank lines and lines beginning with '#' are -# ignored. Undefined sections are reserved. No escapes are currently defined. -# -# When you launch newcoind, it will attempt to find this file. -# -# --conf=: -# You may specify the location of this file with --conf=. The config -# directory is the directory containing this file. The data directory is a -# the subdirectory named "dbs". -# -# Windows and no --conf: -# The config directory is the same directory as the newcoind program. The -# data directory is a the subdirectory named "dbs". -# -# Other OSes and no --conf: -# This file will be looked for in these places in the following order: -# ./newcoind.cfg -# $XDG_CONFIG_HOME/newcoin/newcoind.cfg -# -# If newcoind.cfg, is found in the current working directory, the directory -# will be used as the config directory. The data directory is a the -# subdirectory named "dbs". -# -# Otherwise, the data directory data is: -# $XDG_DATA_HOME/newcoin/ -# -# Note: $XDG_CONFIG_HOME defaults to $HOME/.config -# $XDG_DATA_HOME defaults to $HOME/.local/share -# -# [debug_logfile] -# Specifies were a debug logfile is kept. By default, no debug log is kept -# -# Example: debug.log -# -# [validators_site]: -# Specifies where to find validators.txt for UNL boostrapping and RPC command unl_network. -# During alpha testing, this defaults to: redstem.com -# -# Example: newcoin.org -# -# [unl_default]: -# XXX This should be called: [validators_file] -# Specifies how to bootstrap the UNL list. The UNL list is based on a -# validators.txt file and is maintained in the databases. When newcoind -# starts up, if the databases are missing or are obsolete due to an upgrade -# of newcoind, newcoind will reconstruct the UNL list as specified here. -# -# If this entry is not present or empty, newcoind will look for a validators.txt in the -# config directory. If not found there, it will attempt to retrieve the file -# from the newcoin foundation's web site. -# -# This entry is also used by the RPC command unl_load. -# -# Specify the file by specifying its full path. -# -# Examples: -# C:/home/johndoe/newcoin/validators.txt -# /home/johndoe/newcoin/validators.txt -# -# [validators]: -# Only valid in "newcoind.cfg", "newcoin.txt", and the referered [validators_url]. -# List of nodes to accept as validators speficied by public key or domain. -# -# For domains, newcoind will probe for https web servers at the specied -# domain in the following order: newcoin.DOMAIN, www.DOMAIN, DOMAIN -# -# Examples: -# redstem.com -# n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5 -# n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt John Doe -# -# [ips]: -# Only valid in "newcoind.cfg", "newcoin.txt", and the referered [ips_url]. -# List of ips where the Newcoin protocol is avialable. -# One ipv4 or ipv6 address per line. -# A port may optionally be specified after adding a space to the address. -# By convention, if known, IPs are listed in from most to least trusted. -# -# Examples: -# 192.168.0.1 -# 192.168.0.1 3939 -# 2001:0db8:0100:f101:0210:a4ff:fee3:9566 -# -# [peer_ip]: -# IP address or domain to bind to allow external connections from peers. -# Defaults to not allow external connections from peers. -# -# Examples: 0.0.0.0 - Bind on all interfaces. -# -# [peer_port]: -# Port to bind to allow external connections from peers. -# -# [rpc_ip]: -# IP address or domain to bind to allow insecure RPC connections. -# Defaults to not allow RPC connections. -# -# [rpc_port]: -# Port to bind to if allowing insecure RPC connections. -# -# [rpc_allow_remote]: -# 0 or 1. 0 only allows RPC connections from 127.0.0.1. [default 0] -# -# [websocket_ip]: -# IP address or domain to bind to allow client connections. -# -# Examples: 0.0.0.0 - Bind on all interfaces. -# 127.0.0.1 - Bind on localhost interface. Only local programs may connect. -# -# [websocket_port]: -# Port to bind to allow client connections. -# -# [validation_seed]: -# To perform validation, this section should contain either a validation seed or key. -# The validation seed is used to generate the validation public/private key pair. -# To obtain a validation seed, use the validation_create command. -# -# Examples: RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE -# shfArahZT9Q9ckTf3s1psJ7C7qzVN -# - -[peer_ip] -0.0.0.0 - -[peer_port] -51235 - -[rpc_ip] -127.0.0.1 - -[rpc_port] -5005 - -[rpc_allow_remote] -1 - -[debug_logfile] -debug.log - -[unl_default] -validators.txt - -[ips] -23.21.167.100 51235 -23.23.201.55 51235 -107.21.116.214 51235 diff --git a/deploy/cointoss.nsi b/deploy/rippled.nsi similarity index 73% rename from deploy/cointoss.nsi rename to deploy/rippled.nsi index 1f3656ba7d..f77f8bc681 100644 --- a/deploy/cointoss.nsi +++ b/deploy/rippled.nsi @@ -1,10 +1,10 @@ -Name "CoinToss" +Name "Rippled" ; The file to write -OutFile "toss install.exe" +OutFile "ripple install.exe" ; The default installation directory -InstallDir "$PROGRAMFILES\CoinToss" +InstallDir "$PROGRAMFILES\Rippled" ; Request application privileges for Windows Vista RequestExecutionLevel user @@ -25,12 +25,12 @@ Section "" ;No components page, name is not important SetOutPath $INSTDIR ; Put file there - File ..\Release\newcoin.exe + File ..\Release\rippled.exe File ..\*.dll - File "start CoinToss.bat" - File newcoind.cfg + ;File "start rippled.bat" + File rippled.cfg File validators.txt - File /r /x .git ..\..\nc-client\*.* + ;File /r /x .git ..\..\nc-client\*.* CreateDirectory $INSTDIR\db diff --git a/deploy/start CoinToss.bat b/deploy/start rippled.bat similarity index 100% rename from deploy/start CoinToss.bat rename to deploy/start rippled.bat diff --git a/newcoin.vcxproj b/newcoin.vcxproj index 8f29a10d67..737324e652 100644 --- a/newcoin.vcxproj +++ b/newcoin.vcxproj @@ -41,9 +41,11 @@ true + rippled false + rippled @@ -76,14 +78,14 @@ true true BOOST_TEST_ALTERNATIVE_INIT_API;BOOST_TEST_NO_MAIN;_CRT_SECURE_NO_WARNINGS;_WIN32_WINNT=0x0501;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - ..\OpenSSL\include;..\boost_1_47_0;..\protobuf-2.4.1\src + .\;..\OpenSSL\include;..\boost_1_52_0;..\protobuf\src Console true true true - ..\OpenSSL\lib\VC;..\boost_1_47_0\stage\lib;..\protobuf-2.4.1\vsprojects\Release + ..\OpenSSL\lib\VC;..\boost_1_52_0\stage\lib;..\protobuf\vsprojects\Release libprotobuf.lib;ssleay32MD.lib;libeay32MD.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) @@ -91,7 +93,6 @@ - @@ -158,6 +159,7 @@ + @@ -322,8 +324,10 @@ Document - /code/protobuf/protoc -I=..\newcoin --cpp_out=\code\newcoin\ ..\newcoin/src/cpp/ripple/ripple.proto + "../protobuf/protoc" -I=..\newcoin --cpp_out=..\newcoin\ ..\newcoin/src/cpp/ripple/ripple.proto \code\newcoin\src\ripple.pb.h + /code/protobuf/protoc -I=..\newcoin --cpp_out=\code\newcoin\ ..\newcoin/src/cpp/ripple/ripple.proto + \code\newcoin\src\ripple.pb.h diff --git a/newcoin.vcxproj.filters b/newcoin.vcxproj.filters index 535986aa0c..796adfdd76 100644 --- a/newcoin.vcxproj.filters +++ b/newcoin.vcxproj.filters @@ -42,9 +42,6 @@ Source Files\database - - Source Files\database - Source Files\json @@ -363,6 +360,9 @@ Source Files + + Source Files + diff --git a/newcoin2012.sln b/newcoin2012.sln new file mode 100644 index 0000000000..cf41ac0bf4 --- /dev/null +++ b/newcoin2012.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "newcoin", "newcoin.vcxproj", "{19465545-42EE-42FA-9CC8-F8975F8F1CC7}" + ProjectSection(ProjectDependencies) = postProject + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} = {3E283F37-A4ED-41B7-A3E6-A2D89D131A30} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libprotobuf", "..\protobuf\vsprojects\libprotobuf.vcxproj", "{3E283F37-A4ED-41B7-A3E6-A2D89D131A30}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + FlashDebug|Win32 = FlashDebug|Win32 + FlashDebug|x64 = FlashDebug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseD|Win32 = ReleaseD|Win32 + ReleaseD|x64 = ReleaseD|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Debug|Win32.ActiveCfg = Debug|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Debug|Win32.Build.0 = Debug|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Debug|x64.ActiveCfg = Debug|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.FlashDebug|Win32.ActiveCfg = Debug|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.FlashDebug|Win32.Build.0 = Debug|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.FlashDebug|x64.ActiveCfg = Debug|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Release|Win32.ActiveCfg = Release|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Release|Win32.Build.0 = Release|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.Release|x64.ActiveCfg = Release|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.ReleaseD|Win32.ActiveCfg = Release|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.ReleaseD|Win32.Build.0 = Release|Win32 + {19465545-42EE-42FA-9CC8-F8975F8F1CC7}.ReleaseD|x64.ActiveCfg = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.ActiveCfg = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|Win32.Build.0 = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Debug|x64.ActiveCfg = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.FlashDebug|Win32.ActiveCfg = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.FlashDebug|Win32.Build.0 = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.FlashDebug|x64.ActiveCfg = Debug|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.ActiveCfg = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|Win32.Build.0 = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.Release|x64.ActiveCfg = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.ReleaseD|Win32.ActiveCfg = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.ReleaseD|Win32.Build.0 = Release|Win32 + {3E283F37-A4ED-41B7-A3E6-A2D89D131A30}.ReleaseD|x64.ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/src/cpp/ripple/Application.cpp b/src/cpp/ripple/Application.cpp index 6e9043be64..5be04fc9b4 100644 --- a/src/cpp/ripple/Application.cpp +++ b/src/cpp/ripple/Application.cpp @@ -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) diff --git a/src/cpp/ripple/CallRPC.cpp b/src/cpp/ripple/CallRPC.cpp index 2b6ffff988..17fe7cad2f 100644 --- a/src/cpp/ripple/CallRPC.cpp +++ b/src/cpp/ripple/CallRPC.cpp @@ -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 || @@ -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 }, diff --git a/src/cpp/ripple/CallRPC.h b/src/cpp/ripple/CallRPC.h index 1d6c4d2c75..7f8d2ebe6b 100644 --- a/src/cpp/ripple/CallRPC.h +++ b/src/cpp/ripple/CallRPC.h @@ -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 diff --git a/src/cpp/ripple/InstanceCounter.h b/src/cpp/ripple/InstanceCounter.h index aaec9efcd7..48f82d0332 100644 --- a/src/cpp/ripple/InstanceCounter.h +++ b/src/cpp/ripple/InstanceCounter.h @@ -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 diff --git a/src/cpp/ripple/KeyCache.h b/src/cpp/ripple/KeyCache.h index e4a1d87270..95b0277b67 100644 --- a/src/cpp/ripple/KeyCache.h +++ b/src/cpp/ripple/KeyCache.h @@ -17,7 +17,7 @@ protected: const std::string mName; boost::mutex mNCLock; map_type mCache; - int mTargetSize, mTargetAge; + unsigned int mTargetSize, mTargetAge; public: diff --git a/src/cpp/ripple/LedgerAcquire.cpp b/src/cpp/ripple/LedgerAcquire.cpp index 02cf8ff62a..5d133645eb 100644 --- a/src/cpp/ripple/LedgerAcquire.cpp +++ b/src/cpp/ripple/LedgerAcquire.cpp @@ -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(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(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 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 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 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 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& nodeIDs, std::vector 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& nodeIDs, std::vector 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::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 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 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()); diff --git a/src/cpp/ripple/LedgerAcquire.h b/src/cpp/ripple/LedgerAcquire.h index 805c84c092..0f2c6abd26 100644 --- a/src/cpp/ripple/LedgerAcquire.h +++ b/src/cpp/ripple/LedgerAcquire.h @@ -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& nodeIDs, std::vector& nodeHashes, std::set& recentNodes, int max, bool aggressive); + + Json::Value getJson(int); }; class LedgerAcquireMaster diff --git a/src/cpp/ripple/RPCHandler.cpp b/src/cpp/ripple/RPCHandler.cpp index 8ad6ec1355..9af8b1d304 100644 --- a/src/cpp/ripple/RPCHandler.cpp +++ b/src/cpp/ripple/RPCHandler.cpp @@ -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 diff --git a/src/cpp/ripple/RPCHandler.h b/src/cpp/ripple/RPCHandler.h index 8c4727f3b3..a1d891700b 100644 --- a/src/cpp/ripple/RPCHandler.h +++ b/src/cpp/ripple/RPCHandler.h @@ -1,8 +1,17 @@ #ifndef __RPCHANDLER__ #define __RPCHANDLER__ +#include + +#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 diff --git a/src/cpp/ripple/TaggedCache.h b/src/cpp/ripple/TaggedCache.h index e294e0591c..12ac56b764 100644 --- a/src/cpp/ripple/TaggedCache.h +++ b/src/cpp/ripple/TaggedCache.h @@ -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 diff --git a/src/cpp/ripple/UniqueNodeList.cpp b/src/cpp/ripple/UniqueNodeList.cpp index 3935039656..c0f4d8016f 100644 --- a/src/cpp/ripple/UniqueNodeList.cpp +++ b/src/cpp/ripple/UniqueNodeList.cpp @@ -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; } diff --git a/src/js/sjcl b/src/js/sjcl index dbdef434e7..d04d0bdccd 160000 --- a/src/js/sjcl +++ b/src/js/sjcl @@ -1 +1 @@ -Subproject commit dbdef434e76c3f16835f3126a7ff1c717b1ce8af +Subproject commit d04d0bdccd986e434b98fe393e1e01286c10fc36