Merge bitcoin/bitcoin#35335: Make deployment configuration available outside of regtest in unit tests

801e3bfe38 chainparams: add overloads for RegTest and SigNet with no options (Antoine Poinsot)
4995c00a9c chainparams: make deployment configuration available on all test networks (Antoine Poinsot)
df7ed5f355 chainparams: encapsulate deployment configuration logic (Antoine Poinsot)

Pull request description:

  It's sometimes useful to test a deployment on other networks than regtest. This may be e.g. because regtest lacks a property relevant for the test, or simply because the test aims to be portable while regtest is Bitcoin Core specific.

  This PR makes it possible to set the `-vbparams` and `-testactivationheight` options on any network in unit tests, and on any **test** network as a startup option.

  This is preparatory work for a BIP 54 implementation, but may be useful separately.

ACKs for top commit:
  edilmedeiros:
    utACK 801e3bfe38
  achow101:
    ACK 801e3bfe38
  sedited:
    ACK 801e3bfe38
  instagibbs:
    ACK 801e3bfe38

Tree-SHA512: 10649dc9bbc70a830bb0c4b1c965de5bf2e6be1a6c2832bdf11e9248dacb4a1f60421b410d0284213e88de6c54218252ae5de423b4c6e659d10bab1cbe7e7e87
This commit is contained in:
Ava Chow
2026-06-03 13:53:24 -07:00
6 changed files with 149 additions and 81 deletions

View File

@@ -73,12 +73,41 @@ 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.
*/
class CMainParams : public CChainParams {
public:
CMainParams() {
CMainParams(const MainNetOptions& opts) {
m_chain_type = ChainType::MAIN;
consensus.signet_blocks = false;
consensus.signet_challenge.clear();
@@ -107,6 +136,8 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1815; // 90%
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].period = 2016;
ApplyDeploymentOptions(opts.dep_opts);
consensus.nMinimumChainWork = uint256{"0000000000000000000000000000000000000001128750f82f4c366153a3a030"};
consensus.defaultAssumeValid = uint256{"00000000000000000000ccebd6d74d9194d8dcdc1d177c478e094bfad51ba5ac"}; // 938343
@@ -203,7 +234,7 @@ public:
*/
class CTestNetParams : public CChainParams {
public:
CTestNetParams() {
CTestNetParams(const TestNetOptions& opts) {
m_chain_type = ChainType::TESTNET;
consensus.signet_blocks = false;
consensus.signet_challenge.clear();
@@ -230,6 +261,8 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1512; // 75%
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].period = 2016;
ApplyDeploymentOptions(opts.dep_opts);
consensus.nMinimumChainWork = uint256{"0000000000000000000000000000000000000000000017dde1c649f3708d14b6"};
consensus.defaultAssumeValid = uint256{"000000007a61e4230b28ac5cb6b5e5a0130de37ac1faf2f8987d2fa6505b67f4"}; // 4842348
@@ -304,7 +337,7 @@ public:
*/
class CTestNet4Params : public CChainParams {
public:
CTestNet4Params() {
CTestNet4Params(const TestNetOptions& opts) {
m_chain_type = ChainType::TESTNET4;
consensus.signet_blocks = false;
consensus.signet_challenge.clear();
@@ -330,6 +363,8 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1512; // 75%
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].period = 2016;
ApplyDeploymentOptions(opts.dep_opts);
consensus.nMinimumChainWork = uint256{"0000000000000000000000000000000000000000000009a0fe15d0177d086304"};
consensus.defaultAssumeValid = uint256{"0000000002368b1e4ee27e2e85676ae6f9f9e69579b29093e9a82c170bf7cf8a"}; // 123613
@@ -473,6 +508,8 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1815; // 90%
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].period = 2016;
ApplyDeploymentOptions(options.dep_opts);
// message start is defined as the first 4 bytes of the sha256d of the block script
HashWriter h{};
h << consensus.signet_challenge;
@@ -567,31 +604,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();
@@ -660,19 +673,19 @@ std::unique_ptr<const CChainParams> CChainParams::RegTest(const RegTestOptions&
return std::make_unique<const CRegTestParams>(options);
}
std::unique_ptr<const CChainParams> CChainParams::Main()
std::unique_ptr<const CChainParams> CChainParams::Main(const MainNetOptions& options)
{
return std::make_unique<const CMainParams>();
return std::make_unique<const CMainParams>(options);
}
std::unique_ptr<const CChainParams> CChainParams::TestNet()
std::unique_ptr<const CChainParams> CChainParams::TestNet(const TestNetOptions& options)
{
return std::make_unique<const CTestNetParams>();
return std::make_unique<const CTestNetParams>(options);
}
std::unique_ptr<const CChainParams> CChainParams::TestNet4()
std::unique_ptr<const CChainParams> CChainParams::TestNet4(const TestNetOptions& options)
{
return std::make_unique<const CTestNet4Params>();
return std::make_unique<const CTestNet4Params>(options);
}
std::vector<int> CChainParams::GetAvailableSnapshotHeights() const
@@ -691,8 +704,8 @@ std::optional<ChainType> GetNetworkForMagic(const MessageStartChars& message)
const auto mainnet_msg = CChainParams::Main()->MessageStart();
const auto testnet_msg = CChainParams::TestNet()->MessageStart();
const auto testnet4_msg = CChainParams::TestNet4()->MessageStart();
const auto regtest_msg = CChainParams::RegTest({})->MessageStart();
const auto signet_msg = CChainParams::SigNet({})->MessageStart();
const auto regtest_msg = CChainParams::RegTest()->MessageStart();
const auto signet_msg = CChainParams::SigNet()->MessageStart();
if (std::ranges::equal(message, mainnet_msg)) {
return ChainType::MAIN;