diff options
Diffstat (limited to 'src/init.cpp')
-rw-r--r-- | src/init.cpp | 181 |
1 files changed, 72 insertions, 109 deletions
diff --git a/src/init.cpp b/src/init.cpp index b6e4cd06f6..672ef77e80 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -88,14 +88,6 @@ static CZMQNotificationInterface* pzmqNotificationInterface = NULL; #define MIN_CORE_FILEDESCRIPTORS 150 #endif -/** Used to pass flags to the Bind() function */ -enum BindFlags { - BF_NONE = 0, - BF_EXPLICIT = (1U << 0), - BF_REPORT_ERROR = (1U << 1), - BF_WHITELIST = (1U << 2), -}; - static const char* FEE_ESTIMATES_FILENAME="fee_estimates.dat"; ////////////////////////////////////////////////////////////////////////////// @@ -296,17 +288,6 @@ static void registerSignalHandler(int signal, void(*handler)(int)) } #endif -bool static Bind(CConnman& connman, const CService &addr, unsigned int flags) { - if (!(flags & BF_EXPLICIT) && IsLimited(addr)) - return false; - std::string strError; - if (!connman.BindListenPort(addr, strError, (flags & BF_WHITELIST) != 0)) { - if (flags & BF_REPORT_ERROR) - return InitError(strError); - return false; - } - return true; -} void OnRPCStarted() { uiInterface.NotifyBlockTip.connect(&RPCNotifyBlockChange); @@ -355,6 +336,9 @@ std::string HelpMessage(HelpMessageMode mode) #endif } strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory")); + if (showDebug) { + strUsage += HelpMessageOpt("-dbbatchsize", strprintf("Maximum database write batch size in bytes (default: %u)", nDefaultDbBatchSize)); + } strUsage += HelpMessageOpt("-dbcache=<n>", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); if (showDebug) strUsage += HelpMessageOpt("-feefilter", strprintf("Tell other nodes to filter invs to us by our mempool min fee (default: %u)", DEFAULT_FEEFILTER)); @@ -463,7 +447,7 @@ std::string HelpMessage(HelpMessageMode mode) { strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS)); strUsage += HelpMessageOpt("-mocktime=<n>", "Replace actual time with <n> seconds since epoch (default: 0)"); - strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit size of signature cache to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE)); + strUsage += HelpMessageOpt("-maxsigcachesize=<n>", strprintf("Limit sum of signature cache and script execution cache sizes to <n> MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE)); strUsage += HelpMessageOpt("-maxtipage=<n>", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE)); } strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees (in %s) to use in a single wallet transaction or raw transaction; setting this too low may abort large transactions (default: %s)"), @@ -822,7 +806,7 @@ int nUserMaxConnections; int nFD; ServiceFlags nLocalServices = NODE_NETWORK; -} +} // namespace [[noreturn]] static void new_handler_terminate() { @@ -844,8 +828,6 @@ bool AppInitBasicSetup() // Turn off Microsoft heap dump noise _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0)); -#endif -#if _MSC_VER >= 1400 // Disable confusing "helpful" text message on abort, Ctrl-C _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); #endif @@ -900,10 +882,14 @@ bool AppInitParameterInteraction() return InitError(_("Prune mode is incompatible with -txindex.")); } + // -bind and -whitebind can't be set when not listening + size_t nUserBind = gArgs.GetArgs("-bind").size() + gArgs.GetArgs("-whitebind").size(); + if (nUserBind != 0 && !gArgs.GetBoolArg("-listen", DEFAULT_LISTEN)) { + return InitError("Cannot set -bind or -whitebind together with -listen=0"); + } + // Make sure enough file descriptors are available - int nBind = std::max( - (gArgs.IsArgSet("-bind") ? gArgs.GetArgs("-bind").size() : 0) + - (gArgs.IsArgSet("-whitebind") ? gArgs.GetArgs("-whitebind").size() : 0), size_t(1)); + int nBind = std::max(nUserBind, size_t(1)); nUserMaxConnections = GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); nMaxConnections = std::max(nUserMaxConnections, 0); @@ -935,15 +921,13 @@ bool AppInitParameterInteraction() } // Now remove the logging categories which were explicitly excluded - if (gArgs.IsArgSet("-debugexclude")) { - for (const std::string& cat : gArgs.GetArgs("-debugexclude")) { - uint32_t flag = 0; - if (!GetLogCategory(&flag, &cat)) { - InitWarning(strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat)); - continue; - } - logCategories &= ~flag; + for (const std::string& cat : gArgs.GetArgs("-debugexclude")) { + uint32_t flag = 0; + if (!GetLogCategory(&flag, &cat)) { + InitWarning(strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat)); + continue; } + logCategories &= ~flag; } // Check for -debugnet @@ -1030,14 +1014,7 @@ bool AppInitParameterInteraction() if (nConnectTimeout <= 0) nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; - // Fee-per-kilobyte amount required for mempool acceptance and relay - // If you are mining, be careful setting this: - // if you set it to zero then - // a transaction spammer can cheaply fill blocks using - // 0-fee transactions. It should be set above the real - // cost to you of processing a transaction. - if (IsArgSet("-minrelaytxfee")) - { + if (IsArgSet("-minrelaytxfee")) { CAmount n = 0; if (!ParseMoney(GetArg("-minrelaytxfee", ""), n)) { return InitError(AmountErrMsg("minrelaytxfee", GetArg("-minrelaytxfee", ""))); @@ -1170,6 +1147,7 @@ bool AppInitSanityChecks() // ********************************************************* Step 4: sanity checks // Initialize elliptic curve code + RandomInit(); ECC_Start(); globalVerifyHandle.reset(new ECCVerifyHandle()); @@ -1213,6 +1191,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD); InitSignatureCache(); + InitScriptExecutionCache(); LogPrintf("Using %u threads for script verification\n", nScriptCheckThreads); if (nScriptCheckThreads) { @@ -1259,13 +1238,10 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // sanitize comments per BIP-0014, format user agent and check total size std::vector<std::string> uacomments; - if (gArgs.IsArgSet("-uacomment")) { - for (std::string cmt : gArgs.GetArgs("-uacomment")) - { - if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) - return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt)); - uacomments.push_back(cmt); - } + for (const std::string& cmt : gArgs.GetArgs("-uacomment")) { + if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) + return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt)); + uacomments.push_back(cmt); } strSubVersion = FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments); if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) { @@ -1288,16 +1264,6 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } } - if (gArgs.IsArgSet("-whitelist")) { - for (const std::string& net : gArgs.GetArgs("-whitelist")) { - CSubNet subnet; - LookupSubNet(net.c_str(), subnet); - if (!subnet.IsValid()) - return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net)); - connman.AddWhitelistedRange(subnet); - } - } - // Check for host lookup allowed before parsing any network related parameters fNameLookup = GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); @@ -1348,44 +1314,12 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fDiscover = GetBoolArg("-discover", true); fRelayTxes = !GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); - if (fListen) { - bool fBound = false; - if (gArgs.IsArgSet("-bind")) { - for (const std::string& strBind : gArgs.GetArgs("-bind")) { - CService addrBind; - if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) - return InitError(ResolveErrMsg("bind", strBind)); - fBound |= Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR)); - } - } - if (gArgs.IsArgSet("-whitebind")) { - for (const std::string& strBind : gArgs.GetArgs("-whitebind")) { - CService addrBind; - if (!Lookup(strBind.c_str(), addrBind, 0, false)) - return InitError(ResolveErrMsg("whitebind", strBind)); - if (addrBind.GetPort() == 0) - return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind)); - fBound |= Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST)); - } - } - if (!gArgs.IsArgSet("-bind") && !gArgs.IsArgSet("-whitebind")) { - struct in_addr inaddr_any; - inaddr_any.s_addr = INADDR_ANY; - fBound |= Bind(connman, CService(in6addr_any, GetListenPort()), BF_NONE); - fBound |= Bind(connman, CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE); - } - if (!fBound) - return InitError(_("Failed to listen on any port. Use -listen=0 if you want this.")); - } - - if (gArgs.IsArgSet("-externalip")) { - for (const std::string& strAddr : gArgs.GetArgs("-externalip")) { - CService addrLocal; - if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) - AddLocal(addrLocal, LOCAL_MANUAL); - else - return InitError(ResolveErrMsg("externalip", strAddr)); - } + for (const std::string& strAddr : gArgs.GetArgs("-externalip")) { + CService addrLocal; + if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) + AddLocal(addrLocal, LOCAL_MANUAL); + else + return InitError(ResolveErrMsg("externalip", strAddr)); } #if ENABLE_ZMQ @@ -1407,8 +1341,6 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fReindex = GetBoolArg("-reindex", false); bool fReindexChainState = GetBoolArg("-reindex-chainstate", false); - fs::create_directories(GetDataDir() / "blocks"); - // cache size calculations int64_t nTotalCache = (GetArg("-dbcache", nDefaultDbCache) << 20); nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache @@ -1427,7 +1359,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) LogPrintf("* Using %.1fMiB for in-memory UTXO set (plus up to %.1fMiB of unused mempool space)\n", nCoinCacheUsage * (1.0 / 1024 / 1024), nMempoolSizeMax * (1.0 / 1024 / 1024)); bool fLoaded = false; - while (!fLoaded) { + while (!fLoaded && !fRequestShutdown) { bool fReset = fReindex; std::string strLoadError; @@ -1445,7 +1377,6 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex); pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex || fReindexChainState); pcoinscatcher = new CCoinsViewErrorCatcher(pcoinsdbview); - pcoinsTip = new CCoinsViewCache(pcoinscatcher); if (fReindex) { pblocktree->WriteReindexing(true); @@ -1459,6 +1390,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) break; } } + if (fRequestShutdown) break; if (!LoadBlockIndex(chainparams)) { strLoadError = _("Error loading block database"); @@ -1489,6 +1421,13 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) break; } + if (!ReplayBlocks(chainparams, pcoinsdbview)) { + strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate."); + break; + } + pcoinsTip = new CCoinsViewCache(pcoinscatcher); + LoadChainTip(chainparams); + if (!fReindex && chainActive.Tip() != NULL) { uiInterface.InitMessage(_("Rewinding blocks...")); if (!RewindBlockIndex(chainparams)) { @@ -1529,7 +1468,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fLoaded = true; } while(false); - if (!fLoaded) { + if (!fLoaded && !fRequestShutdown) { // first suggest a reindex if (!fReset) { bool fRet = uiInterface.ThreadSafeQuestion( @@ -1616,10 +1555,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); std::vector<fs::path> vImportFiles; - if (gArgs.IsArgSet("-loadblock")) - { - for (const std::string& strFile : gArgs.GetArgs("-loadblock")) - vImportFiles.push_back(strFile); + for (const std::string& strFile : gArgs.GetArgs("-loadblock")) { + vImportFiles.push_back(strFile); } threadGroup.create_thread(boost::bind(&ThreadImport, vImportFiles)); @@ -1646,7 +1583,6 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // Map ports with UPnP MapPort(GetBoolArg("-upnp", DEFAULT_UPNP)); - std::string strNodeError; CConnman::Options connOptions; connOptions.nLocalServices = nLocalServices; connOptions.nRelevantServices = nRelevantServices; @@ -1662,12 +1598,39 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) connOptions.nMaxOutboundTimeframe = nMaxOutboundTimeframe; connOptions.nMaxOutboundLimit = nMaxOutboundLimit; + for (const std::string& strBind : gArgs.GetArgs("-bind")) { + CService addrBind; + if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false)) { + return InitError(ResolveErrMsg("bind", strBind)); + } + connOptions.vBinds.push_back(addrBind); + } + for (const std::string& strBind : gArgs.GetArgs("-whitebind")) { + CService addrBind; + if (!Lookup(strBind.c_str(), addrBind, 0, false)) { + return InitError(ResolveErrMsg("whitebind", strBind)); + } + if (addrBind.GetPort() == 0) { + return InitError(strprintf(_("Need to specify a port with -whitebind: '%s'"), strBind)); + } + connOptions.vWhiteBinds.push_back(addrBind); + } + + for (const auto& net : gArgs.GetArgs("-whitelist")) { + CSubNet subnet; + LookupSubNet(net.c_str(), subnet); + if (!subnet.IsValid()) + return InitError(strprintf(_("Invalid netmask specified in -whitelist: '%s'"), net)); + connOptions.vWhitelistedRange.push_back(subnet); + } + if (gArgs.IsArgSet("-seednode")) { connOptions.vSeedNodes = gArgs.GetArgs("-seednode"); } - if (!connman.Start(scheduler, strNodeError, connOptions)) - return InitError(strNodeError); + if (!connman.Start(scheduler, connOptions)) { + return false; + } // ********************************************************* Step 12: finished |