diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -193,8 +193,8 @@ error.c_str()); return EXIT_FAILURE; } - // Check for -testnet or -regtest parameter (BaseParams() calls are only - // valid after this clause) + // Check for -chain, -testnet or -regtest parameter (BaseParams() calls are + // only valid after this clause) try { SelectBaseParams(gArgs.GetChainName()); } catch (const std::exception &e) { diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -114,8 +114,8 @@ return EXIT_FAILURE; } - // Check for -testnet or -regtest parameter (Params() calls are only valid - // after this clause) + // Check for -chain, -testnet or -regtest parameter (Params() calls are only + // valid after this clause) try { SelectParams(gArgs.GetChainName()); } catch (const std::exception &e) { diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -114,8 +114,8 @@ return InitError( strprintf("Error reading configuration file: %s\n", error)); } - // Check for -testnet or -regtest parameter (Params() calls are only - // valid after this clause) + // Check for -chain, -testnet or -regtest parameter (Params() calls are + // only valid after this clause) try { SelectParams(gArgs.GetChainName()); } catch (const std::exception &e) { diff --git a/src/chainparamsbase.cpp b/src/chainparamsbase.cpp --- a/src/chainparamsbase.cpp +++ b/src/chainparamsbase.cpp @@ -16,14 +16,19 @@ const std::string CBaseChainParams::REGTEST = "regtest"; void SetupChainParamsBaseOptions() { - gArgs.AddArg("-regtest", - "Enter regression test mode, which uses a special chain in " - "which blocks can be solved instantly. This is intended for " - "regression testing tools and app development.", - ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, - OptionsCategory::CHAINPARAMS); - gArgs.AddArg("-testnet", "Use the test chain", ArgsManager::ALLOW_ANY, - OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-chain=", + "Use the chain (default: main). Allowed values: main, " + "test, regtest", + ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS); + gArgs.AddArg( + "-regtest", + "Enter regression test mode, which uses a special chain in which " + "blocks can be solved instantly. This is intended for regression " + "testing tools and app development. Equivalent to -chain=regtest.", + ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, + OptionsCategory::CHAINPARAMS); + gArgs.AddArg("-testnet", "Use the test chain. Equivalent to -chain=test.", + ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS); } static std::unique_ptr globalChainBaseParams; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -655,8 +655,8 @@ // network-specific settings. // - Needs to be done before createOptionsModel. - // Check for -testnet or -regtest parameter (Params() calls are only valid - // after this clause) + // Check for -chain, -testnet or -regtest parameter (Params() calls are only + // valid after this clause) try { node->selectParams(gArgs.GetChainName()); } catch (std::exception &e) { @@ -670,8 +670,8 @@ PaymentServer::ipcParseCommandLine(*node, argc, argv); #endif - QScopedPointer networkStyle(NetworkStyle::instantiate( - QString::fromStdString(Params().NetworkIDString()))); + QScopedPointer networkStyle( + NetworkStyle::instantiate(Params().NetworkIDString())); assert(!networkStyle.isNull()); // Allow for separate UI settings for testnets QApplication::setApplicationName(networkStyle->getAppName()); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -598,9 +598,8 @@ // Start client minimized QString strArgs = "-min"; // Set -testnet /-regtest options - strArgs += QString::fromStdString(strprintf( - " -testnet=%d -regtest=%d", gArgs.GetBoolArg("-testnet", false), - gArgs.GetBoolArg("-regtest", false))); + strArgs += QString::fromStdString( + strprintf(" -chain=%s", gArgs.GetChainName())); // Set the path to the shortcut target psl->SetPath(pszExePath); @@ -702,9 +701,7 @@ optionFile << strprintf("Name=Bitcoin (%s)\n", chain); } optionFile << "Exec=" << pszExePath - << strprintf(" -min -testnet=%d -regtest=%d\n", - gArgs.GetBoolArg("-testnet", false), - gArgs.GetBoolArg("-regtest", false)); + << strprintf(" -min -chain=%s\n", chain); optionFile << "Terminal=false\n"; optionFile << "Hidden=false\n"; optionFile.close(); diff --git a/src/qt/networkstyle.h b/src/qt/networkstyle.h --- a/src/qt/networkstyle.h +++ b/src/qt/networkstyle.h @@ -12,9 +12,10 @@ /* Coin network-specific GUI style information */ class NetworkStyle { public: - /** Get style associated with provided BIP70 network id, or 0 if not known + /** + * Get style associated with provided BIP70 network id, or 0 if not known. */ - static const NetworkStyle *instantiate(const QString &networkId); + static const NetworkStyle *instantiate(const std::string &networkId); const QString &getAppName() const { return appName; } const QIcon &getAppIcon() const { return appIcon; } diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -6,6 +6,9 @@ #include +#include +#include + #include static const struct { @@ -13,11 +16,9 @@ const char *appName; const int iconColorHueShift; const int iconColorSaturationReduction; - const char *titleAddText; -} network_styles[] = {{"main", QAPP_APP_NAME_DEFAULT, 0, 0, ""}, - {"test", QAPP_APP_NAME_TESTNET, 70, 30, - QT_TRANSLATE_NOOP("SplashScreen", "[testnet]")}, - {"regtest", QAPP_APP_NAME_REGTEST, 160, 30, "[regtest]"}}; +} network_styles[] = {{"main", QAPP_APP_NAME_DEFAULT, 0, 0}, + {"test", QAPP_APP_NAME_TESTNET, 70, 30}, + {"regtest", QAPP_APP_NAME_REGTEST, 160, 30}}; static const unsigned network_styles_count = sizeof(network_styles) / sizeof(*network_styles); @@ -73,13 +74,15 @@ trayAndWindowIcon = QIcon(pixmap.scaled(QSize(256, 256))); } -const NetworkStyle *NetworkStyle::instantiate(const QString &networkId) { +const NetworkStyle *NetworkStyle::instantiate(const std::string &networkId) { + std::string titleAddText = + networkId == CBaseChainParams::MAIN ? "" : strprintf("[%s]", networkId); for (unsigned x = 0; x < network_styles_count; ++x) { if (networkId == network_styles[x].networkId) { return new NetworkStyle( network_styles[x].appName, network_styles[x].iconColorHueShift, network_styles[x].iconColorSaturationReduction, - network_styles[x].titleAddText); + titleAddText.c_str()); } } return nullptr; diff --git a/src/qt/test/apptests.cpp b/src/qt/test/apptests.cpp --- a/src/qt/test/apptests.cpp +++ b/src/qt/test/apptests.cpp @@ -101,8 +101,8 @@ m_app.parameterSetup(); m_app.createOptionsModel(true /* reset settings */); - QScopedPointer style(NetworkStyle::instantiate( - QString::fromStdString(Params().NetworkIDString()))); + QScopedPointer style( + NetworkStyle::instantiate(Params().NetworkIDString())); m_app.setupPlatformStyle(); m_app.createWindow(&config, style.data()); connect(&m_app, &BitcoinApplication::windowShown, this, diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -1138,7 +1138,7 @@ // || BOOST_CHECK_EQUAL( out_sha_hex, - "b284f4b4a15dd6bf8c06213a69a004b1960388e1d9917173927db52ac220927f"); + "94b4ad55c8ac639a56b93e36f7e32e4c611fd7d7dd7b2be6a71707b1eadcaec7"); } BOOST_AUTO_TEST_CASE(util_FormatMoney) { diff --git a/src/util/system.cpp b/src/util/system.cpp --- a/src/util/system.cpp +++ b/src/util/system.cpp @@ -1108,12 +1108,13 @@ std::string ArgsManager::GetChainName() const { LOCK(cs_args); - bool fRegTest = ArgsManagerHelper::GetNetBoolArg(*this, "-regtest"); - bool fTestNet = ArgsManagerHelper::GetNetBoolArg(*this, "-testnet"); + const bool fRegTest = ArgsManagerHelper::GetNetBoolArg(*this, "-regtest"); + const bool fTestNet = ArgsManagerHelper::GetNetBoolArg(*this, "-testnet"); + const bool is_chain_arg_set = IsArgSet("-chain"); - if (fTestNet && fRegTest) { - throw std::runtime_error( - "Invalid combination of -regtest and -testnet."); + if (int(is_chain_arg_set) + int(fRegTest) + int(fTestNet) > 1) { + throw std::runtime_error("Invalid combination of -regtest, -testnet " + "and -chain. Can use at most one."); } if (fRegTest) { return CBaseChainParams::REGTEST; @@ -1121,7 +1122,7 @@ if (fTestNet) { return CBaseChainParams::TESTNET; } - return CBaseChainParams::MAIN; + return GetArg("-chain", CBaseChainParams::MAIN); } bool RenameOver(fs::path src, fs::path dest) { diff --git a/test/lint/check-doc.py b/test/lint/check-doc.py --- a/test/lint/check-doc.py +++ b/test/lint/check-doc.py @@ -25,10 +25,14 @@ REGEX_DOC = r'AddArg\(\s*"(-[^"=]+?)(?:=|")' # list false positive unknows arguments -SET_FALSE_POSITIVE_UNKNOWNS = set(['-zmqpubhashblock', - '-zmqpubhashtx', - '-zmqpubrawblock', - '-zmqpubrawtx']) +SET_FALSE_POSITIVE_UNKNOWNS = set([ + '-regtest', + '-testnet', + '-zmqpubhashblock', + '-zmqpubhashtx', + '-zmqpubrawblock', + '-zmqpubrawtx', +]) # list false positive undocumented arguments SET_FALSE_POSITIVE_UNDOCUMENTED = set(['-dbcrashratio',