diff options
author | fanquake <fanquake@gmail.com> | 2020-08-26 14:59:33 +0800 |
---|---|---|
committer | fanquake <fanquake@gmail.com> | 2020-08-26 15:18:38 +0800 |
commit | 6a2ba626852bd5bd8531dfa335c78fa87e4f6282 (patch) | |
tree | 869f30a41fccc0880e0a2e60cf33ec1044bd1a2f /src | |
parent | 92735e45badfa98ee3c6f4e69b8858119bc09406 (diff) | |
parent | fa9d5902f7d72e8cce105dd1b1f5a1062e304b10 (diff) |
Merge #19779: Remove gArgs global from init
fa9d5902f7d72e8cce105dd1b1f5a1062e304b10 scripted-diff: gArgs -> args (MarcoFalke)
fa33bc2dabbbd2d73961f9b0ce51420a3b6e4ad5 init: Capture copy of blocknotify setting for BlockNotifyCallback (MarcoFalke)
fa40017706e08b4de111e8e57aabeced60881a57 init: Pass reference to ArgsManager around instead of relying on global (MarcoFalke)
Pull request description:
The gArgs global has several issues:
* gArgs is used by each process (bitcoind, bitcoin-qt, bitcoin-wallet, bitcoin-cli, bitcoin-tx, ...), but it is hard to determine which arguments are actually used by each process. For example arguments that have never been registered, but are still used, will always return the fallback value.
* Tests may run several sub-tests, which need different settings. So globals will have to be overwritten, but that is fragile on its own: e.g. https://github.com/bitcoin/bitcoin/pull/19704#issuecomment-678259092 or #19511
The goal is to remove gArgs, but as a first step in that direction this pull will change gArgs in init to use a passed-in reference instead.
ACKs for top commit:
ryanofsky:
Code review ACK fa9d5902f7d72e8cce105dd1b1f5a1062e304b10. Looks good. Nice day to remove some globals, and add some lambdas :+1:
fanquake:
ACK fa9d5902f7d72e8cce105dd1b1f5a1062e304b10 - I'm not as familiar with the settings & argument handling code, but this make sense, and is a step in the right direction towards a reduction in the usage of globals. Not a huge fan of the clang-formatting in the scripted diff.
jonasschnelli:
Concept ACK fa9d5902f7d72e8cce105dd1b1f5a1062e304b10
Tree-SHA512: ed00db5f826566c7e3b4d0b3d2ee0fc1a49a6e748e04e5c93bdd694ac7da5598749e73937047d5fce86150d764a067d2ca344ba4ae3eb2704cc5c4fa0d20940f
Diffstat (limited to 'src')
-rw-r--r-- | src/bitcoind.cpp | 40 | ||||
-rw-r--r-- | src/init.cpp | 327 | ||||
-rw-r--r-- | src/init.h | 10 | ||||
-rw-r--r-- | src/interfaces/node.cpp | 6 | ||||
-rw-r--r-- | src/test/util/setup_common.cpp | 4 |
5 files changed, 189 insertions, 198 deletions
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index b04cc12059..227626f40f 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -50,28 +50,23 @@ static bool AppInit(int argc, char* argv[]) util::ThreadSetInternalName("init"); - // - // Parameters - // // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's main() SetupServerArgs(node); + ArgsManager& args = *Assert(node.args); std::string error; - if (!gArgs.ParseParameters(argc, argv, error)) { + if (!args.ParseParameters(argc, argv, error)) { return InitError(Untranslated(strprintf("Error parsing command line arguments: %s\n", error))); } // Process help and version before taking care about datadir - if (HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { + if (HelpRequested(args) || args.IsArgSet("-version")) { std::string strUsage = PACKAGE_NAME " version " + FormatFullVersion() + "\n"; - if (gArgs.IsArgSet("-version")) - { + if (args.IsArgSet("-version")) { strUsage += FormatParagraph(LicenseInfo()) + "\n"; - } - else - { + } else { strUsage += "\nUsage: bitcoind [options] Start " PACKAGE_NAME "\n"; - strUsage += "\n" + gArgs.GetHelpMessage(); + strUsage += "\n" + args.GetHelpMessage(); } tfm::format(std::cout, "%s", strUsage); @@ -82,14 +77,14 @@ static bool AppInit(int argc, char* argv[]) try { if (!CheckDataDirOption()) { - return InitError(Untranslated(strprintf("Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "")))); + return InitError(Untranslated(strprintf("Specified data directory \"%s\" does not exist.\n", args.GetArg("-datadir", "")))); } - if (!gArgs.ReadConfigFiles(error, true)) { + if (!args.ReadConfigFiles(error, true)) { return InitError(Untranslated(strprintf("Error reading configuration file: %s\n", error))); } // Check for -chain, -testnet or -regtest parameter (Params() calls are only valid after this clause) try { - SelectParams(gArgs.GetChainName()); + SelectParams(args.GetChainName()); } catch (const std::exception& e) { return InitError(Untranslated(strprintf("%s\n", e.what()))); } @@ -101,23 +96,21 @@ static bool AppInit(int argc, char* argv[]) } } - if (!gArgs.InitSettings(error)) { + if (!args.InitSettings(error)) { InitError(Untranslated(error)); return false; } // -server defaults to true for bitcoind but not for the GUI so do this here - gArgs.SoftSetBoolArg("-server", true); + args.SoftSetBoolArg("-server", true); // Set this early so that parameter interactions go to console - InitLogging(); - InitParameterInteraction(); - if (!AppInitBasicSetup()) - { + InitLogging(args); + InitParameterInteraction(args); + if (!AppInitBasicSetup(args)) { // InitError will have been called with detailed error, which ends up on console return false; } - if (!AppInitParameterInteraction()) - { + if (!AppInitParameterInteraction(args)) { // InitError will have been called with detailed error, which ends up on console return false; } @@ -126,8 +119,7 @@ static bool AppInit(int argc, char* argv[]) // InitError will have been called with detailed error, which ends up on console return false; } - if (gArgs.GetBoolArg("-daemon", false)) - { + if (args.GetBoolArg("-daemon", false)) { #if HAVE_DECL_DAEMON #if defined(MAC_OSX) #pragma GCC diagnostic push diff --git a/src/init.cpp b/src/init.cpp index ebea6037d6..ecd57960ad 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -107,14 +107,14 @@ static const char* DEFAULT_ASMAP_FILENAME="ip_asn.map"; */ static const char* BITCOIN_PID_FILENAME = "bitcoind.pid"; -static fs::path GetPidFile() +static fs::path GetPidFile(const ArgsManager& args) { - return AbsPathForConfigVal(fs::path(gArgs.GetArg("-pid", BITCOIN_PID_FILENAME))); + return AbsPathForConfigVal(fs::path(args.GetArg("-pid", BITCOIN_PID_FILENAME))); } -NODISCARD static bool CreatePidFile() +NODISCARD static bool CreatePidFile(const ArgsManager& args) { - fsbridge::ofstream file{GetPidFile()}; + fsbridge::ofstream file{GetPidFile(args)}; if (file) { #ifdef WIN32 tfm::format(file, "%d\n", GetCurrentProcessId()); @@ -123,7 +123,7 @@ NODISCARD static bool CreatePidFile() #endif return true; } else { - return InitError(strprintf(_("Unable to create the PID file '%s': %s"), GetPidFile().string(), std::strerror(errno))); + return InitError(strprintf(_("Unable to create the PID file '%s': %s"), GetPidFile(args).string(), std::strerror(errno))); } } @@ -180,6 +180,7 @@ void Shutdown(NodeContext& node) TRY_LOCK(g_shutdown_mutex, lock_shutdown); if (!lock_shutdown) return; LogPrintf("%s: In progress...\n", __func__); + Assert(node.args); /// Note: Shutdown() must be able to handle cases in which initialization failed part of the way, /// for example if the data directory was found to be locked. @@ -230,7 +231,7 @@ void Shutdown(NodeContext& node) node.connman.reset(); node.banman.reset(); - if (::mempool.IsLoaded() && gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { + if (::mempool.IsLoaded() && node.args->GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { DumpMempool(::mempool); } @@ -301,19 +302,19 @@ void Shutdown(NodeContext& node) GetMainSignals().UnregisterBackgroundSignalScheduler(); globalVerifyHandle.reset(); ECC_Stop(); - node.args = nullptr; node.mempool = nullptr; node.chainman = nullptr; node.scheduler.reset(); try { - if (!fs::remove(GetPidFile())) { + if (!fs::remove(GetPidFile(*node.args))) { LogPrintf("%s: Unable to remove PID file: File does not exist\n", __func__); } } catch (const fs::filesystem_error& e) { LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e)); } + node.args = nullptr; LogPrintf("%s: done\n", __func__); } @@ -372,7 +373,7 @@ void SetupServerArgs(NodeContext& node) node.args = &gArgs; ArgsManager& argsman = *node.args; - SetupHelpOptions(gArgs); + SetupHelpOptions(argsman); argsman.AddArg("-help-debug", "Print help message with debugging options and exit", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); // server-only for now const auto defaultBaseParams = CreateBaseChainParams(CBaseChainParams::MAIN); @@ -599,21 +600,6 @@ std::string LicenseInfo() "\n"; } -#if HAVE_SYSTEM -static void BlockNotifyCallback(SynchronizationState sync_state, const CBlockIndex* pBlockIndex) -{ - if (sync_state != SynchronizationState::POST_INIT || !pBlockIndex) - return; - - std::string strCmd = gArgs.GetArg("-blocknotify", ""); - if (!strCmd.empty()) { - boost::replace_all(strCmd, "%s", pBlockIndex->GetBlockHash().GetHex()); - std::thread t(runCommand, strCmd); - t.detach(); // thread runs free - } -} -#endif - static bool fHaveGenesis = false; static Mutex g_genesis_wait_mutex; static std::condition_variable g_genesis_wait_cv; @@ -684,7 +670,7 @@ static void CleanupBlockRevFiles() } } -static void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles) +static void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args) { const CChainParams& chainparams = Params(); ScheduleBatchPriority(); @@ -746,13 +732,13 @@ static void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImp } } - if (gArgs.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) { + if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) { LogPrintf("Stopping after block import\n"); StartShutdown(); return; } } // End scope of CImportingNow - if (gArgs.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { + if (args.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) { LoadMempool(::mempool); } ::mempool.SetIsLoaded(!ShutdownRequested()); @@ -780,6 +766,7 @@ static bool InitSanityCheck() static bool AppInitServers(const util::Ref& context, NodeContext& node) { + const ArgsManager& args = *Assert(node.args); RPCServer::OnStarted(&OnRPCStarted); RPCServer::OnStopped(&OnRPCStopped); if (!InitHTTPServer()) @@ -788,71 +775,71 @@ static bool AppInitServers(const util::Ref& context, NodeContext& node) node.rpc_interruption_point = RpcInterruptionPoint; if (!StartHTTPRPC(context)) return false; - if (gArgs.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) StartREST(context); + if (args.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) StartREST(context); StartHTTPServer(); return true; } // Parameter interaction based on rules -void InitParameterInteraction() +void InitParameterInteraction(ArgsManager& args) { // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified - if (gArgs.IsArgSet("-bind")) { - if (gArgs.SoftSetBoolArg("-listen", true)) + if (args.IsArgSet("-bind")) { + if (args.SoftSetBoolArg("-listen", true)) LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__); } - if (gArgs.IsArgSet("-whitebind")) { - if (gArgs.SoftSetBoolArg("-listen", true)) + if (args.IsArgSet("-whitebind")) { + if (args.SoftSetBoolArg("-listen", true)) LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__); } - if (gArgs.IsArgSet("-connect")) { + if (args.IsArgSet("-connect")) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default - if (gArgs.SoftSetBoolArg("-dnsseed", false)) + if (args.SoftSetBoolArg("-dnsseed", false)) LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__); - if (gArgs.SoftSetBoolArg("-listen", false)) + if (args.SoftSetBoolArg("-listen", false)) LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__); } - if (gArgs.IsArgSet("-proxy")) { + if (args.IsArgSet("-proxy")) { // to protect privacy, do not listen by default if a default proxy server is specified - if (gArgs.SoftSetBoolArg("-listen", false)) + if (args.SoftSetBoolArg("-listen", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__); // to protect privacy, do not use UPNP when a proxy is set. The user may still specify -listen=1 // to listen locally, so don't rely on this happening through -listen below. - if (gArgs.SoftSetBoolArg("-upnp", false)) + if (args.SoftSetBoolArg("-upnp", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -upnp=0\n", __func__); // to protect privacy, do not discover addresses by default - if (gArgs.SoftSetBoolArg("-discover", false)) + if (args.SoftSetBoolArg("-discover", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -discover=0\n", __func__); } - if (!gArgs.GetBoolArg("-listen", DEFAULT_LISTEN)) { + if (!args.GetBoolArg("-listen", DEFAULT_LISTEN)) { // do not map ports or try to retrieve public IP when not listening (pointless) - if (gArgs.SoftSetBoolArg("-upnp", false)) + if (args.SoftSetBoolArg("-upnp", false)) LogPrintf("%s: parameter interaction: -listen=0 -> setting -upnp=0\n", __func__); - if (gArgs.SoftSetBoolArg("-discover", false)) + if (args.SoftSetBoolArg("-discover", false)) LogPrintf("%s: parameter interaction: -listen=0 -> setting -discover=0\n", __func__); - if (gArgs.SoftSetBoolArg("-listenonion", false)) + if (args.SoftSetBoolArg("-listenonion", false)) LogPrintf("%s: parameter interaction: -listen=0 -> setting -listenonion=0\n", __func__); } - if (gArgs.IsArgSet("-externalip")) { + if (args.IsArgSet("-externalip")) { // if an explicit public IP is specified, do not try to find others - if (gArgs.SoftSetBoolArg("-discover", false)) + if (args.SoftSetBoolArg("-discover", false)) LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__); } // disable whitelistrelay in blocksonly mode - if (gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) { - if (gArgs.SoftSetBoolArg("-whitelistrelay", false)) + if (args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) { + if (args.SoftSetBoolArg("-whitelistrelay", false)) LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -whitelistrelay=0\n", __func__); } // Forcing relay from whitelisted hosts implies we will accept relays from them in the first place. - if (gArgs.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { - if (gArgs.SoftSetBoolArg("-whitelistrelay", true)) + if (args.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) { + if (args.SoftSetBoolArg("-whitelistrelay", true)) LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1\n", __func__); } } @@ -863,18 +850,18 @@ void InitParameterInteraction() * Note that this is called very early in the process lifetime, so you should be * careful about what global state you rely on here. */ -void InitLogging() +void InitLogging(const ArgsManager& args) { - LogInstance().m_print_to_file = !gArgs.IsArgNegated("-debuglogfile"); - LogInstance().m_file_path = AbsPathForConfigVal(gArgs.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE)); - LogInstance().m_print_to_console = gArgs.GetBoolArg("-printtoconsole", !gArgs.GetBoolArg("-daemon", false)); - LogInstance().m_log_timestamps = gArgs.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); - LogInstance().m_log_time_micros = gArgs.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); + LogInstance().m_print_to_file = !args.IsArgNegated("-debuglogfile"); + LogInstance().m_file_path = AbsPathForConfigVal(args.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE)); + LogInstance().m_print_to_console = args.GetBoolArg("-printtoconsole", !args.GetBoolArg("-daemon", false)); + LogInstance().m_log_timestamps = args.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS); + LogInstance().m_log_time_micros = args.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS); #ifdef HAVE_THREAD_LOCAL - LogInstance().m_log_threadnames = gArgs.GetBoolArg("-logthreadnames", DEFAULT_LOGTHREADNAMES); + LogInstance().m_log_threadnames = args.GetBoolArg("-logthreadnames", DEFAULT_LOGTHREADNAMES); #endif - fLogIPs = gArgs.GetBoolArg("-logips", DEFAULT_LOGIPS); + fLogIPs = args.GetBoolArg("-logips", DEFAULT_LOGIPS); std::string version_string = FormatFullVersion(); #ifdef DEBUG @@ -909,7 +896,7 @@ std::set<BlockFilterType> g_enabled_filter_types; std::terminate(); }; -bool AppInitBasicSetup() +bool AppInitBasicSetup(ArgsManager& args) { // ********************************************************* Step 1: setup #ifdef _MSC_VER @@ -929,7 +916,7 @@ bool AppInitBasicSetup() } #ifndef WIN32 - if (!gArgs.GetBoolArg("-sysperms", false)) { + if (!args.GetBoolArg("-sysperms", false)) { umask(077); } @@ -951,7 +938,7 @@ bool AppInitBasicSetup() return true; } -bool AppInitParameterInteraction() +bool AppInitParameterInteraction(const ArgsManager& args) { const CChainParams& chainparams = Params(); // ********************************************************* Step 2: parameter interactions @@ -961,9 +948,9 @@ bool AppInitParameterInteraction() // Error if network-specific options (-addnode, -connect, etc) are // specified in default section of config file, but not overridden // on the command line or in this network's section of the config file. - std::string network = gArgs.GetChainName(); + std::string network = args.GetChainName(); bilingual_str errors; - for (const auto& arg : gArgs.GetUnsuitableSectionOnlyArgs()) { + for (const auto& arg : args.GetUnsuitableSectionOnlyArgs()) { errors += strprintf(_("Config setting for %s only applied on %s network when in [%s] section.") + Untranslated("\n"), arg, network, network); } @@ -973,7 +960,7 @@ bool AppInitParameterInteraction() // Warn if unrecognized section name are present in the config file. bilingual_str warnings; - for (const auto& section : gArgs.GetUnrecognizedSections()) { + for (const auto& section : args.GetUnrecognizedSections()) { warnings += strprintf(Untranslated("%s:%i ") + _("Section [%s] is not recognized.") + Untranslated("\n"), section.m_file, section.m_line, section.m_name); } @@ -982,15 +969,15 @@ bool AppInitParameterInteraction() } if (!fs::is_directory(GetBlocksDir())) { - return InitError(strprintf(_("Specified blocks directory \"%s\" does not exist."), gArgs.GetArg("-blocksdir", ""))); + return InitError(strprintf(_("Specified blocks directory \"%s\" does not exist."), args.GetArg("-blocksdir", ""))); } // parse and validate enabled filter types - std::string blockfilterindex_value = gArgs.GetArg("-blockfilterindex", DEFAULT_BLOCKFILTERINDEX); + std::string blockfilterindex_value = args.GetArg("-blockfilterindex", DEFAULT_BLOCKFILTERINDEX); if (blockfilterindex_value == "" || blockfilterindex_value == "1") { g_enabled_filter_types = AllBlockFilterTypes(); } else if (blockfilterindex_value != "0") { - const std::vector<std::string> names = gArgs.GetArgs("-blockfilterindex"); + const std::vector<std::string> names = args.GetArgs("-blockfilterindex"); for (const auto& name : names) { BlockFilterType filter_type; if (!BlockFilterTypeByName(name, filter_type)) { @@ -1001,7 +988,7 @@ bool AppInitParameterInteraction() } // Signal NODE_COMPACT_FILTERS if peerblockfilters and basic filters index are both enabled. - if (gArgs.GetBoolArg("-peerblockfilters", DEFAULT_PEERBLOCKFILTERS)) { + if (args.GetBoolArg("-peerblockfilters", DEFAULT_PEERBLOCKFILTERS)) { if (g_enabled_filter_types.count(BlockFilterType::BASIC) != 1) { return InitError(_("Cannot set -peerblockfilters without -blockfilterindex.")); } @@ -1010,8 +997,8 @@ bool AppInitParameterInteraction() } // if using block pruning, then disallow txindex - if (gArgs.GetArg("-prune", 0)) { - if (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) + if (args.GetArg("-prune", 0)) { + if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) return InitError(_("Prune mode is incompatible with -txindex.")); if (!g_enabled_filter_types.empty()) { return InitError(_("Prune mode is incompatible with -blockfilterindex.")); @@ -1019,14 +1006,14 @@ bool AppInitParameterInteraction() } // -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)) { + size_t nUserBind = args.GetArgs("-bind").size() + args.GetArgs("-whitebind").size(); + if (nUserBind != 0 && !args.GetBoolArg("-listen", DEFAULT_LISTEN)) { return InitError(Untranslated("Cannot set -bind or -whitebind together with -listen=0")); } // Make sure enough file descriptors are available int nBind = std::max(nUserBind, size_t(1)); - nUserMaxConnections = gArgs.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); + nUserMaxConnections = args.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS); nMaxConnections = std::max(nUserMaxConnections, 0); // Trim requested connection counts, to fit into system limitations @@ -1046,9 +1033,9 @@ bool AppInitParameterInteraction() InitWarning(strprintf(_("Reducing -maxconnections from %d to %d, because of system limitations."), nUserMaxConnections, nMaxConnections)); // ********************************************************* Step 3: parameter-to-internal-flags - if (gArgs.IsArgSet("-debug")) { + if (args.IsArgSet("-debug")) { // Special-case: if -debug=0/-nodebug is set, turn off debugging messages - const std::vector<std::string> categories = gArgs.GetArgs("-debug"); + const std::vector<std::string> categories = args.GetArgs("-debug"); if (std::none_of(categories.begin(), categories.end(), [](std::string cat){return cat == "0" || cat == "none";})) { @@ -1061,28 +1048,28 @@ bool AppInitParameterInteraction() } // Now remove the logging categories which were explicitly excluded - for (const std::string& cat : gArgs.GetArgs("-debugexclude")) { + for (const std::string& cat : args.GetArgs("-debugexclude")) { if (!LogInstance().DisableCategory(cat)) { InitWarning(strprintf(_("Unsupported logging category %s=%s."), "-debugexclude", cat)); } } // Checkmempool and checkblockindex default to true in regtest mode - int ratio = std::min<int>(std::max<int>(gArgs.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); + int ratio = std::min<int>(std::max<int>(args.GetArg("-checkmempool", chainparams.DefaultConsistencyChecks() ? 1 : 0), 0), 1000000); if (ratio != 0) { mempool.setSanityCheck(1.0 / ratio); } - fCheckBlockIndex = gArgs.GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); - fCheckpointsEnabled = gArgs.GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED); + fCheckBlockIndex = args.GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); + fCheckpointsEnabled = args.GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED); - hashAssumeValid = uint256S(gArgs.GetArg("-assumevalid", chainparams.GetConsensus().defaultAssumeValid.GetHex())); + hashAssumeValid = uint256S(args.GetArg("-assumevalid", chainparams.GetConsensus().defaultAssumeValid.GetHex())); if (!hashAssumeValid.IsNull()) LogPrintf("Assuming ancestors of block %s have valid signatures.\n", hashAssumeValid.GetHex()); else LogPrintf("Validating signatures for all blocks.\n"); - if (gArgs.IsArgSet("-minimumchainwork")) { - const std::string minChainWorkStr = gArgs.GetArg("-minimumchainwork", ""); + if (args.IsArgSet("-minimumchainwork")) { + const std::string minChainWorkStr = args.GetArg("-minimumchainwork", ""); if (!IsHexNumber(minChainWorkStr)) { return InitError(strprintf(Untranslated("Invalid non-hex (%s) minimum chain work value specified"), minChainWorkStr)); } @@ -1096,22 +1083,21 @@ bool AppInitParameterInteraction() } // mempool limits - int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; - int64_t nMempoolSizeMin = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40; + int64_t nMempoolSizeMax = args.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + int64_t nMempoolSizeMin = args.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) * 1000 * 40; if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin) return InitError(strprintf(_("-maxmempool must be at least %d MB"), std::ceil(nMempoolSizeMin / 1000000.0))); // incremental relay fee sets the minimum feerate increase necessary for BIP 125 replacement in the mempool // and the amount the mempool min fee increases above the feerate of txs evicted due to mempool limiting. - if (gArgs.IsArgSet("-incrementalrelayfee")) - { + if (args.IsArgSet("-incrementalrelayfee")) { CAmount n = 0; - if (!ParseMoney(gArgs.GetArg("-incrementalrelayfee", ""), n)) - return InitError(AmountErrMsg("incrementalrelayfee", gArgs.GetArg("-incrementalrelayfee", ""))); + if (!ParseMoney(args.GetArg("-incrementalrelayfee", ""), n)) + return InitError(AmountErrMsg("incrementalrelayfee", args.GetArg("-incrementalrelayfee", ""))); incrementalRelayFee = CFeeRate(n); } // block pruning; get the amount of disk space (in MiB) to allot for block & undo files - int64_t nPruneArg = gArgs.GetArg("-prune", 0); + int64_t nPruneArg = args.GetArg("-prune", 0); if (nPruneArg < 0) { return InitError(_("Prune cannot be configured with a negative value.")); } @@ -1128,20 +1114,20 @@ bool AppInitParameterInteraction() fPruneMode = true; } - nConnectTimeout = gArgs.GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); + nConnectTimeout = args.GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); if (nConnectTimeout <= 0) { nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; } - peer_connect_timeout = gArgs.GetArg("-peertimeout", DEFAULT_PEER_CONNECT_TIMEOUT); + peer_connect_timeout = args.GetArg("-peertimeout", DEFAULT_PEER_CONNECT_TIMEOUT); if (peer_connect_timeout <= 0) { return InitError(Untranslated("peertimeout cannot be configured with a negative value.")); } - if (gArgs.IsArgSet("-minrelaytxfee")) { + if (args.IsArgSet("-minrelaytxfee")) { CAmount n = 0; - if (!ParseMoney(gArgs.GetArg("-minrelaytxfee", ""), n)) { - return InitError(AmountErrMsg("minrelaytxfee", gArgs.GetArg("-minrelaytxfee", ""))); + if (!ParseMoney(args.GetArg("-minrelaytxfee", ""), n)) { + return InitError(AmountErrMsg("minrelaytxfee", args.GetArg("-minrelaytxfee", ""))); } // High fee check is done afterward in CWallet::CreateWalletFromFile() ::minRelayTxFee = CFeeRate(n); @@ -1153,48 +1139,46 @@ bool AppInitParameterInteraction() // Sanity check argument for min fee for including tx in block // TODO: Harmonize which arguments need sanity checking and where that happens - if (gArgs.IsArgSet("-blockmintxfee")) - { + if (args.IsArgSet("-blockmintxfee")) { CAmount n = 0; - if (!ParseMoney(gArgs.GetArg("-blockmintxfee", ""), n)) - return InitError(AmountErrMsg("blockmintxfee", gArgs.GetArg("-blockmintxfee", ""))); + if (!ParseMoney(args.GetArg("-blockmintxfee", ""), n)) + return InitError(AmountErrMsg("blockmintxfee", args.GetArg("-blockmintxfee", ""))); } // Feerate used to define dust. Shouldn't be changed lightly as old // implementations may inadvertently create non-standard transactions - if (gArgs.IsArgSet("-dustrelayfee")) - { + if (args.IsArgSet("-dustrelayfee")) { CAmount n = 0; - if (!ParseMoney(gArgs.GetArg("-dustrelayfee", ""), n)) - return InitError(AmountErrMsg("dustrelayfee", gArgs.GetArg("-dustrelayfee", ""))); + if (!ParseMoney(args.GetArg("-dustrelayfee", ""), n)) + return InitError(AmountErrMsg("dustrelayfee", args.GetArg("-dustrelayfee", ""))); dustRelayFee = CFeeRate(n); } - fRequireStandard = !gArgs.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard()); + fRequireStandard = !args.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard()); if (!chainparams.IsTestChain() && !fRequireStandard) { return InitError(strprintf(Untranslated("acceptnonstdtxn is not currently supported for %s chain"), chainparams.NetworkIDString())); } - nBytesPerSigOp = gArgs.GetArg("-bytespersigop", nBytesPerSigOp); + nBytesPerSigOp = args.GetArg("-bytespersigop", nBytesPerSigOp); if (!g_wallet_init_interface.ParameterInteraction()) return false; - fIsBareMultisigStd = gArgs.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); - fAcceptDatacarrier = gArgs.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER); - nMaxDatacarrierBytes = gArgs.GetArg("-datacarriersize", nMaxDatacarrierBytes); + fIsBareMultisigStd = args.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); + fAcceptDatacarrier = args.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER); + nMaxDatacarrierBytes = args.GetArg("-datacarriersize", nMaxDatacarrierBytes); // Option to startup with mocktime set (used for regression testing): - SetMockTime(gArgs.GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op + SetMockTime(args.GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op - if (gArgs.GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) + if (args.GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM); - if (gArgs.GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) < 0) + if (args.GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) < 0) return InitError(Untranslated("rpcserialversion must be non-negative.")); - if (gArgs.GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1) + if (args.GetArg("-rpcserialversion", DEFAULT_RPC_SERIALIZE_VERSION) > 1) return InitError(Untranslated("Unknown rpcserialversion requested.")); - nMaxTipAge = gArgs.GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); + nMaxTipAge = args.GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); return true; } @@ -1247,14 +1231,15 @@ bool AppInitLockDataDirectory() bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) { + const ArgsManager& args = *Assert(node.args); const CChainParams& chainparams = Params(); // ********************************************************* Step 4a: application initialization - if (!CreatePidFile()) { + if (!CreatePidFile(args)) { // Detailed error printed inside CreatePidFile(). return false; } if (LogInstance().m_print_to_file) { - if (gArgs.GetBoolArg("-shrinkdebugfile", LogInstance().DefaultShrinkDebugFile())) { + if (args.GetBoolArg("-shrinkdebugfile", LogInstance().DefaultShrinkDebugFile())) { // Do this first since it both loads a bunch of debug.log into memory, // and because this needs to happen before any other debug.log printing LogInstance().ShrinkDebugFile(); @@ -1271,10 +1256,10 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA LogPrintf("Using data directory %s\n", GetDataDir().string()); // Only log conf file usage message if conf file actually exists. - fs::path config_file_path = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME)); + fs::path config_file_path = GetConfigFile(args.GetArg("-conf", BITCOIN_CONF_FILENAME)); if (fs::exists(config_file_path)) { LogPrintf("Config file: %s\n", config_file_path.string()); - } else if (gArgs.IsArgSet("-conf")) { + } else if (args.IsArgSet("-conf")) { // Warn if no conf file exists at path provided by user InitWarning(strprintf(_("The specified config file %s does not exist\n"), config_file_path.string())); } else { @@ -1283,23 +1268,23 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA } // Log the config arguments to debug.log - gArgs.LogArgs(); + args.LogArgs(); LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD); // Warn about relative -datadir path. - if (gArgs.IsArgSet("-datadir") && !fs::path(gArgs.GetArg("-datadir", "")).is_absolute()) { + if (args.IsArgSet("-datadir") && !fs::path(args.GetArg("-datadir", "")).is_absolute()) { LogPrintf("Warning: relative datadir option '%s' specified, which will be interpreted relative to the " /* Continued */ "current working directory '%s'. This is fragile, because if bitcoin is started in the future " "from a different location, it will be unable to locate the current data files. There could " "also be data loss if bitcoin is started while in a temporary directory.\n", - gArgs.GetArg("-datadir", ""), fs::current_path().string()); + args.GetArg("-datadir", ""), fs::current_path().string()); } InitSignatureCache(); InitScriptExecutionCache(); - int script_threads = gArgs.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS); + int script_threads = args.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS); if (script_threads <= 0) { // -par=0 means autodetect (number of cores - 1 script threads) // -par=-n means "leave n cores free" (number of cores - n - 1 script threads) @@ -1355,8 +1340,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA * that the server is there and will be ready later). Warmup mode will * be disabled when initialisation is finished. */ - if (gArgs.GetBoolArg("-server", false)) - { + if (args.GetBoolArg("-server", false)) { uiInterface.InitMessage_connect(SetRPCWarmupStatus); if (!AppInitServers(context, node)) return InitError(_("Unable to start HTTP server. See debug log for details.")); @@ -1376,9 +1360,9 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA // need to reindex later. assert(!node.banman); - node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", &uiInterface, gArgs.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME)); + node.banman = MakeUnique<BanMan>(GetDataDir() / "banlist.dat", &uiInterface, args.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME)); assert(!node.connman); - node.connman = MakeUnique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()), gArgs.GetBoolArg("-networkactive", true)); + node.connman = MakeUnique<CConnman>(GetRand(std::numeric_limits<uint64_t>::max()), GetRand(std::numeric_limits<uint64_t>::max()), args.GetBoolArg("-networkactive", true)); // Make mempool generally available in the node context. For example the connection manager, wallet, or RPC threads, // which are all started after this, may use it from the node context. assert(!node.mempool); @@ -1392,7 +1376,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA // sanitize comments per BIP-0014, format user agent and check total size std::vector<std::string> uacomments; - for (const std::string& cmt : gArgs.GetArgs("-uacomment")) { + for (const std::string& cmt : args.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); @@ -1403,9 +1387,9 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA strSubVersion.size(), MAX_SUBVERSION_LENGTH)); } - if (gArgs.IsArgSet("-onlynet")) { + if (args.IsArgSet("-onlynet")) { std::set<enum Network> nets; - for (const std::string& snet : gArgs.GetArgs("-onlynet")) { + for (const std::string& snet : args.GetArgs("-onlynet")) { enum Network net = ParseNetwork(snet); if (net == NET_UNROUTABLE) return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet)); @@ -1419,12 +1403,12 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA } // Check for host lookup allowed before parsing any network related parameters - fNameLookup = gArgs.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); + fNameLookup = args.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP); - bool proxyRandomize = gArgs.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE); + bool proxyRandomize = args.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE); // -proxy sets a proxy for all outgoing network traffic // -noproxy (or -proxy=0) as well as the empty string can be used to not set a proxy, this is the default - std::string proxyArg = gArgs.GetArg("-proxy", ""); + std::string proxyArg = args.GetArg("-proxy", ""); SetReachable(NET_ONION, false); if (proxyArg != "" && proxyArg != "0") { CService proxyAddr; @@ -1446,7 +1430,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA // -onion can be used to set only a proxy for .onion, or override normal proxy for .onion addresses // -noonion (or -onion=0) disables connecting to .onion entirely // An empty string is used to not override the onion proxy (in which case it defaults to -proxy set above, or none) - std::string onionArg = gArgs.GetArg("-onion", ""); + std::string onionArg = args.GetArg("-onion", ""); if (onionArg != "") { if (onionArg == "0") { // Handle -noonion/-onion=0 SetReachable(NET_ONION, false); @@ -1464,11 +1448,11 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA } // see Step 2: parameter interactions for more information about these - fListen = gArgs.GetBoolArg("-listen", DEFAULT_LISTEN); - fDiscover = gArgs.GetBoolArg("-discover", true); - g_relay_txes = !gArgs.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); + fListen = args.GetBoolArg("-listen", DEFAULT_LISTEN); + fDiscover = args.GetBoolArg("-discover", true); + g_relay_txes = !args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY); - for (const std::string& strAddr : gArgs.GetArgs("-externalip")) { + for (const std::string& strAddr : args.GetArgs("-externalip")) { CService addrLocal; if (Lookup(strAddr, addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) AddLocal(addrLocal, LOCAL_MANUAL); @@ -1477,8 +1461,8 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA } // Read asmap file if configured - if (gArgs.IsArgSet("-asmap")) { - fs::path asmap_path = fs::path(gArgs.GetArg("-asmap", "")); + if (args.IsArgSet("-asmap")) { + fs::path asmap_path = fs::path(args.GetArg("-asmap", "")); if (asmap_path.empty()) { asmap_path = DEFAULT_ASMAP_FILENAME; } @@ -1511,22 +1495,22 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA uint64_t nMaxOutboundLimit = 0; //unlimited unless -maxuploadtarget is set uint64_t nMaxOutboundTimeframe = MAX_UPLOAD_TIMEFRAME; - if (gArgs.IsArgSet("-maxuploadtarget")) { - nMaxOutboundLimit = gArgs.GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET)*1024*1024; + if (args.IsArgSet("-maxuploadtarget")) { + nMaxOutboundLimit = args.GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET) * 1024 * 1024; } // ********************************************************* Step 7: load block chain - fReindex = gArgs.GetBoolArg("-reindex", false); - bool fReindexChainState = gArgs.GetBoolArg("-reindex-chainstate", false); + fReindex = args.GetBoolArg("-reindex", false); + bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false); // cache size calculations - int64_t nTotalCache = (gArgs.GetArg("-dbcache", nDefaultDbCache) << 20); + int64_t nTotalCache = (args.GetArg("-dbcache", nDefaultDbCache) << 20); nTotalCache = std::max(nTotalCache, nMinDbCache << 20); // total cache cannot be less than nMinDbCache nTotalCache = std::min(nTotalCache, nMaxDbCache << 20); // total cache cannot be greater than nMaxDbcache int64_t nBlockTreeDBCache = std::min(nTotalCache / 8, nMaxBlockDBCache << 20); nTotalCache -= nBlockTreeDBCache; - int64_t nTxIndexCache = std::min(nTotalCache / 8, gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxTxIndexCache << 20 : 0); + int64_t nTxIndexCache = std::min(nTotalCache / 8, args.GetBoolArg("-txindex", DEFAULT_TXINDEX) ? nMaxTxIndexCache << 20 : 0); nTotalCache -= nTxIndexCache; int64_t filter_index_cache = 0; if (!g_enabled_filter_types.empty()) { @@ -1539,10 +1523,10 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA nCoinDBCache = std::min(nCoinDBCache, nMaxCoinsDBCache << 20); // cap total coins db cache nTotalCache -= nCoinDBCache; int64_t nCoinCacheUsage = nTotalCache; // the rest goes to in-memory cache - int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; + int64_t nMempoolSizeMax = args.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; LogPrintf("Cache configuration:\n"); LogPrintf("* Using %.1f MiB for block index database\n", nBlockTreeDBCache * (1.0 / 1024 / 1024)); - if (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { + if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { LogPrintf("* Using %.1f MiB for transaction index database\n", nTxIndexCache * (1.0 / 1024 / 1024)); } for (BlockFilterType filter_type : g_enabled_filter_types) { @@ -1707,7 +1691,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA for (CChainState* chainstate : chainman.GetAll()) { if (!is_coinsview_empty(chainstate)) { uiInterface.InitMessage(_("Verifying blocks...").translated); - if (fHavePruned && gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { + if (fHavePruned && args.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks\n", MIN_BLOCKS_TO_KEEP); } @@ -1725,10 +1709,10 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA // Only verify the DB of the active chainstate. This is fixed in later // work when we allow VerifyDB to be parameterized by chainstate. if (&::ChainstateActive() == chainstate && - !CVerifyDB().VerifyDB( + !CVerifyDB().VerifyDB( chainparams, &chainstate->CoinsDB(), - gArgs.GetArg("-checklevel", DEFAULT_CHECKLEVEL), - gArgs.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { + args.GetArg("-checklevel", DEFAULT_CHECKLEVEL), + args.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS))) { strLoadError = _("Corrupted block database detected"); failed_verification = true; break; @@ -1784,7 +1768,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA fFeeEstimatesInitialized = true; // ********************************************************* Step 8: start indexers - if (gArgs.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { + if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) { g_txindex = MakeUnique<TxIndex>(nTxIndexCache, false, fReindex); g_txindex->Start(); } @@ -1844,16 +1828,31 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA } #if HAVE_SYSTEM - if (gArgs.IsArgSet("-blocknotify")) + if (args.IsArgSet("-blocknotify")) { + const std::string block_notify = args.GetArg("-blocknotify", ""); + const auto BlockNotifyCallback = [block_notify](SynchronizationState sync_state, const CBlockIndex* pBlockIndex) { + if (sync_state != SynchronizationState::POST_INIT || !pBlockIndex) + return; + + std::string strCmd = block_notify; + if (!strCmd.empty()) { + boost::replace_all(strCmd, "%s", pBlockIndex->GetBlockHash().GetHex()); + std::thread t(runCommand, strCmd); + t.detach(); // thread runs free + } + }; uiInterface.NotifyBlockTip_connect(BlockNotifyCallback); + } #endif std::vector<fs::path> vImportFiles; - for (const std::string& strFile : gArgs.GetArgs("-loadblock")) { + for (const std::string& strFile : args.GetArgs("-loadblock")) { vImportFiles.push_back(strFile); } - g_load_block = std::thread(&TraceThread<std::function<void()>>, "loadblk", [=, &chainman]{ ThreadImport(chainman, vImportFiles); }); + g_load_block = std::thread(&TraceThread<std::function<void()>>, "loadblk", [=, &chainman, &args] { + ThreadImport(chainman, vImportFiles, args); + }); // Wait for genesis block to be processed { @@ -1892,13 +1891,13 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA } LogPrintf("nBestHeight = %d\n", chain_active_height); - if (gArgs.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) + if (args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) StartTorControl(); Discover(); // Map ports with UPnP - if (gArgs.GetBoolArg("-upnp", DEFAULT_UPNP)) { + if (args.GetBoolArg("-upnp", DEFAULT_UPNP)) { StartMapPort(); } @@ -1913,41 +1912,41 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA connOptions.uiInterface = &uiInterface; connOptions.m_banman = node.banman.get(); connOptions.m_msgproc = node.peer_logic.get(); - connOptions.nSendBufferMaxSize = 1000*gArgs.GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER); - connOptions.nReceiveFloodSize = 1000*gArgs.GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER); - connOptions.m_added_nodes = gArgs.GetArgs("-addnode"); + connOptions.nSendBufferMaxSize = 1000 * args.GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER); + connOptions.nReceiveFloodSize = 1000 * args.GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER); + connOptions.m_added_nodes = args.GetArgs("-addnode"); connOptions.nMaxOutboundTimeframe = nMaxOutboundTimeframe; connOptions.nMaxOutboundLimit = nMaxOutboundLimit; connOptions.m_peer_connect_timeout = peer_connect_timeout; - for (const std::string& strBind : gArgs.GetArgs("-bind")) { + for (const std::string& strBind : args.GetArgs("-bind")) { CService addrBind; if (!Lookup(strBind, addrBind, GetListenPort(), false)) { return InitError(ResolveErrMsg("bind", strBind)); } connOptions.vBinds.push_back(addrBind); } - for (const std::string& strBind : gArgs.GetArgs("-whitebind")) { + for (const std::string& strBind : args.GetArgs("-whitebind")) { NetWhitebindPermissions whitebind; bilingual_str error; if (!NetWhitebindPermissions::TryParse(strBind, whitebind, error)) return InitError(error); connOptions.vWhiteBinds.push_back(whitebind); } - for (const auto& net : gArgs.GetArgs("-whitelist")) { + for (const auto& net : args.GetArgs("-whitelist")) { NetWhitelistPermissions subnet; bilingual_str error; if (!NetWhitelistPermissions::TryParse(net, subnet, error)) return InitError(error); connOptions.vWhitelistedRange.push_back(subnet); } - connOptions.vSeedNodes = gArgs.GetArgs("-seednode"); + connOptions.vSeedNodes = args.GetArgs("-seednode"); // Initiate outbound connections unless connect=0 - connOptions.m_use_addrman_outgoing = !gArgs.IsArgSet("-connect"); + connOptions.m_use_addrman_outgoing = !args.IsArgSet("-connect"); if (!connOptions.m_use_addrman_outgoing) { - const auto connect = gArgs.GetArgs("-connect"); + const auto connect = args.GetArgs("-connect"); if (connect.size() != 1 || connect[0] != "0") { connOptions.m_specified_outgoing = connect; } diff --git a/src/init.h b/src/init.h index 20008ba5be..ce12a80dc7 100644 --- a/src/init.h +++ b/src/init.h @@ -8,8 +8,8 @@ #include <memory> #include <string> -#include <util/system.h> +class ArgsManager; struct NodeContext; namespace interfaces { struct BlockAndHeaderTipInfo; @@ -25,21 +25,21 @@ class Ref; void Interrupt(NodeContext& node); void Shutdown(NodeContext& node); //!Initialize the logging infrastructure -void InitLogging(); +void InitLogging(const ArgsManager& args); //!Parameter interaction: change current parameters depending on various rules -void InitParameterInteraction(); +void InitParameterInteraction(ArgsManager& args); /** Initialize bitcoin core: Basic context setup. * @note This can be done before daemonization. Do not call Shutdown() if this function fails. * @pre Parameters should be parsed and config file should be read. */ -bool AppInitBasicSetup(); +bool AppInitBasicSetup(ArgsManager& args); /** * Initialization: parameter interaction. * @note This can be done before daemonization. Do not call Shutdown() if this function fails. * @pre Parameters should be parsed and config file should be read, AppInitBasicSetup should have been called. */ -bool AppInitParameterInteraction(); +bool AppInitParameterInteraction(const ArgsManager& args); /** * Initialization sanity checks: ecc init, sanity checks, dir lock. * @note This can be done before daemonization. Do not call Shutdown() if this function fails. diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp index 21400d00f8..e1c3a460e9 100644 --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -71,13 +71,13 @@ public: uint64_t getAssumedBlockchainSize() override { return Params().AssumedBlockchainSize(); } uint64_t getAssumedChainStateSize() override { return Params().AssumedChainStateSize(); } std::string getNetwork() override { return Params().NetworkIDString(); } - void initLogging() override { InitLogging(); } - void initParameterInteraction() override { InitParameterInteraction(); } + void initLogging() override { InitLogging(gArgs); } + void initParameterInteraction() override { InitParameterInteraction(gArgs); } bilingual_str getWarnings() override { return GetWarnings(true); } uint32_t getLogCategories() override { return LogInstance().GetCategoryMask(); } bool baseInitialize() override { - return AppInitBasicSetup() && AppInitParameterInteraction() && AppInitSanityChecks() && + return AppInitBasicSetup(gArgs) && AppInitParameterInteraction(gArgs) && AppInitSanityChecks() && AppInitLockDataDirectory(); } bool appInitMain(interfaces::BlockAndHeaderTipInfo* tip_info) override diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 5ffa7e82eb..d9a00c2205 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -97,8 +97,8 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve SelectParams(chainName); SeedInsecureRand(); if (G_TEST_LOG_FUN) LogInstance().PushBackCallback(G_TEST_LOG_FUN); - InitLogging(); - AppInitParameterInteraction(); + InitLogging(*m_node.args); + AppInitParameterInteraction(*m_node.args); LogInstance().StartLogging(); SHA256AutoDetect(); ECC_Start(); |