aboutsummaryrefslogtreecommitdiff
path: root/src/init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/init.cpp')
-rw-r--r--src/init.cpp181
1 files changed, 114 insertions, 67 deletions
diff --git a/src/init.cpp b/src/init.cpp
index ef1c39db2..5c961a3ad 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -16,6 +16,8 @@
#include "checkpoints.h"
#include "compat/sanity.h"
#include "consensus/validation.h"
+#include "httpserver.h"
+#include "httprpc.h"
#include "key.h"
#include "main.h"
#include "miner.h"
@@ -36,7 +38,6 @@
#include "wallet/wallet.h"
#include "wallet/walletdb.h"
#endif
-
#include <stdint.h>
#include <stdio.h>
@@ -53,6 +54,10 @@
#include <boost/thread.hpp>
#include <openssl/crypto.h>
+#if ENABLE_ZMQ
+#include "zmq/zmqnotificationinterface.h"
+#endif
+
using namespace std;
#ifdef ENABLE_WALLET
@@ -60,6 +65,10 @@ CWallet* pwalletMain = NULL;
#endif
bool fFeeEstimatesInitialized = false;
+#if ENABLE_ZMQ
+static CZMQNotificationInterface* pzmqNotificationInterface = NULL;
+#endif
+
#ifdef WIN32
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
// accessing block files don't count towards the fd_set size limit
@@ -144,6 +153,15 @@ public:
static CCoinsViewDB *pcoinsdbview = NULL;
static CCoinsViewErrorCatcher *pcoinscatcher = NULL;
+void Interrupt(boost::thread_group& threadGroup)
+{
+ InterruptHTTPServer();
+ InterruptHTTPRPC();
+ InterruptRPC();
+ InterruptREST();
+ threadGroup.interrupt_all();
+}
+
void Shutdown()
{
LogPrintf("%s: In progress...\n", __func__);
@@ -158,7 +176,11 @@ void Shutdown()
/// module was initialized.
RenameThread("bitcoin-shutoff");
mempool.AddTransactionsUpdated(1);
- StopRPCThreads();
+
+ StopHTTPRPC();
+ StopREST();
+ StopRPC();
+ StopHTTPServer();
#ifdef ENABLE_WALLET
if (pwalletMain)
pwalletMain->Flush(false);
@@ -196,6 +218,16 @@ void Shutdown()
if (pwalletMain)
pwalletMain->Flush(true);
#endif
+
+#if ENABLE_ZMQ
+ if (pzmqNotificationInterface) {
+ UnregisterValidationInterface(pzmqNotificationInterface);
+ pzmqNotificationInterface->Shutdown();
+ delete pzmqNotificationInterface;
+ pzmqNotificationInterface = NULL;
+ }
+#endif
+
#ifndef WIN32
try {
boost::filesystem::remove(GetPidFile());
@@ -280,7 +312,7 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "bitcoin.conf"));
if (mode == HMM_BITCOIND)
{
-#if !defined(WIN32)
+#ifndef WIN32
strUsage += HelpMessageOpt("-daemon", _("Run in the background as a daemon and accept commands"));
#endif
}
@@ -288,16 +320,18 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache));
strUsage += HelpMessageOpt("-loadblock=<file>", _("Imports blocks from external blk000??.dat file") + " " + _("on startup"));
strUsage += HelpMessageOpt("-maxorphantx=<n>", strprintf(_("Keep at most <n> unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS));
+ strUsage += HelpMessageOpt("-maxmempool=<n>", strprintf(_("Keep the transaction memory pool below <n> megabytes (default: %u)"), DEFAULT_MAX_MEMPOOL_SIZE));
+ strUsage += HelpMessageOpt("-mempoolexpiry=<n>", strprintf(_("Do not keep transactions in the mempool longer than <n> hours (default: %u)"), DEFAULT_MEMPOOL_EXPIRY));
strUsage += HelpMessageOpt("-par=<n>", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"),
-GetNumCores(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS));
#ifndef WIN32
strUsage += HelpMessageOpt("-pid=<file>", strprintf(_("Specify pid file (default: %s)"), "bitcoind.pid"));
#endif
- strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode disables wallet support and is incompatible with -txindex. "
+ strUsage += HelpMessageOpt("-prune=<n>", strprintf(_("Reduce storage requirements by pruning (deleting) old blocks. This mode is incompatible with -txindex and -rescan. "
"Warning: Reverting this setting requires re-downloading the entire blockchain. "
"(default: 0 = disable pruning blocks, >%u = target size in MiB to use for block files)"), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
strUsage += HelpMessageOpt("-reindex", _("Rebuild block chain index from current blk000??.dat files on startup"));
-#if !defined(WIN32)
+#ifndef WIN32
strUsage += HelpMessageOpt("-sysperms", _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)"));
#endif
strUsage += HelpMessageOpt("-txindex", strprintf(_("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)"), 0));
@@ -335,7 +369,6 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-whitebind=<addr>", _("Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6"));
strUsage += HelpMessageOpt("-whitelist=<netmask>", _("Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times.") +
" " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway"));
- strUsage += HelpMessageOpt("-whiteconnections=<n>", strprintf(_("Reserve this many inbound connections for whitelisted peers (default: %d)"), 0));
#ifdef ENABLE_WALLET
strUsage += HelpMessageGroup(_("Wallet options:"));
@@ -361,6 +394,14 @@ std::string HelpMessage(HelpMessageMode mode)
" " + _("(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)"));
#endif
+#if ENABLE_ZMQ
+ strUsage += HelpMessageGroup(_("ZeroMQ notification options:"));
+ strUsage += HelpMessageOpt("-zmqpubhashblock=<address>", _("Enable publish hash block in <address>"));
+ strUsage += HelpMessageOpt("-zmqpubhashtransaction=<address>", _("Enable publish hash transaction in <address>"));
+ strUsage += HelpMessageOpt("-zmqpubrawblock=<address>", _("Enable publish raw block in <address>"));
+ strUsage += HelpMessageOpt("-zmqpubrawtransaction=<address>", _("Enable publish raw transaction in <address>"));
+#endif
+
strUsage += HelpMessageGroup(_("Debugging/Testing options:"));
if (showDebug)
{
@@ -372,8 +413,12 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-fuzzmessagestest=<n>", "Randomly fuzz 1 of every <n> network messages");
strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1));
strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0));
+ strUsage += HelpMessageOpt("-limitancestorcount=<n>", strprintf("Do not accept transactions if number of in-mempool ancestors is <n> or more (default: %u)", DEFAULT_ANCESTOR_LIMIT));
+ strUsage += HelpMessageOpt("-limitancestorsize=<n>", strprintf("Do not accept transactions whose size with all in-mempool ancestors exceeds <n> kilobytes (default: %u)", DEFAULT_ANCESTOR_SIZE_LIMIT));
+ strUsage += HelpMessageOpt("-limitdescendantcount=<n>", strprintf("Do not accept transactions if any ancestor would have <n> or more in-mempool descendants (default: %u)", DEFAULT_DESCENDANT_LIMIT));
+ strUsage += HelpMessageOpt("-limitdescendantsize=<n>", strprintf("Do not accept transactions if any ancestor would have more than <n> kilobytes of in-mempool descendants (default: %u).", DEFAULT_DESCENDANT_SIZE_LIMIT));
}
- string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, net, proxy, prune"; // Don't translate these and qt below
+ string debugCategories = "addrman, alert, bench, coindb, db, lock, rand, rpc, selectcoins, mempool, mempoolrej, net, proxy, prune, http, libevent"; // Don't translate these and qt below
if (mode == HMM_BITCOIN_QT)
debugCategories += ", qt";
strUsage += HelpMessageOpt("-debug=<category>", strprintf(_("Output debugging information (default: %u, supplying <category> is optional)"), 0) + ". " +
@@ -396,11 +441,10 @@ std::string HelpMessage(HelpMessageMode mode)
{
strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", 0));
strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", 1));
- strUsage += HelpMessageOpt("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. "
- "This is intended for regression testing tools and app development.");
}
strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
- strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
+
+ AppendParamsHelpMessages(strUsage, showDebug);
strUsage += HelpMessageGroup(_("Node relay options:"));
if (showDebug)
@@ -423,14 +467,11 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Listen for JSON-RPC connections on <port> (default: %u or testnet: %u)"), 8332, 18332));
strUsage += HelpMessageOpt("-rpcallowip=<ip>", _("Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times"));
- strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), 4));
- strUsage += HelpMessageOpt("-rpckeepalive", strprintf(_("RPC support for HTTP persistent connections (default: %d)"), 1));
-
- strUsage += HelpMessageGroup(_("RPC SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
- strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
- strUsage += HelpMessageOpt("-rpcsslcertificatechainfile=<file.cert>", strprintf(_("Server certificate file (default: %s)"), "server.cert"));
- strUsage += HelpMessageOpt("-rpcsslprivatekeyfile=<file.pem>", strprintf(_("Server private key (default: %s)"), "server.pem"));
- strUsage += HelpMessageOpt("-rpcsslciphers=<ciphers>", strprintf(_("Acceptable ciphers (default: %s)"), "TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"));
+ strUsage += HelpMessageOpt("-rpcthreads=<n>", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS));
+ if (showDebug) {
+ strUsage += HelpMessageOpt("-rpcworkqueue=<n>", strprintf("Set the depth of the work queue to service RPC calls (default: %d)", DEFAULT_HTTP_WORKQUEUE));
+ strUsage += HelpMessageOpt("-rpcservertimeout=<n>", strprintf("Timeout during HTTP requests (default: %d)", DEFAULT_HTTP_SERVER_TIMEOUT));
+ }
if (mode == HMM_BITCOIN_QT)
{
@@ -602,6 +643,23 @@ bool InitSanityCheck(void)
return true;
}
+bool AppInitServers(boost::thread_group& threadGroup)
+{
+ RPCServer::OnStopped(&OnRPCStopped);
+ RPCServer::OnPreCommand(&OnRPCPreCommand);
+ if (!InitHTTPServer())
+ return false;
+ if (!StartRPC())
+ return false;
+ if (!StartHTTPRPC())
+ return false;
+ if (GetBoolArg("-rest", false) && !StartREST())
+ return false;
+ if (!StartHTTPServer(threadGroup))
+ return false;
+ return true;
+}
+
/** Initialize bitcoin.
* @pre Parameters should be parsed and config file should be read.
*/
@@ -629,17 +687,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
typedef BOOL (WINAPI *PSETPROCDEPPOL)(DWORD);
PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy");
if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE);
-
- // Initialize Windows Sockets
- WSADATA wsadata;
- int ret = WSAStartup(MAKEWORD(2,2), &wsadata);
- if (ret != NO_ERROR || LOBYTE(wsadata.wVersion ) != 2 || HIBYTE(wsadata.wVersion) != 2)
- {
- return InitError(strprintf("Error: Winsock library failed to start (WSAStartup returned error %d)", ret));
- }
#endif
-#ifndef WIN32
+ if (!SetupNetworking())
+ return InitError("Error: Initializing networking failed");
+
+#ifndef WIN32
if (GetBoolArg("-sysperms", false)) {
#ifdef ENABLE_WALLET
if (!GetBoolArg("-disablewallet", false))
@@ -664,11 +717,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
sa_hup.sa_flags = 0;
sigaction(SIGHUP, &sa_hup, NULL);
-#if defined (__SVR4) && defined (__sun)
- // ignore SIGPIPE on Solaris
+ // Ignore SIGPIPE, otherwise it will bring the daemon down if the client closes unexpectedly
signal(SIGPIPE, SIG_IGN);
#endif
-#endif
// ********************************************************* Step 2: parameter interactions
const CChainParams& chainparams = Params();
@@ -754,25 +805,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
int nBind = std::max((int)mapArgs.count("-bind") + (int)mapArgs.count("-whitebind"), 1);
int nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
nMaxConnections = std::max(nUserMaxConnections, 0);
- int nUserWhiteConnections = GetArg("-whiteconnections", 0);
- nWhiteConnections = std::max(nUserWhiteConnections, 0);
-
- if ((mapArgs.count("-whitelist")) || (mapArgs.count("-whitebind"))) {
- if (!(mapArgs.count("-maxconnections"))) {
- // User is using whitelist feature,
- // but did not specify -maxconnections parameter.
- // Silently increase the default to compensate,
- // so that the whitelist connection reservation feature
- // does not inadvertently reduce the default
- // inbound connection capacity of the network.
- nMaxConnections += nWhiteConnections;
- }
- } else {
- // User not using whitelist feature.
- // Silently disable connection reservation,
- // for the same reason as above.
- nWhiteConnections = 0;
- }
// Trim requested connection counts, to fit into system limitations
nMaxConnections = std::max(std::min(nMaxConnections, (int)(FD_SETSIZE - nBind - MIN_CORE_FILEDESCRIPTORS)), 0);
@@ -784,13 +816,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (nMaxConnections < nUserMaxConnections)
InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections));
- // Connection capacity is prioritized in this order:
- // outbound connections (hardcoded to 8),
- // then whitelisted connections,
- // then non-whitelisted connections get whatever's left (if any).
- if ((nWhiteConnections > 0) && (nWhiteConnections >= (nMaxConnections - 8)))
- InitWarning(strprintf(_("All non-whitelisted incoming connections will be dropped, because -whiteconnections is %d and -maxconnections is only %d."), nWhiteConnections, nMaxConnections));
-
// ********************************************************* Step 3: parameter-to-internal-flags
fDebug = !mapMultiArgs["-debug"].empty();
@@ -817,6 +842,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
fCheckBlockIndex = GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks());
fCheckpointsEnabled = GetBoolArg("-checkpoints", true);
+ // -mempoollimit limits
+ int64_t nMempoolSizeLimit = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
+ int64_t nMempoolDescendantSizeLimit = GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000;
+ if (nMempoolSizeLimit < 0 || nMempoolSizeLimit < nMempoolDescendantSizeLimit * 40)
+ return InitError(strprintf(_("Error: -maxmempool must be at least %d MB"), GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) / 25));
+
// -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
nScriptCheckThreads = GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
if (nScriptCheckThreads <= 0)
@@ -828,7 +859,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
fServer = GetBoolArg("-server", false);
- // block pruning; get the amount of disk space (in MB) to allot for block & undo files
+ // block pruning; get the amount of disk space (in MiB) to allot for block & undo files
int64_t nSignedPruneTarget = GetArg("-prune", 0) * 1024 * 1024;
if (nSignedPruneTarget < 0) {
return InitError(_("Prune cannot be configured with a negative value."));
@@ -836,7 +867,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
nPruneTarget = (uint64_t) nSignedPruneTarget;
if (nPruneTarget) {
if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) {
- return InitError(strprintf(_("Prune configured below the minimum of %d MB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
+ return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
}
LogPrintf("Prune configured to target %uMiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024);
fPruneMode = true;
@@ -921,6 +952,9 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Option to startup with mocktime set (used for regression testing):
SetMockTime(GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
+ if (GetBoolArg("-peerbloomfilters", true))
+ nLocalServices |= NODE_BLOOM;
+
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
// Initialize elliptic curve code
@@ -968,8 +1002,6 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
LogPrintf("Using data directory %s\n", strDataDir);
LogPrintf("Using config file %s\n", GetConfigFile().string());
LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
- if (nWhiteConnections > 0)
- LogPrintf("Reserving %i of these connections for whitelisted inbound peers\n", nWhiteConnections);
std::ostringstream strErrors;
LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads);
@@ -990,9 +1022,8 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (fServer)
{
uiInterface.InitMessage.connect(SetRPCWarmupStatus);
- RPCServer::OnStopped(&OnRPCStopped);
- RPCServer::OnPreCommand(&OnRPCPreCommand);
- StartRPCThreads();
+ if (!AppInitServers(threadGroup))
+ return InitError(_("Unable to start HTTP server. See debug log for details."));
}
int64_t nStart;
@@ -1012,7 +1043,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
if (!warningString.empty())
InitWarning(warningString);
if (!errorString.empty())
- return InitError(warningString);
+ return InitError(errorString);
} // (!fDisableWallet)
#endif // ENABLE_WALLET
@@ -1020,8 +1051,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
RegisterNodeSignals(GetNodeSignals());
- // format user agent, check total size
- strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, mapMultiArgs.count("-uacomment") ? mapMultiArgs["-uacomment"] : std::vector<string>());
+ // sanitize comments per BIP-0014, format user agent and check total size
+ std::vector<string> uacomments;
+ BOOST_FOREACH(string cmt, mapMultiArgs["-uacomment"])
+ {
+ if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT))
+ return InitError(strprintf("User Agent comment (%s) contains unsafe characters.", cmt));
+ uacomments.push_back(SanitizeString(cmt, SAFE_CHARS_UA_COMMENT));
+ }
+ strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments);
if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) {
return InitError(strprintf("Total length of network version string %i exceeds maximum of %i characters. Reduce the number and/or size of uacomments.",
strSubVersion.size(), MAX_SUBVERSION_LENGTH));
@@ -1128,6 +1166,15 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
BOOST_FOREACH(const std::string& strDest, mapMultiArgs["-seednode"])
AddOneShot(strDest);
+#if ENABLE_ZMQ
+ pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs);
+
+ if (pzmqNotificationInterface) {
+ pzmqNotificationInterface->Initialize();
+ RegisterValidationInterface(pzmqNotificationInterface);
+ }
+#endif
+
// ********************************************************* Step 7: load block chain
fReindex = GetBoolArg("-reindex", false);
@@ -1520,7 +1567,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
// Generate coins in the background
GenerateBitcoins(GetBoolArg("-gen", false), GetArg("-genproclimit", 1), Params());
- // ********************************************************* Step 11: finished
+ // ********************************************************* Step 12: finished
SetRPCWarmupFinished();
uiInterface.InitMessage(_("Done loading"));