diff --git a/src/chainparams.cpp b/src/chainparams.cpp index fd928318d..65bc5577c 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -402,6 +402,12 @@ public: vFoundersRewardAddress = { "t2FwcEhFdNXuFMv1tcYwaBJtYVtMj8b1uTg" }; assert(vFoundersRewardAddress.size() <= consensus.GetLastFoundersRewardBlockHeight()); } + + void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight) + { + assert(idx > Consensus::BASE_SPROUT && idx < Consensus::MAX_NETWORK_UPGRADES); + consensus.vUpgrades[idx].nActivationHeight = nActivationHeight; + } }; static CRegTestParams regTestParams; @@ -475,3 +481,8 @@ std::string CChainParams::GetFoundersRewardAddressAtIndex(int i) const { assert(i >= 0 && i < vFoundersRewardAddress.size()); return vFoundersRewardAddress[i]; } + +void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight) +{ + regTestParams.UpdateNetworkUpgradeParameters(idx, nActivationHeight); +} diff --git a/src/chainparams.h b/src/chainparams.h index 10e2e6d15..f1d9b43c3 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -134,4 +134,9 @@ void SelectParams(CBaseChainParams::Network network); */ bool SelectParamsFromCommandLine(); +/** + * Allows modifying the network upgrade regtest parameters. + */ +void UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex idx, int nActivationHeight); + #endif // BITCOIN_CHAINPARAMS_H diff --git a/src/init.cpp b/src/init.cpp index 7df31ab1b..52b120830 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -16,6 +16,7 @@ #endif #include "checkpoints.h" #include "compat/sanity.h" +#include "consensus/upgrades.h" #include "consensus/validation.h" #include "httpserver.h" #include "httprpc.h" @@ -44,8 +45,10 @@ #include #endif +#include #include #include +#include #include #include #include @@ -448,6 +451,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-fuzzmessagestest=", "Randomly fuzz 1 of every network messages"); strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", 1)); strUsage += HelpMessageOpt("-stopafterblockimport", strprintf("Stop running after importing blocks from disk (default: %u)", 0)); + strUsage += HelpMessageOpt("-nuparams=hexBranchId:activationHeight", "Use given activation height for specified network upgrade (regtest-only)"); } string debugCategories = "addrman, alert, bench, coindb, db, estimatefee, http, libevent, lock, mempool, net, partitioncheck, pow, proxy, prune, " "rand, reindex, rpc, selectcoins, tor, zmq, zrpc, zrpcunsafe (implies zrpc)"; // Don't translate these @@ -1035,6 +1039,38 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } } + if (!mapMultiArgs["-nuparams"].empty()) { + // Allow overriding network upgrade parameters for testing + if (Params().NetworkIDString() != "regtest") { + return InitError("Network upgrade parameters may only be overridden on regtest."); + } + const vector& deployments = mapMultiArgs["-nuparams"]; + for (auto i : deployments) { + std::vector vDeploymentParams; + boost::split(vDeploymentParams, i, boost::is_any_of(":")); + if (vDeploymentParams.size() != 2) { + return InitError("Network upgrade parameters malformed, expecting hexBranchId:activationHeight"); + } + int nActivationHeight; + if (!ParseInt32(vDeploymentParams[1], &nActivationHeight)) { + return InitError(strprintf("Invalid nActivationHeight (%s)", vDeploymentParams[1])); + } + bool found = false; + // Exclude Sprout from upgrades + for (auto i = Consensus::BASE_SPROUT + 1; i < Consensus::MAX_NETWORK_UPGRADES; ++i) + { + if (vDeploymentParams[0].compare(HexInt(NetworkUpgradeInfo[i].nBranchId)) == 0) { + UpdateNetworkUpgradeParameters(Consensus::UpgradeIndex(i), nActivationHeight); + found = true; + LogPrintf("Setting network upgrade activation parameters for %s to height=%d\n", vDeploymentParams[0], nActivationHeight); + break; + } + } + if (!found) { + return InitError(strprintf("Invalid network upgrade (%s)", vDeploymentParams[0])); + } + } + } // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 054992cfb..4648eb0bb 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include using namespace std; @@ -46,6 +47,13 @@ string SanitizeFilename(const string& str) return strResult; } +std::string HexInt(uint32_t val) +{ + std::stringstream ss; + ss << std::setfill('0') << std::setw(sizeof(uint32_t) * 2) << std::hex << val; + return ss.str(); +} + const signed char p_util_hexdigit[256] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index d6973a130..173bbefd0 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -24,6 +24,7 @@ std::string SanitizeFilename(const std::string& str); std::string SanitizeString(const std::string& str); +std::string HexInt(uint32_t val); std::vector ParseHex(const char* psz); std::vector ParseHex(const std::string& str); signed char HexDigit(char c);