From c8042a48f01aaf306e108683e40db4bfaf0bbcaa Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 29 Nov 2016 15:17:34 -0800 Subject: [PATCH 1/7] Remove arguments to ParseConfigFile --- src/bitcoin-cli.cpp | 2 +- src/bitcoind.cpp | 2 +- src/qt/bitcoin.cpp | 2 +- src/util.cpp | 10 ++++------ src/util.h | 2 +- 5 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 596cc8ead..cee9ae31b 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -99,7 +99,7 @@ static int AppInitRPC(int argc, char* argv[]) return EXIT_FAILURE; } try { - ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME), mapArgs, mapMultiArgs); + ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return EXIT_FAILURE; diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index ba3ccac61..3dd085628 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -104,7 +104,7 @@ bool AppInit(int argc, char* argv[]) } try { - ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME), mapArgs, mapMultiArgs); + ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)); } catch (const std::exception& e) { fprintf(stderr,"Error reading configuration file: %s\n", e.what()); return false; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index cfd0955a7..3ae54f311 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -608,7 +608,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } try { - ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME), mapArgs, mapMultiArgs); + ReadConfigFile(GetArg("-conf", BITCOIN_CONF_FILENAME)); } catch (const std::exception& e) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), QObject::tr("Error: Cannot parse configuration file: %1. Only use key=value syntax.").arg(e.what())); diff --git a/src/util.cpp b/src/util.cpp index 977f8993e..8b3e5f93f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -526,9 +526,7 @@ boost::filesystem::path GetConfigFile(const std::string& confPath) return pathConfigFile; } -void ReadConfigFile(const std::string& confPath, - map& mapSettingsRet, - map >& mapMultiSettingsRet) +void ReadConfigFile(const std::string& confPath) { boost::filesystem::ifstream streamConfig(GetConfigFile(confPath)); if (!streamConfig.good()) @@ -543,9 +541,9 @@ void ReadConfigFile(const std::string& confPath, string strKey = string("-") + it->string_key; string strValue = it->value[0]; InterpretNegativeSetting(strKey, strValue); - if (mapSettingsRet.count(strKey) == 0) - mapSettingsRet[strKey] = strValue; - mapMultiSettingsRet[strKey].push_back(strValue); + if (mapArgs.count(strKey) == 0) + mapArgs[strKey] = strValue; + mapMultiArgs[strKey].push_back(strValue); } // If datadir is changed in .conf file: ClearDatadirCache(); diff --git a/src/util.h b/src/util.h index 3ec38a7c7..4fb09046b 100644 --- a/src/util.h +++ b/src/util.h @@ -106,7 +106,7 @@ boost::filesystem::path GetConfigFile(const std::string& confPath); boost::filesystem::path GetPidFile(); void CreatePidFile(const boost::filesystem::path &path, pid_t pid); #endif -void ReadConfigFile(const std::string& confPath, std::map& mapSettingsRet, std::map >& mapMultiSettingsRet); +void ReadConfigFile(const std::string& confPath); #ifdef WIN32 boost::filesystem::path GetSpecialFolderPath(int nFolder, bool fCreate = true); #endif From 2b5f085ad11b4b354f48d77e66698fa386c8abbd Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 29 Nov 2016 16:50:49 -0800 Subject: [PATCH 2/7] Fix non-const mapMultiArgs[] access after init. Swap mapMultiArgs for a const-reference to a _mapMultiArgs which is only accessed in util.cpp --- src/httprpc.cpp | 2 +- src/httpserver.cpp | 6 ++--- src/init.cpp | 60 +++++++++++++++++++++++------------------ src/net.cpp | 9 ++++--- src/test/util_tests.cpp | 2 +- src/util.cpp | 18 ++++++++----- src/util.h | 2 +- 7 files changed, 56 insertions(+), 43 deletions(-) diff --git a/src/httprpc.cpp b/src/httprpc.cpp index e35acb6cd..049a3f19a 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -95,7 +95,7 @@ static bool multiUserAuthorized(std::string strUserPass) if (mapMultiArgs.count("-rpcauth") > 0) { //Search for multi-user login/pass "rpcauth" from config - BOOST_FOREACH(std::string strRPCAuth, mapMultiArgs["-rpcauth"]) + BOOST_FOREACH(std::string strRPCAuth, mapMultiArgs.at("-rpcauth")) { std::vector vFields; boost::split(vFields, strRPCAuth, boost::is_any_of(":$")); diff --git a/src/httpserver.cpp b/src/httpserver.cpp index b296b2850..2d25168a1 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -204,7 +204,7 @@ static bool InitHTTPAllowList() rpc_allow_subnets.push_back(CSubNet(localv4, 8)); // always allow IPv4 local subnet rpc_allow_subnets.push_back(CSubNet(localv6)); // always allow IPv6 localhost if (mapMultiArgs.count("-rpcallowip")) { - const std::vector& vAllow = mapMultiArgs["-rpcallowip"]; + const std::vector& vAllow = mapMultiArgs.at("-rpcallowip"); for (std::string strAllow : vAllow) { CSubNet subnet; LookupSubNet(strAllow.c_str(), subnet); @@ -328,8 +328,8 @@ static bool HTTPBindAddresses(struct evhttp* http) if (mapArgs.count("-rpcbind")) { LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n"); } - } else if (mapArgs.count("-rpcbind")) { // Specific bind address - const std::vector& vbind = mapMultiArgs["-rpcbind"]; + } else if (mapMultiArgs.count("-rpcbind")) { // Specific bind address + const std::vector& vbind = mapMultiArgs.at("-rpcbind"); for (std::vector::const_iterator i = vbind.begin(); i != vbind.end(); ++i) { int port = defaultPort; std::string host; diff --git a/src/init.cpp b/src/init.cpp index e642729a9..ecfd33fb6 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -717,7 +717,7 @@ void InitParameterInteraction() LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__); } - if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) { + if (mapMultiArgs.count("-connect") && mapMultiArgs.at("-connect").size() > 0) { // when only connecting to trusted nodes, do not seed via DNS, or listen by default if (SoftSetBoolArg("-dnsseed", false)) LogPrintf("%s: parameter interaction: -connect set -> setting -dnsseed=0\n", __func__); @@ -880,11 +880,13 @@ bool AppInitParameterInteraction() // ********************************************************* Step 3: parameter-to-internal-flags - fDebug = !mapMultiArgs["-debug"].empty(); + fDebug = mapMultiArgs.count("-debug"); // Special-case: if -debug=0/-nodebug is set, turn off debugging messages - const vector& categories = mapMultiArgs["-debug"]; - if (GetBoolArg("-nodebug", false) || find(categories.begin(), categories.end(), string("0")) != categories.end()) - fDebug = false; + if (fDebug) { + const vector& categories = mapMultiArgs.at("-debug"); + if (GetBoolArg("-nodebug", false) || find(categories.begin(), categories.end(), string("0")) != categories.end()) + fDebug = false; + } // Check for -debugnet if (GetBoolArg("-debugnet", false)) @@ -1003,12 +1005,12 @@ bool AppInitParameterInteraction() fEnableReplacement = (std::find(vstrReplacementModes.begin(), vstrReplacementModes.end(), "fee") != vstrReplacementModes.end()); } - if (!mapMultiArgs["-bip9params"].empty()) { + if (mapMultiArgs.count("-bip9params")) { // Allow overriding BIP9 parameters for testing if (!chainparams.MineBlocksOnDemand()) { return InitError("BIP9 parameters may only be overridden on regtest."); } - const vector& deployments = mapMultiArgs["-bip9params"]; + const vector& deployments = mapMultiArgs.at("-bip9params"); for (auto i : deployments) { std::vector vDeploymentParams; boost::split(vDeploymentParams, i, boost::is_any_of(":")); @@ -1154,11 +1156,13 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // sanitize comments per BIP-0014, format user agent and check total size std::vector 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)); + if (mapMultiArgs.count("-uacomment")) { + BOOST_FOREACH(string cmt, mapMultiArgs.at("-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) { @@ -1166,9 +1170,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) strSubVersion.size(), MAX_SUBVERSION_LENGTH)); } - if (mapArgs.count("-onlynet")) { + if (mapMultiArgs.count("-onlynet")) { std::set nets; - BOOST_FOREACH(const std::string& snet, mapMultiArgs["-onlynet"]) { + BOOST_FOREACH(const std::string& snet, mapMultiArgs.at("-onlynet")) { enum Network net = ParseNetwork(snet); if (net == NET_UNROUTABLE) return InitError(strprintf(_("Unknown network specified in -onlynet: '%s'"), snet)); @@ -1181,8 +1185,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } } - if (mapArgs.count("-whitelist")) { - BOOST_FOREACH(const std::string& net, mapMultiArgs["-whitelist"]) { + if (mapMultiArgs.count("-whitelist")) { + BOOST_FOREACH(const std::string& net, mapMultiArgs.at("-whitelist")) { CSubNet subnet; LookupSubNet(net.c_str(), subnet); if (!subnet.IsValid()) @@ -1234,14 +1238,16 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) if (fListen) { bool fBound = false; - if (mapArgs.count("-bind") || mapArgs.count("-whitebind")) { - BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-bind"]) { + if (mapMultiArgs.count("-bind")) { + BOOST_FOREACH(const std::string& strBind, mapMultiArgs.at("-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)); } - BOOST_FOREACH(const std::string& strBind, mapMultiArgs["-whitebind"]) { + } + if (mapMultiArgs.count("-whitebind")) { + BOOST_FOREACH(const std::string& strBind, mapMultiArgs.at("-whitebind")) { CService addrBind; if (!Lookup(strBind.c_str(), addrBind, 0, false)) return InitError(ResolveErrMsg("whitebind", strBind)); @@ -1250,7 +1256,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fBound |= Bind(connman, addrBind, (BF_EXPLICIT | BF_REPORT_ERROR | BF_WHITELIST)); } } - else { + if (!mapMultiArgs.count("-bind") && !mapMultiArgs.count("-whitebind")) { struct in_addr inaddr_any; inaddr_any.s_addr = INADDR_ANY; fBound |= Bind(connman, CService(in6addr_any, GetListenPort()), BF_NONE); @@ -1260,8 +1266,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) return InitError(_("Failed to listen on any port. Use -listen=0 if you want this.")); } - if (mapArgs.count("-externalip")) { - BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-externalip"]) { + if (mapMultiArgs.count("-externalip")) { + BOOST_FOREACH(const std::string& strAddr, mapMultiArgs.at("-externalip")) { CService addrLocal; if (Lookup(strAddr.c_str(), addrLocal, GetListenPort(), fNameLookup) && addrLocal.IsValid()) AddLocal(addrLocal, LOCAL_MANUAL); @@ -1270,8 +1276,10 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } } - BOOST_FOREACH(const std::string& strDest, mapMultiArgs["-seednode"]) - connman.AddOneShot(strDest); + if (mapMultiArgs.count("-seednode")) { + BOOST_FOREACH(const std::string& strDest, mapMultiArgs.at("-seednode")) + connman.AddOneShot(strDest); + } #if ENABLE_ZMQ pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs); @@ -1519,9 +1527,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); std::vector vImportFiles; - if (mapArgs.count("-loadblock")) + if (mapMultiArgs.count("-loadblock")) { - BOOST_FOREACH(const std::string& strFile, mapMultiArgs["-loadblock"]) + BOOST_FOREACH(const std::string& strFile, mapMultiArgs.at("-loadblock")) vImportFiles.push_back(strFile); } diff --git a/src/net.cpp b/src/net.cpp index 27b200b3f..3ac962354 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1569,12 +1569,12 @@ void CConnman::ProcessOneShot() void CConnman::ThreadOpenConnections() { // Connect to specific addresses - if (mapArgs.count("-connect") && mapMultiArgs["-connect"].size() > 0) + if (mapMultiArgs.count("-connect") && mapMultiArgs.at("-connect").size() > 0) { for (int64_t nLoop = 0;; nLoop++) { ProcessOneShot(); - BOOST_FOREACH(const std::string& strAddr, mapMultiArgs["-connect"]) + BOOST_FOREACH(const std::string& strAddr, mapMultiArgs.at("-connect")) { CAddress addr(CService(), NODE_NONE); OpenNetworkConnection(addr, false, NULL, strAddr.c_str()); @@ -1765,7 +1765,8 @@ void CConnman::ThreadOpenAddedConnections() { { LOCK(cs_vAddedNodes); - vAddedNodes = mapMultiArgs["-addnode"]; + if (mapMultiArgs.count("-addnode")) + vAddedNodes = mapMultiArgs.at("-addnode"); } for (unsigned int i = 0; true; i++) @@ -2157,7 +2158,7 @@ bool CConnman::Start(boost::thread_group& threadGroup, CScheduler& scheduler, st threadGroup.create_thread(boost::bind(&TraceThread >, "addcon", boost::function(boost::bind(&CConnman::ThreadOpenAddedConnections, this)))); // Initiate outbound connections unless connect=0 - if (!mapArgs.count("-connect") || mapMultiArgs["-connect"].size() != 1 || mapMultiArgs["-connect"][0] != "0") + if (!mapMultiArgs.count("-connect") || mapMultiArgs.at("-connect").size() != 1 || mapMultiArgs.at("-connect")[0] != "0") threadGroup.create_thread(boost::bind(&TraceThread >, "opencon", boost::function(boost::bind(&CConnman::ThreadOpenConnections, this)))); // Process messages diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index bad72ffc0..493d58641 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(util_ParseParameters) && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d")); BOOST_CHECK(mapArgs["-a"] == "" && mapArgs["-ccc"] == "multiple"); - BOOST_CHECK(mapMultiArgs["-ccc"].size() == 2); + BOOST_CHECK(mapMultiArgs.at("-ccc").size() == 2); } BOOST_AUTO_TEST_CASE(util_GetArg) diff --git a/src/util.cpp b/src/util.cpp index 8b3e5f93f..6625ac932 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -103,7 +103,8 @@ const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf"; const char * const BITCOIN_PID_FILENAME = "bitcoind.pid"; map mapArgs; -map > mapMultiArgs; +static map > _mapMultiArgs; +const map >& mapMultiArgs = _mapMultiArgs; bool fDebug = false; bool fPrintToConsole = false; bool fPrintToDebugLog = true; @@ -238,9 +239,12 @@ bool LogAcceptCategory(const char* category) static boost::thread_specific_ptr > ptrCategory; if (ptrCategory.get() == NULL) { - const vector& categories = mapMultiArgs["-debug"]; - ptrCategory.reset(new set(categories.begin(), categories.end())); - // thread_specific_ptr automatically deletes the set when the thread ends. + if (mapMultiArgs.count("-debug")) { + const vector& categories = mapMultiArgs.at("-debug"); + ptrCategory.reset(new set(categories.begin(), categories.end())); + // thread_specific_ptr automatically deletes the set when the thread ends. + } else + ptrCategory.reset(new set()); } const set& setCategories = *ptrCategory.get(); @@ -343,7 +347,7 @@ static void InterpretNegativeSetting(std::string& strKey, std::string& strValue) void ParseParameters(int argc, const char* const argv[]) { mapArgs.clear(); - mapMultiArgs.clear(); + _mapMultiArgs.clear(); for (int i = 1; i < argc; i++) { @@ -371,7 +375,7 @@ void ParseParameters(int argc, const char* const argv[]) InterpretNegativeSetting(str, strValue); mapArgs[str] = strValue; - mapMultiArgs[str].push_back(strValue); + _mapMultiArgs[str].push_back(strValue); } } @@ -543,7 +547,7 @@ void ReadConfigFile(const std::string& confPath) InterpretNegativeSetting(strKey, strValue); if (mapArgs.count(strKey) == 0) mapArgs[strKey] = strValue; - mapMultiArgs[strKey].push_back(strValue); + _mapMultiArgs[strKey].push_back(strValue); } // If datadir is changed in .conf file: ClearDatadirCache(); diff --git a/src/util.h b/src/util.h index 4fb09046b..5d1d80d2d 100644 --- a/src/util.h +++ b/src/util.h @@ -42,7 +42,7 @@ public: }; extern std::map mapArgs; -extern std::map > mapMultiArgs; +extern const std::map >& mapMultiArgs; extern bool fDebug; extern bool fPrintToConsole; extern bool fPrintToDebugLog; From 0cf86a6678413aa03e765a7133f048df4001ff4c Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 29 Nov 2016 17:51:30 -0800 Subject: [PATCH 3/7] Introduce (and use) an IsArgSet accessor method --- src/bitcoin-cli.cpp | 4 ++-- src/bitcoin-tx.cpp | 2 +- src/bitcoind.cpp | 4 ++-- src/httpserver.cpp | 4 ++-- src/init.cpp | 20 ++++++++++---------- src/miner.cpp | 4 ++-- src/net_processing.cpp | 2 +- src/qt/bitcoin.cpp | 6 +++--- src/test/util_tests.cpp | 4 ++-- src/util.cpp | 7 ++++++- src/util.h | 8 ++++++++ src/wallet/wallet.cpp | 10 +++++----- 12 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index cee9ae31b..a4360dcd1 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -76,9 +76,9 @@ static int AppInitRPC(int argc, char* argv[]) // Parameters // ParseParameters(argc, argv); - if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) { + if (argc<2 || IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help") || IsArgSet("-version")) { std::string strUsage = strprintf(_("%s RPC client version"), _(PACKAGE_NAME)) + " " + FormatFullVersion() + "\n"; - if (!mapArgs.count("-version")) { + if (!IsArgSet("-version")) { strUsage += "\n" + _("Usage:") + "\n" + " bitcoin-cli [options] [params] " + strprintf(_("Send command to %s"), _(PACKAGE_NAME)) + "\n" + " bitcoin-cli [options] help " + _("List commands") + "\n" + diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 816687a45..d46f33045 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -51,7 +51,7 @@ static int AppInitRawTx(int argc, char* argv[]) fCreateBlank = GetBoolArg("-create", false); - if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help")) + if (argc<2 || IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help")) { // First part of help message is specific to this utility std::string strUsage = strprintf(_("%s bitcoin-tx utility version"), _(PACKAGE_NAME)) + " " + FormatFullVersion() + "\n\n" + diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 3dd085628..ee27f4122 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -75,11 +75,11 @@ bool AppInit(int argc, char* argv[]) ParseParameters(argc, argv); // Process help and version before taking care about datadir - if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) + if (IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help") || IsArgSet("-version")) { std::string strUsage = strprintf(_("%s Daemon"), _(PACKAGE_NAME)) + " " + _("version") + " " + FormatFullVersion() + "\n"; - if (mapArgs.count("-version")) + if (IsArgSet("-version")) { strUsage += FormatParagraph(LicenseInfo()); } diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 2d25168a1..257390074 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -322,10 +322,10 @@ static bool HTTPBindAddresses(struct evhttp* http) std::vector > endpoints; // Determine what addresses to bind to - if (!mapArgs.count("-rpcallowip")) { // Default to loopback if not allowing external IPs + if (!IsArgSet("-rpcallowip")) { // Default to loopback if not allowing external IPs endpoints.push_back(std::make_pair("::1", defaultPort)); endpoints.push_back(std::make_pair("127.0.0.1", defaultPort)); - if (mapArgs.count("-rpcbind")) { + if (IsArgSet("-rpcbind")) { LogPrintf("WARNING: option -rpcbind was ignored because -rpcallowip was not specified, refusing to allow everyone to connect\n"); } } else if (mapMultiArgs.count("-rpcbind")) { // Specific bind address diff --git a/src/init.cpp b/src/init.cpp index ecfd33fb6..778d66fba 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -708,11 +708,11 @@ void InitParameterInteraction() { // when specifying an explicit binding address, you want to listen on it // even when -connect or -proxy is specified - if (mapArgs.count("-bind")) { + if (IsArgSet("-bind")) { if (SoftSetBoolArg("-listen", true)) LogPrintf("%s: parameter interaction: -bind set -> setting -listen=1\n", __func__); } - if (mapArgs.count("-whitebind")) { + if (IsArgSet("-whitebind")) { if (SoftSetBoolArg("-listen", true)) LogPrintf("%s: parameter interaction: -whitebind set -> setting -listen=1\n", __func__); } @@ -725,7 +725,7 @@ void InitParameterInteraction() LogPrintf("%s: parameter interaction: -connect set -> setting -listen=0\n", __func__); } - if (mapArgs.count("-proxy")) { + if (IsArgSet("-proxy")) { // to protect privacy, do not listen by default if a default proxy server is specified if (SoftSetBoolArg("-listen", false)) LogPrintf("%s: parameter interaction: -proxy set -> setting -listen=0\n", __func__); @@ -748,7 +748,7 @@ void InitParameterInteraction() LogPrintf("%s: parameter interaction: -listen=0 -> setting -listenonion=0\n", __func__); } - if (mapArgs.count("-externalip")) { + if (IsArgSet("-externalip")) { // if an explicit public IP is specified, do not try to find others if (SoftSetBoolArg("-discover", false)) LogPrintf("%s: parameter interaction: -externalip set -> setting -discover=0\n", __func__); @@ -892,7 +892,7 @@ bool AppInitParameterInteraction() if (GetBoolArg("-debugnet", false)) InitWarning(_("Unsupported argument -debugnet ignored, use -debug=net.")); // Check for -socks - as this is a privacy risk to continue, exit here - if (mapArgs.count("-socks")) + if (IsArgSet("-socks")) return InitError(_("Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported.")); // Check for -tor - as this is a privacy risk to continue, exit here if (GetBoolArg("-tor", false)) @@ -904,7 +904,7 @@ bool AppInitParameterInteraction() if (GetBoolArg("-whitelistalwaysrelay", false)) InitWarning(_("Unsupported argument -whitelistalwaysrelay ignored, use -whitelistrelay and/or -whitelistforcerelay.")); - if (mapArgs.count("-blockminsize")) + if (IsArgSet("-blockminsize")) InitWarning("Unsupported argument -blockminsize ignored."); // Checkmempool and checkblockindex default to true in regtest mode @@ -959,7 +959,7 @@ bool AppInitParameterInteraction() // a transaction spammer can cheaply fill blocks using // 1-satoshi-fee transactions. It should be set above the real // cost to you of processing a transaction. - if (mapArgs.count("-minrelaytxfee")) + if (IsArgSet("-minrelaytxfee")) { CAmount n = 0; if (!ParseMoney(mapArgs["-minrelaytxfee"], n) || 0 == n) @@ -997,7 +997,7 @@ bool AppInitParameterInteraction() nMaxTipAge = GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE); fEnableReplacement = GetBoolArg("-mempoolreplacement", DEFAULT_ENABLE_REPLACEMENT); - if ((!fEnableReplacement) && mapArgs.count("-mempoolreplacement")) { + if ((!fEnableReplacement) && IsArgSet("-mempoolreplacement")) { // Minimal effort at forwards compatibility std::string strReplacementModeList = GetArg("-mempoolreplacement", ""); // default is impossible std::vector vstrReplacementModes; @@ -1291,7 +1291,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) uint64_t nMaxOutboundLimit = 0; //unlimited unless -maxuploadtarget is set uint64_t nMaxOutboundTimeframe = MAX_UPLOAD_TIMEFRAME; - if (mapArgs.count("-maxuploadtarget")) { + if (IsArgSet("-maxuploadtarget")) { nMaxOutboundLimit = GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET)*1024*1024; } @@ -1523,7 +1523,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fHaveGenesis = true; } - if (mapArgs.count("-blocknotify")) + if (IsArgSet("-blocknotify")) uiInterface.NotifyBlockTip.connect(BlockNotifyCallback); std::vector vImportFiles; diff --git a/src/miner.cpp b/src/miner.cpp index b48b9cee4..55231730f 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -84,12 +84,12 @@ BlockAssembler::BlockAssembler(const CChainParams& _chainparams) nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT; nBlockMaxSize = DEFAULT_BLOCK_MAX_SIZE; bool fWeightSet = false; - if (mapArgs.count("-blockmaxweight")) { + if (IsArgSet("-blockmaxweight")) { nBlockMaxWeight = GetArg("-blockmaxweight", DEFAULT_BLOCK_MAX_WEIGHT); nBlockMaxSize = MAX_BLOCK_SERIALIZED_SIZE; fWeightSet = true; } - if (mapArgs.count("-blockmaxsize")) { + if (IsArgSet("-blockmaxsize")) { nBlockMaxSize = GetArg("-blockmaxsize", DEFAULT_BLOCK_MAX_SIZE); if (!fWeightSet) { nBlockMaxWeight = nBlockMaxSize * WITNESS_SCALE_FACTOR; diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 87d367c2f..98872200d 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1060,7 +1060,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, unsigned int nMaxSendBufferSize = connman.GetSendBufferSize(); LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id); - if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) + if (IsArgSet("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) { LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n"); return true; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 3ae54f311..9d80a3800 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -587,9 +587,9 @@ int main(int argc, char *argv[]) // Show help message immediately after parsing command-line options (for "-lang") and setting locale, // but before showing splash screen. - if (mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) + if (IsArgSet("-?") || IsArgSet("-h") || IsArgSet("-help") || IsArgSet("-version")) { - HelpMessageDialog help(NULL, mapArgs.count("-version")); + HelpMessageDialog help(NULL, IsArgSet("-version")); help.showOrPrint(); return EXIT_SUCCESS; } @@ -672,7 +672,7 @@ int main(int argc, char *argv[]) // Allow parameter interaction before we create the options model app.parameterSetup(); // Load GUI settings from QSettings - app.createOptionsModel(mapArgs.count("-resetguisettings") != 0); + app.createOptionsModel(IsArgSet("-resetguisettings")); // Subscribe to global signals from core uiInterface.InitMessage.connect(InitMessage); diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 493d58641..6ce065b37 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -115,8 +115,8 @@ BOOST_AUTO_TEST_CASE(util_ParseParameters) // -a, -b and -ccc end up in map, -d ignored because it is after // a non-option argument (non-GNU option parsing) BOOST_CHECK(mapArgs.size() == 3 && mapMultiArgs.size() == 3); - BOOST_CHECK(mapArgs.count("-a") && mapArgs.count("-b") && mapArgs.count("-ccc") - && !mapArgs.count("f") && !mapArgs.count("-d")); + BOOST_CHECK(IsArgSet("-a") && IsArgSet("-b") && IsArgSet("-ccc") + && !IsArgSet("f") && !IsArgSet("-d")); BOOST_CHECK(mapMultiArgs.count("-a") && mapMultiArgs.count("-b") && mapMultiArgs.count("-ccc") && !mapMultiArgs.count("f") && !mapMultiArgs.count("-d")); diff --git a/src/util.cpp b/src/util.cpp index 6625ac932..cef3e97c2 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -379,6 +379,11 @@ void ParseParameters(int argc, const char* const argv[]) } } +bool IsArgSet(const std::string& strArg) +{ + return mapArgs.count(strArg); +} + std::string GetArg(const std::string& strArg, const std::string& strDefault) { if (mapArgs.count(strArg)) @@ -498,7 +503,7 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific) if (!path.empty()) return path; - if (mapArgs.count("-datadir")) { + if (IsArgSet("-datadir")) { path = fs::system_complete(mapArgs["-datadir"]); if (!fs::is_directory(path)) { path = ""; diff --git a/src/util.h b/src/util.h index 5d1d80d2d..aff4c3271 100644 --- a/src/util.h +++ b/src/util.h @@ -123,6 +123,14 @@ inline bool IsSwitchChar(char c) #endif } +/** + * Return true if the given argument has been manually set + * + * @param strArg Argument to get (e.g. "-foo") + * @return true if the argument has been set + */ +bool IsArgSet(const std::string& strArg); + /** * Return string argument or default value * diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1261aad3f..51423f88e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3494,7 +3494,7 @@ bool CWallet::InitLoadWallet() walletInstance->SetBestChain(chainActive.GetLocator()); } - else if (mapArgs.count("-usehd")) { + else if (IsArgSet("-usehd")) { bool useHD = GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET); if (walletInstance->IsHDEnabled() && !useHD) return InitError(strprintf(_("Error loading %s: You can't disable HD on a already existing HD wallet"), walletFile)); @@ -3618,7 +3618,7 @@ bool CWallet::ParameterInteraction() InitWarning(AmountHighWarn("-minrelaytxfee") + " " + _("The wallet will avoid paying less than the minimum relay fee.")); - if (mapArgs.count("-mintxfee")) + if (IsArgSet("-mintxfee")) { CAmount n = 0; if (!ParseMoney(mapArgs["-mintxfee"], n) || 0 == n) @@ -3628,7 +3628,7 @@ bool CWallet::ParameterInteraction() _("This is the minimum transaction fee you pay on every transaction.")); CWallet::minTxFee = CFeeRate(n); } - if (mapArgs.count("-fallbackfee")) + if (IsArgSet("-fallbackfee")) { CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) @@ -3638,7 +3638,7 @@ bool CWallet::ParameterInteraction() _("This is the transaction fee you may pay when fee estimates are not available.")); CWallet::fallbackFee = CFeeRate(nFeePerK); } - if (mapArgs.count("-paytxfee")) + if (IsArgSet("-paytxfee")) { CAmount nFeePerK = 0; if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) @@ -3654,7 +3654,7 @@ bool CWallet::ParameterInteraction() mapArgs["-paytxfee"], ::minRelayTxFee.ToString())); } } - if (mapArgs.count("-maxtxfee")) + if (IsArgSet("-maxtxfee")) { CAmount nMaxFee = 0; if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) From 71fde5563b5d05a63e3ad08a3c32a9e5ffb952f7 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 29 Nov 2016 18:43:29 -0800 Subject: [PATCH 4/7] Get rid of mapArgs direct access in ZMQ construction --- src/init.cpp | 2 +- src/zmq/zmqnotificationinterface.cpp | 8 ++++---- src/zmq/zmqnotificationinterface.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 778d66fba..76ef08da3 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1282,7 +1282,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) } #if ENABLE_ZMQ - pzmqNotificationInterface = CZMQNotificationInterface::CreateWithArguments(mapArgs); + pzmqNotificationInterface = CZMQNotificationInterface::Create(); if (pzmqNotificationInterface) { RegisterValidationInterface(pzmqNotificationInterface); diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index a7e20a835..2f5efcb4d 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -29,7 +29,7 @@ CZMQNotificationInterface::~CZMQNotificationInterface() } } -CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const std::map &args) +CZMQNotificationInterface* CZMQNotificationInterface::Create() { CZMQNotificationInterface* notificationInterface = NULL; std::map factories; @@ -42,11 +42,11 @@ CZMQNotificationInterface* CZMQNotificationInterface::CreateWithArguments(const for (std::map::const_iterator i=factories.begin(); i!=factories.end(); ++i) { - std::map::const_iterator j = args.find("-zmq" + i->first); - if (j!=args.end()) + std::string arg("-zmq" + i->first); + if (IsArgSet(arg)) { CZMQNotifierFactory factory = i->second; - std::string address = j->second; + std::string address = GetArg(arg, ""); CZMQAbstractNotifier *notifier = factory(); notifier->SetType(i->first); notifier->SetAddress(address); diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index 037470ec1..585554ccd 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -17,7 +17,7 @@ class CZMQNotificationInterface : public CValidationInterface public: virtual ~CZMQNotificationInterface(); - static CZMQNotificationInterface* CreateWithArguments(const std::map &args); + static CZMQNotificationInterface* Create(); protected: bool Initialize(); From 4cd373aea8d20356727f7d65e0bc818beb6523dc Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 29 Nov 2016 18:45:24 -0800 Subject: [PATCH 5/7] Un-expose mapArgs from utils.h --- src/bitcoin-cli.cpp | 6 +++--- src/bitcoind.cpp | 2 +- src/httprpc.cpp | 4 ++-- src/init.cpp | 4 ++-- src/net_processing.cpp | 2 +- src/qt/bitcoin.cpp | 2 +- src/qt/optionsmodel.cpp | 4 ++-- src/qt/test/rpcnestedtests.cpp | 2 ++ src/test/DoS_tests.cpp | 1 + src/test/test_bitcoin.cpp | 2 ++ src/test/util_tests.cpp | 2 ++ src/util.cpp | 2 +- src/util.h | 1 - src/wallet/wallet.cpp | 20 ++++++++++---------- 14 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index a4360dcd1..29d3cf674 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -95,7 +95,7 @@ static int AppInitRPC(int argc, char* argv[]) return EXIT_SUCCESS; } if (!boost::filesystem::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); + fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", GetArg("-datadir", "").c_str()); return EXIT_FAILURE; } try { @@ -211,7 +211,7 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) // Get credentials std::string strRPCUserColonPass; - if (mapArgs["-rpcpassword"] == "") { + if (GetArg("-rpcpassword", "") == "") { // Try fall back to cookie-based authentication if no password is provided if (!GetAuthCookie(&strRPCUserColonPass)) { throw std::runtime_error(strprintf( @@ -220,7 +220,7 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) } } else { - strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + strRPCUserColonPass = GetArg("-rpcuser", "") + ":" + GetArg("-rpcpassword", ""); } struct evkeyvalq *output_headers = evhttp_request_get_output_headers(req); diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index ee27f4122..98551ee85 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -99,7 +99,7 @@ bool AppInit(int argc, char* argv[]) { if (!boost::filesystem::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str()); + fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", GetArg("-datadir", "").c_str()); return false; } try diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 049a3f19a..970ce2db7 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -215,7 +215,7 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) static bool InitRPCAuthentication() { - if (mapArgs["-rpcpassword"] == "") + if (GetArg("-rpcpassword", "") == "") { LogPrintf("No rpcpassword set - using random cookie authentication\n"); if (!GenerateAuthCookie(&strRPCUserColonPass)) { @@ -226,7 +226,7 @@ static bool InitRPCAuthentication() } } else { LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation.\n"); - strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; + strRPCUserColonPass = GetArg("-rpcuser", "") + ":" + GetArg("-rpcpassword", ""); } return true; } diff --git a/src/init.cpp b/src/init.cpp index 76ef08da3..7d2bcb57b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -962,8 +962,8 @@ bool AppInitParameterInteraction() if (IsArgSet("-minrelaytxfee")) { CAmount n = 0; - if (!ParseMoney(mapArgs["-minrelaytxfee"], n) || 0 == n) - return InitError(AmountErrMsg("minrelaytxfee", mapArgs["-minrelaytxfee"])); + if (!ParseMoney(GetArg("-minrelaytxfee", ""), n) || 0 == n) + return InitError(AmountErrMsg("minrelaytxfee", GetArg("-minrelaytxfee", ""))); // High fee check is done afterward in CWallet::ParameterInteraction() ::minRelayTxFee = CFeeRate(n); } diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 98872200d..6282849ed 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -1060,7 +1060,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, unsigned int nMaxSendBufferSize = connman.GetSendBufferSize(); LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id); - if (IsArgSet("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0) + if (IsArgSet("-dropmessagestest") && GetRand(GetArg("-dropmessagestest", 0)) == 0) { LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n"); return true; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 9d80a3800..36d803ce0 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -604,7 +604,7 @@ int main(int argc, char *argv[]) if (!boost::filesystem::is_directory(GetDataDir(false))) { QMessageBox::critical(0, QObject::tr(PACKAGE_NAME), - QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); + QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(GetArg("-datadir", "")))); return EXIT_FAILURE; } try { diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index d48c4d91e..ce3a04010 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -36,7 +36,7 @@ OptionsModel::OptionsModel(QObject *parent, bool resetSettings) : void OptionsModel::addOverriddenOption(const std::string &option) { - strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(mapArgs[option]) + " "; + strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(GetArg(option, "")) + " "; } // Writes all missing QSettings with their default values @@ -464,4 +464,4 @@ void OptionsModel::checkAndMigrate() settings.setValue(strSettingsVersionKey, CLIENT_VERSION); } -} \ No newline at end of file +} diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index 26ac5e211..972dad72d 100644 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -19,6 +19,8 @@ #include +extern std::map mapArgs; + static UniValue rpcNestedTest_rpc(const JSONRPCRequest& request) { if (request.fHelp) { diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index 131d667e0..dafb096e8 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -32,6 +32,7 @@ struct COrphanTx { int64_t nTimeExpire; }; extern std::map mapOrphanTransactions; +extern std::map mapArgs; CService ip(uint32_t i) { diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 2a5a78de0..b62b31710 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -33,6 +33,8 @@ std::unique_ptr g_connman; FastRandomContext insecure_rand_ctx(true); +extern std::map mapArgs; + extern bool fPrintToConsole; extern void noui_connect(); diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 6ce065b37..b2f601613 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -19,6 +19,8 @@ using namespace std; +extern map mapArgs; + BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(util_criticalsection) diff --git a/src/util.cpp b/src/util.cpp index cef3e97c2..0a5a89999 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -504,7 +504,7 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific) return path; if (IsArgSet("-datadir")) { - path = fs::system_complete(mapArgs["-datadir"]); + path = fs::system_complete(GetArg("-datadir", "")); if (!fs::is_directory(path)) { path = ""; return path; diff --git a/src/util.h b/src/util.h index aff4c3271..88f8bb1be 100644 --- a/src/util.h +++ b/src/util.h @@ -41,7 +41,6 @@ public: boost::signals2::signal Translate; }; -extern std::map mapArgs; extern const std::map >& mapMultiArgs; extern bool fDebug; extern bool fPrintToConsole; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 51423f88e..543cfd685 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3621,8 +3621,8 @@ bool CWallet::ParameterInteraction() if (IsArgSet("-mintxfee")) { CAmount n = 0; - if (!ParseMoney(mapArgs["-mintxfee"], n) || 0 == n) - return InitError(AmountErrMsg("mintxfee", mapArgs["-mintxfee"])); + if (!ParseMoney(GetArg("-mintxfee", ""), n) || 0 == n) + return InitError(AmountErrMsg("mintxfee", GetArg("-mintxfee", ""))); if (n > HIGH_TX_FEE_PER_KB) InitWarning(AmountHighWarn("-mintxfee") + " " + _("This is the minimum transaction fee you pay on every transaction.")); @@ -3631,8 +3631,8 @@ bool CWallet::ParameterInteraction() if (IsArgSet("-fallbackfee")) { CAmount nFeePerK = 0; - if (!ParseMoney(mapArgs["-fallbackfee"], nFeePerK)) - return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), mapArgs["-fallbackfee"])); + if (!ParseMoney(GetArg("-fallbackfee", ""), nFeePerK)) + return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), GetArg("-fallbackfee", ""))); if (nFeePerK > HIGH_TX_FEE_PER_KB) InitWarning(AmountHighWarn("-fallbackfee") + " " + _("This is the transaction fee you may pay when fee estimates are not available.")); @@ -3641,8 +3641,8 @@ bool CWallet::ParameterInteraction() if (IsArgSet("-paytxfee")) { CAmount nFeePerK = 0; - if (!ParseMoney(mapArgs["-paytxfee"], nFeePerK)) - return InitError(AmountErrMsg("paytxfee", mapArgs["-paytxfee"])); + if (!ParseMoney(GetArg("-paytxfee", ""), nFeePerK)) + return InitError(AmountErrMsg("paytxfee", GetArg("-paytxfee", ""))); if (nFeePerK > HIGH_TX_FEE_PER_KB) InitWarning(AmountHighWarn("-paytxfee") + " " + _("This is the transaction fee you will pay if you send a transaction.")); @@ -3651,21 +3651,21 @@ bool CWallet::ParameterInteraction() if (payTxFee < ::minRelayTxFee) { return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s' (must be at least %s)"), - mapArgs["-paytxfee"], ::minRelayTxFee.ToString())); + GetArg("-paytxfee", ""), ::minRelayTxFee.ToString())); } } if (IsArgSet("-maxtxfee")) { CAmount nMaxFee = 0; - if (!ParseMoney(mapArgs["-maxtxfee"], nMaxFee)) - return InitError(AmountErrMsg("maxtxfee", mapArgs["-maxtxfee"])); + if (!ParseMoney(GetArg("-maxtxfee", ""), nMaxFee)) + return InitError(AmountErrMsg("maxtxfee", GetArg("-maxtxfee", ""))); if (nMaxFee > HIGH_MAX_TX_FEE) InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); maxTxFee = nMaxFee; if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) { return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), - mapArgs["-maxtxfee"], ::minRelayTxFee.ToString())); + GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString())); } } nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); From 4e048142a5e45d622355dad92ade192ad4769ca3 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 29 Nov 2016 18:52:44 -0800 Subject: [PATCH 6/7] Lock mapArgs/mapMultiArgs access in util --- src/util.cpp | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 0a5a89999..e3697183d 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -102,6 +102,7 @@ using namespace std; const char * const BITCOIN_CONF_FILENAME = "bitcoin.conf"; const char * const BITCOIN_PID_FILENAME = "bitcoind.pid"; +CCriticalSection cs_args; map mapArgs; static map > _mapMultiArgs; const map >& mapMultiArgs = _mapMultiArgs; @@ -346,6 +347,7 @@ static void InterpretNegativeSetting(std::string& strKey, std::string& strValue) void ParseParameters(int argc, const char* const argv[]) { + LOCK(cs_args); mapArgs.clear(); _mapMultiArgs.clear(); @@ -381,11 +383,13 @@ void ParseParameters(int argc, const char* const argv[]) bool IsArgSet(const std::string& strArg) { + LOCK(cs_args); return mapArgs.count(strArg); } std::string GetArg(const std::string& strArg, const std::string& strDefault) { + LOCK(cs_args); if (mapArgs.count(strArg)) return mapArgs[strArg]; return strDefault; @@ -393,6 +397,7 @@ std::string GetArg(const std::string& strArg, const std::string& strDefault) int64_t GetArg(const std::string& strArg, int64_t nDefault) { + LOCK(cs_args); if (mapArgs.count(strArg)) return atoi64(mapArgs[strArg]); return nDefault; @@ -400,6 +405,7 @@ int64_t GetArg(const std::string& strArg, int64_t nDefault) bool GetBoolArg(const std::string& strArg, bool fDefault) { + LOCK(cs_args); if (mapArgs.count(strArg)) return InterpretBool(mapArgs[strArg]); return fDefault; @@ -407,6 +413,7 @@ bool GetBoolArg(const std::string& strArg, bool fDefault) bool SoftSetArg(const std::string& strArg, const std::string& strValue) { + LOCK(cs_args); if (mapArgs.count(strArg)) return false; mapArgs[strArg] = strValue; @@ -522,6 +529,8 @@ const boost::filesystem::path &GetDataDir(bool fNetSpecific) void ClearDatadirCache() { + LOCK(csPathCached); + pathCached = boost::filesystem::path(); pathCachedNetSpecific = boost::filesystem::path(); } @@ -541,18 +550,21 @@ void ReadConfigFile(const std::string& confPath) if (!streamConfig.good()) return; // No bitcoin.conf file is OK - set setOptions; - setOptions.insert("*"); - - for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it) { - // Don't overwrite existing settings so command line settings override bitcoin.conf - string strKey = string("-") + it->string_key; - string strValue = it->value[0]; - InterpretNegativeSetting(strKey, strValue); - if (mapArgs.count(strKey) == 0) - mapArgs[strKey] = strValue; - _mapMultiArgs[strKey].push_back(strValue); + LOCK(cs_args); + set setOptions; + setOptions.insert("*"); + + for (boost::program_options::detail::config_file_iterator it(streamConfig, setOptions), end; it != end; ++it) + { + // Don't overwrite existing settings so command line settings override bitcoin.conf + string strKey = string("-") + it->string_key; + string strValue = it->value[0]; + InterpretNegativeSetting(strKey, strValue); + if (mapArgs.count(strKey) == 0) + mapArgs[strKey] = strValue; + _mapMultiArgs[strKey].push_back(strValue); + } } // If datadir is changed in .conf file: ClearDatadirCache(); From c2f61bebb190258753714b29ab2041e80651cec9 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 24 Dec 2016 11:28:44 -0500 Subject: [PATCH 7/7] Add a ForceSetArg method for testing --- src/qt/test/rpcnestedtests.cpp | 4 +--- src/test/DoS_tests.cpp | 6 +++--- src/test/test_bitcoin.cpp | 4 +--- src/util.cpp | 8 ++++++++ src/util.h | 3 +++ 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index 972dad72d..fb044489d 100644 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -19,8 +19,6 @@ #include -extern std::map mapArgs; - static UniValue rpcNestedTest_rpc(const JSONRPCRequest& request) { if (request.fHelp) { @@ -47,7 +45,7 @@ void RPCNestedTests::rpcNestedTests() std::string path = QDir::tempPath().toStdString() + "/" + strprintf("test_bitcoin_qt_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); QDir dir(QString::fromStdString(path)); dir.mkpath("."); - mapArgs["-datadir"] = path; + ForceSetArg("-datadir", path); //mempool.setSanityCheck(1.0); pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); diff --git a/src/test/DoS_tests.cpp b/src/test/DoS_tests.cpp index dafb096e8..d90dcaeb0 100644 --- a/src/test/DoS_tests.cpp +++ b/src/test/DoS_tests.cpp @@ -12,6 +12,7 @@ #include "script/sign.h" #include "serialize.h" #include "util.h" +#include "validation.h" #include "test/test_bitcoin.h" @@ -32,7 +33,6 @@ struct COrphanTx { int64_t nTimeExpire; }; extern std::map mapOrphanTransactions; -extern std::map mapArgs; CService ip(uint32_t i) { @@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE(DoS_banning) BOOST_AUTO_TEST_CASE(DoS_banscore) { connman->ClearBanned(); - mapArgs["-banscore"] = "111"; // because 11 is my favorite number + ForceSetArg("-banscore", "111"); // because 11 is my favorite number CAddress addr1(ip(0xa0b0c001), NODE_NONE); CNode dummyNode1(id++, NODE_NETWORK, 0, INVALID_SOCKET, addr1, 3, 1, "", true); dummyNode1.SetSendVersion(PROTOCOL_VERSION); @@ -90,7 +90,7 @@ BOOST_AUTO_TEST_CASE(DoS_banscore) Misbehaving(dummyNode1.GetId(), 1); SendMessages(&dummyNode1, *connman); BOOST_CHECK(connman->IsBanned(addr1)); - mapArgs.erase("-banscore"); + ForceSetArg("-banscore", std::to_string(DEFAULT_BANSCORE_THRESHOLD)); } BOOST_AUTO_TEST_CASE(DoS_bantime) diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index b62b31710..5c4ef5eb8 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -33,8 +33,6 @@ std::unique_ptr g_connman; FastRandomContext insecure_rand_ctx(true); -extern std::map mapArgs; - extern bool fPrintToConsole; extern void noui_connect(); @@ -66,7 +64,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha ClearDatadirCache(); pathTemp = GetTempPath() / strprintf("test_bitcoin_%lu_%i", (unsigned long)GetTime(), (int)(GetRand(100000))); boost::filesystem::create_directories(pathTemp); - mapArgs["-datadir"] = pathTemp.string(); + ForceSetArg("-datadir", pathTemp.string()); mempool.setSanityCheck(1.0); pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); diff --git a/src/util.cpp b/src/util.cpp index e3697183d..793b8f2dd 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -428,6 +428,14 @@ bool SoftSetBoolArg(const std::string& strArg, bool fValue) return SoftSetArg(strArg, std::string("0")); } +void ForceSetArg(const std::string& strArg, const std::string& strValue) +{ + LOCK(cs_args); + mapArgs[strArg] = strValue; +} + + + static const int screenWidth = 79; static const int optIndent = 2; static const int msgIndent = 7; diff --git a/src/util.h b/src/util.h index 88f8bb1be..f030dbbb2 100644 --- a/src/util.h +++ b/src/util.h @@ -175,6 +175,9 @@ bool SoftSetArg(const std::string& strArg, const std::string& strValue); */ bool SoftSetBoolArg(const std::string& strArg, bool fValue); +// Forces a arg setting, used only in testing +void ForceSetArg(const std::string& strArg, const std::string& strValue); + /** * Format a string to be used as group of options in help messages *