chainparams: encapsulate deployment configuration logic
What changed, and why it matters
This commit is a straightforward internal code reorganization. It moves the logic that applies custom soft-fork activation settings from one place in the code to another, grouping it into a reusable helper function. There is no change to how Bitcoin Core behaves, no bug fix, and no security-relevant change visible in the diff.
No action required. This is a non-security refactoring commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change refactors chain parameter construction. A new CChainParams::DeploymentOptions struct is introduced, the -testactivationheight and -vbparams parsing logic is extracted into a static HandleDeploymentArgs helper, and the application of those options is moved into a new protected ApplyDeploymentOptions method. The regtest-only behavior is preserved; the commit message explicitly states this is preparation for a future change. No functional or security changes are introduced.
Changed components
src/chainparams.cppsrc/kernel/chainparams.cppsrc/kernel/chainparams.hInspect captured patch +73 / −57
diff --git a/src/chainparams.cpp b/src/chainparams.cpp
index 32c3bff7..4cfd9589 100644
--- a/src/chainparams.cpp
+++ b/src/chainparams.cpp
@@ -23,29 +23,8 @@
using util::SplitString;
-void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options)
-{
- if (!args.GetArgs("-signetseednode").empty()) {
- options.seeds.emplace(args.GetArgs("-signetseednode"));
- }
- if (!args.GetArgs("-signetchallenge").empty()) {
- const auto signet_challenge = args.GetArgs("-signetchallenge");
- if (signet_challenge.size() != 1) {
- throw std::runtime_error("-signetchallenge cannot be multiple values.");
- }
- const auto val{TryParseHex<uint8_t>(signet_challenge[0])};
- if (!val) {
- throw std::runtime_error(strprintf("-signetchallenge must be hex, not '%s'.", signet_challenge[0]));
- }
- options.challenge.emplace(*val);
- }
-}
-
-void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& options)
+static void HandleDeploymentArgs(const ArgsManager& args, CChainParams::DeploymentOptions& options)
{
- if (auto value = args.GetBoolArg("-fastprune")) options.fastprune = *value;
- if (HasTestOption(args, "bip94")) options.enforce_bip94 = true;
-
for (const std::string& arg : args.GetArgs("-testactivationheight")) {
const auto found{arg.find('@')};
if (found == std::string::npos) {
@@ -107,6 +86,32 @@ void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& opti
}
}
+void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options)
+{
+ if (!args.GetArgs("-signetseednode").empty()) {
+ options.seeds.emplace(args.GetArgs("-signetseednode"));
+ }
+ if (!args.GetArgs("-signetchallenge").empty()) {
+ const auto signet_challenge = args.GetArgs("-signetchallenge");
+ if (signet_challenge.size() != 1) {
+ throw std::runtime_error("-signetchallenge cannot be multiple values.");
+ }
+ const auto val{TryParseHex<uint8_t>(signet_challenge[0])};
+ if (!val) {
+ throw std::runtime_error(strprintf("-signetchallenge must be hex, not '%s'.", signet_challenge[0]));
+ }
+ options.challenge.emplace(*val);
+ }
+}
+
+void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& options)
+{
+ if (auto value = args.GetBoolArg("-fastprune")) options.fastprune = *value;
+ if (HasTestOption(args, "bip94")) options.enforce_bip94 = true;
+
+ HandleDeploymentArgs(args, options.dep_opts);
+}
+
static std::unique_ptr<const CChainParams> globalChainParams;
const CChainParams &Params() {
diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp
index 969a838c..27e846fe 100644
--- a/src/kernel/chainparams.cpp
+++ b/src/kernel/chainparams.cpp
@@ -72,6 +72,35 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
}
+void CChainParams::ApplyDeploymentOptions(const DeploymentOptions& opts)
+{
+ 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) {
+ consensus.vDeployments[deployment_pos].nStartTime = version_bits_params.start_time;
+ consensus.vDeployments[deployment_pos].nTimeout = version_bits_params.timeout;
+ consensus.vDeployments[deployment_pos].min_activation_height = version_bits_params.min_activation_height;
+ }
+}
+
/**
* Main network on which people trade goods and services.
*/
@@ -566,31 +595,7 @@ public:
m_assumed_blockchain_size = 0;
m_assumed_chain_state_size = 0;
- 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) {
- consensus.vDeployments[deployment_pos].nStartTime = version_bits_params.start_time;
- consensus.vDeployments[deployment_pos].nTimeout = version_bits_params.timeout;
- consensus.vDeployments[deployment_pos].min_activation_height = version_bits_params.min_activation_height;
- }
+ ApplyDeploymentOptions(opts.dep_opts);
genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN);
consensus.hashGenesisBlock = genesis.GetHash();
diff --git a/src/kernel/chainparams.h b/src/kernel/chainparams.h
index f7209bee..ae57fd82 100644
--- a/src/kernel/chainparams.h
+++ b/src/kernel/chainparams.h
@@ -127,14 +127,6 @@ public:
const ChainTxData& TxData() const { return chainTxData; }
- /**
- * SigNetOptions holds configurations for creating a signet CChainParams.
- */
- struct SigNetOptions {
- std::optional<std::vector<uint8_t>> challenge{};
- std::optional<std::vector<std::string>> seeds{};
- };
-
/**
* VersionBitsParameters holds activation parameters
*/
@@ -144,12 +136,24 @@ public:
int min_activation_height;
};
+ struct DeploymentOptions {
+ std::unordered_map<Consensus::DeploymentPos, VersionBitsParameters> version_bits_parameters{};
+ std::unordered_map<Consensus::BuriedDeployment, int> activation_heights{};
+ };
+
+ /**
+ * SigNetOptions holds configurations for creating a signet CChainParams.
+ */
+ struct SigNetOptions {
+ std::optional<std::vector<uint8_t>> challenge{};
+ std::optional<std::vector<std::string>> seeds{};
+ };
+
/**
* RegTestOptions holds configurations for creating a regtest CChainParams.
*/
struct RegTestOptions {
- std::unordered_map<Consensus::DeploymentPos, VersionBitsParameters> version_bits_parameters{};
- std::unordered_map<Consensus::BuriedDeployment, int> activation_heights{};
+ DeploymentOptions dep_opts{};
bool fastprune{false};
bool enforce_bip94{false};
};
@@ -180,6 +184,8 @@ protected:
std::vector<AssumeutxoData> m_assumeutxo_data;
ChainTxData chainTxData;
HeadersSyncParams m_headers_sync_params;
+
+ void ApplyDeploymentOptions(const DeploymentOptions& opts);
};
std::optional<ChainType> GetNetworkForMagic(const MessageStartChars& pchMessageStart);
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.