From 84b85786f0f5cb23cc257a4464ae345e1d372313 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Wed, 9 Mar 2022 16:11:39 -0500 Subject: [PATCH] Decouple RegTestChainParams from ArgsManager RegTest chain params can now be initialized by configuring a RegTestOptions struct, or with ArgsManager. This offers an interface for creating RegTestChainParams without a gArgs object. --- src/chainparams.cpp | 78 ++++++++++++++++++++++++++---------------- src/chainparams.h | 20 +++++++++++ src/deploymentinfo.cpp | 18 ++++++++++ src/deploymentinfo.h | 3 ++ 4 files changed, 89 insertions(+), 30 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 12b5a788b46..e4a5a489a2f 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -399,7 +399,8 @@ void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& option class CRegTestParams : public CChainParams { public: - explicit CRegTestParams(const ArgsManager& args) { + explicit CRegTestParams(const RegTestOptions& opts) + { strNetworkID = CBaseChainParams::REGTEST; consensus.signet_blocks = false; consensus.signet_challenge.clear(); @@ -437,11 +438,33 @@ public: pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; nDefaultPort = 18444; - nPruneAfterHeight = args.GetBoolArg("-fastprune", false) ? 100 : 1000; + nPruneAfterHeight = opts.fastprune ? 100 : 1000; m_assumed_blockchain_size = 0; m_assumed_chain_state_size = 0; - UpdateActivationParametersFromArgs(args); + for (const auto& [dep, height] : opts.activation_heights) { + switch (dep) { + case Consensus::BuriedDeployment::DEPLOYMENT_SEGWIT: + consensus.SegwitHeight = int{height}; + break; + case Consensus::BuriedDeployment::DEPLOYMENT_HEIGHTINCB: + consensus.BIP34Height = int{height}; + break; + case Consensus::BuriedDeployment::DEPLOYMENT_DERSIG: + consensus.BIP66Height = int{height}; + break; + case Consensus::BuriedDeployment::DEPLOYMENT_CLTV: + consensus.BIP65Height = int{height}; + break; + case Consensus::BuriedDeployment::DEPLOYMENT_CSV: + consensus.CSVHeight = int{height}; + break; + } + } + + for (const auto& [deployment_pos, version_bits_params] : opts.version_bits_parameters) { + UpdateVersionBitsParameters(deployment_pos, version_bits_params.start_time, version_bits_params.timeout, version_bits_params.min_activation_height); + } genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); @@ -498,41 +521,31 @@ public: consensus.vDeployments[d].nTimeout = nTimeout; consensus.vDeployments[d].min_activation_height = min_activation_height; } - void UpdateActivationParametersFromArgs(const ArgsManager& args); }; -static void MaybeUpdateHeights(const ArgsManager& args, Consensus::Params& consensus) +void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& options) { + if (auto value = args.GetBoolArg("-fastprune")) options.fastprune = *value; + for (const std::string& arg : args.GetArgs("-testactivationheight")) { const auto found{arg.find('@')}; if (found == std::string::npos) { throw std::runtime_error(strprintf("Invalid format (%s) for -testactivationheight=name@height.", arg)); } - const auto name{arg.substr(0, found)}; + const auto value{arg.substr(found + 1)}; int32_t height; if (!ParseInt32(value, &height) || height < 0 || height >= std::numeric_limits::max()) { throw std::runtime_error(strprintf("Invalid height value (%s) for -testactivationheight=name@height.", arg)); } - if (name == "segwit") { - consensus.SegwitHeight = int{height}; - } else if (name == "bip34") { - consensus.BIP34Height = int{height}; - } else if (name == "dersig") { - consensus.BIP66Height = int{height}; - } else if (name == "cltv") { - consensus.BIP65Height = int{height}; - } else if (name == "csv") { - consensus.CSVHeight = int{height}; + + const auto deployment_name{arg.substr(0, found)}; + if (const auto buried_deployment = GetBuriedDeployment(deployment_name)) { + options.activation_heights[*buried_deployment] = height; } else { throw std::runtime_error(strprintf("Invalid name (%s) for -testactivationheight=name@height.", arg)); } } -} - -void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args) -{ - MaybeUpdateHeights(args, consensus); if (!args.IsArgSet("-vbparams")) return; @@ -541,23 +554,26 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args) if (vDeploymentParams.size() < 3 || 4 < vDeploymentParams.size()) { throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:min_activation_height]"); } - int64_t nStartTime, nTimeout; - int min_activation_height = 0; - if (!ParseInt64(vDeploymentParams[1], &nStartTime)) { + CChainParams::VersionBitsParameters vbparams{}; + if (!ParseInt64(vDeploymentParams[1], &vbparams.start_time)) { throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1])); } - if (!ParseInt64(vDeploymentParams[2], &nTimeout)) { + if (!ParseInt64(vDeploymentParams[2], &vbparams.timeout)) { throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2])); } - if (vDeploymentParams.size() >= 4 && !ParseInt32(vDeploymentParams[3], &min_activation_height)) { - throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3])); + if (vDeploymentParams.size() >= 4) { + if (!ParseInt32(vDeploymentParams[3], &vbparams.min_activation_height)) { + throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3])); + } + } else { + vbparams.min_activation_height = 0; } bool found = false; for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) { - UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, min_activation_height); + options.version_bits_parameters[Consensus::DeploymentPos(j)] = vbparams; found = true; - LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, min_activation_height=%d\n", vDeploymentParams[0], nStartTime, nTimeout, min_activation_height); + LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, min_activation_height=%d\n", vDeploymentParams[0], vbparams.start_time, vbparams.timeout, vbparams.min_activation_height); break; } } @@ -585,7 +601,9 @@ std::unique_ptr CreateChainParams(const ArgsManager& args, c ReadSigNetArgs(args, opts); return std::make_unique(opts); } else if (chain == CBaseChainParams::REGTEST) { - return std::unique_ptr(new CRegTestParams(args)); + auto opts = CChainParams::RegTestOptions{}; + ReadRegTestArgs(args, opts); + return std::make_unique(opts); } throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); } diff --git a/src/chainparams.h b/src/chainparams.h index 2f6f3f0907e..f2e2eb8bc0a 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -13,8 +13,10 @@ #include #include +#include #include #include +#include #include typedef std::map MapCheckpoints; @@ -131,6 +133,24 @@ public: std::optional> seeds{}; }; + /** + * VersionBitsParameters holds activation parameters + */ + struct VersionBitsParameters { + int64_t start_time; + int64_t timeout; + int min_activation_height; + }; + + /** + * RegTestOptions holds configurations for creating a regtest CChainParams. + */ + struct RegTestOptions { + std::unordered_map version_bits_parameters{}; + std::unordered_map activation_heights{}; + bool fastprune{false}; + }; + protected: CChainParams() {} diff --git a/src/deploymentinfo.cpp b/src/deploymentinfo.cpp index 246932e56da..185a7dcb54c 100644 --- a/src/deploymentinfo.cpp +++ b/src/deploymentinfo.cpp @@ -6,6 +6,8 @@ #include +#include + const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = { { /*.name =*/ "testdummy", @@ -34,3 +36,19 @@ std::string DeploymentName(Consensus::BuriedDeployment dep) } // no default case, so the compiler can warn about missing cases return ""; } + +std::optional GetBuriedDeployment(const std::string_view name) +{ + if (name == "segwit") { + return Consensus::BuriedDeployment::DEPLOYMENT_SEGWIT; + } else if (name == "bip34") { + return Consensus::BuriedDeployment::DEPLOYMENT_HEIGHTINCB; + } else if (name == "dersig") { + return Consensus::BuriedDeployment::DEPLOYMENT_DERSIG; + } else if (name == "cltv") { + return Consensus::BuriedDeployment::DEPLOYMENT_CLTV; + } else if (name == "csv") { + return Consensus::BuriedDeployment::DEPLOYMENT_CSV; + } + return std::nullopt; +} diff --git a/src/deploymentinfo.h b/src/deploymentinfo.h index 8b909dedb46..72ba297ea0b 100644 --- a/src/deploymentinfo.h +++ b/src/deploymentinfo.h @@ -7,6 +7,7 @@ #include +#include #include struct VBDeploymentInfo { @@ -26,4 +27,6 @@ inline std::string DeploymentName(Consensus::DeploymentPos pos) return VersionBitsDeploymentInfo[pos].name; } +std::optional GetBuriedDeployment(const std::string_view deployment_name); + #endif // BITCOIN_DEPLOYMENTINFO_H