Skip to content

Commit 2cd834e

Browse files
committed
Merge #21377: Speedy trial support for versionbits
ffe33df chainparams: drop versionbits threshold to 90% for mainnnet and signet (Anthony Towns) f054f6b versionbits: simplify state transitions (Anthony Towns) 55ac5f5 versionbits: Add explicit NEVER_ACTIVE deployments (Anthony Towns) dd07e6d fuzz: test versionbits delayed activation (Anthony Towns) dd85d54 tests: test versionbits delayed activation (Anthony Towns) 73d4a70 versionbits: Add support for delayed activation (Anthony Towns) 9e6b65f tests: clean up versionbits test (Anthony Towns) 5932744 tests: test ComputeBlockVersion for all deployments (Anthony Towns) 63879f0 tests: pull ComputeBlockVersion test into its own function (Anthony Towns) Pull request description: BIP9-based implementation of "speedy trial" activation specification, see https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-March/018583.html Edge cases are tested by fuzzing added in #21380. ACKs for top commit: instagibbs: tACK bitcoin/bitcoin@ffe33df jnewbery: utACK ffe33df MarcoFalke: review ACK ffe33df 💈 achow101: re-ACK ffe33df gmaxwell: ACK ffe33df benthecarman: ACK ffe33df Sjors: ACK ffe33df jonatack: Initial approach ACK ffe33df after a first pass of review, building and testing each commit, mostly looking at the changes and diffs. Will do a more high-level review iteration. A few minor comments follow to pick/choose/ignore. ariard: Code Review ACK ffe33df Tree-SHA512: f79a7146b2450057ee92155cbbbcec12cd64334236d9239c6bd7d31b32eec145a9781c320f178da7b44ababdb8808b84d9d22a40e0851e229ba6d224e3be747c
2 parents 7fcf53f + ffe33df commit 2cd834e

File tree

9 files changed

+311
-158
lines changed

9 files changed

+311
-158
lines changed

src/chainparams.cpp

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,18 @@ class CMainParams : public CChainParams {
7878
consensus.nPowTargetSpacing = 10 * 60;
7979
consensus.fPowAllowMinDifficultyBlocks = false;
8080
consensus.fPowNoRetargeting = false;
81-
consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016
81+
consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016
8282
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
8383
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
84-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
85-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
84+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
85+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
86+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
8687

8788
// Deployment of Taproot (BIPs 340-342)
8889
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
89-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1199145601; // January 1, 2008
90-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1230767999; // December 31, 2008
90+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
91+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
92+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
9193

9294
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000001533efd8d716a517fe2c5008");
9395
consensus.defaultAssumeValid = uint256S("0x0000000000000000000b9d2ec5a352ecba0592946514a92f14319dc2b367fc72"); // 654683
@@ -198,13 +200,15 @@ class CTestNetParams : public CChainParams {
198200
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
199201
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
200202
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
201-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
202-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
203+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
204+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
205+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
203206

204207
// Deployment of Taproot (BIPs 340-342)
205208
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
206-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1199145601; // January 1, 2008
207-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1230767999; // December 31, 2008
209+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
210+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
211+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
208212

209213
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000001db6ec4ac88cf2272c6");
210214
consensus.defaultAssumeValid = uint256S("0x000000000000006433d1efec504c53ca332b64963c425395515b01977bd7b3b0"); // 1864000
@@ -328,18 +332,20 @@ class SigNetParams : public CChainParams {
328332
consensus.nPowTargetSpacing = 10 * 60;
329333
consensus.fPowAllowMinDifficultyBlocks = false;
330334
consensus.fPowNoRetargeting = false;
331-
consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016
335+
consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016
332336
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
333337
consensus.MinBIP9WarningHeight = 0;
334338
consensus.powLimit = uint256S("00000377ae000000000000000000000000000000000000000000000000000000");
335339
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
336-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
337-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
340+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
341+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
342+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
338343

339344
// Activation of Taproot (BIPs 340-342)
340345
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
341346
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
342347
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
348+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
343349

344350
// message start is defined as the first 4 bytes of the sha256d of the block script
345351
CHashWriter h(SER_DISK, 0);
@@ -398,12 +404,16 @@ class CRegTestParams : public CChainParams {
398404
consensus.fPowNoRetargeting = true;
399405
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
400406
consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
407+
401408
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
402409
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
403410
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
411+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
412+
404413
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
405414
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
406415
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
416+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay
407417

408418
consensus.nMinimumChainWork = uint256{};
409419
consensus.defaultAssumeValid = uint256{};
@@ -467,10 +477,11 @@ class CRegTestParams : public CChainParams {
467477
/**
468478
* Allows modifying the Version Bits regtest parameters.
469479
*/
470-
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
480+
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int min_activation_height)
471481
{
472482
consensus.vDeployments[d].nStartTime = nStartTime;
473483
consensus.vDeployments[d].nTimeout = nTimeout;
484+
consensus.vDeployments[d].min_activation_height = min_activation_height;
474485
}
475486
void UpdateActivationParametersFromArgs(const ArgsManager& args);
476487
};
@@ -493,22 +504,26 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args)
493504
for (const std::string& strDeployment : args.GetArgs("-vbparams")) {
494505
std::vector<std::string> vDeploymentParams;
495506
boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
496-
if (vDeploymentParams.size() != 3) {
497-
throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end");
507+
if (vDeploymentParams.size() < 3 || 4 < vDeploymentParams.size()) {
508+
throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:min_activation_height]");
498509
}
499510
int64_t nStartTime, nTimeout;
511+
int min_activation_height = 0;
500512
if (!ParseInt64(vDeploymentParams[1], &nStartTime)) {
501513
throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
502514
}
503515
if (!ParseInt64(vDeploymentParams[2], &nTimeout)) {
504516
throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2]));
505517
}
518+
if (vDeploymentParams.size() >= 4 && !ParseInt32(vDeploymentParams[3], &min_activation_height)) {
519+
throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3]));
520+
}
506521
bool found = false;
507522
for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
508523
if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) {
509-
UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout);
524+
UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, min_activation_height);
510525
found = true;
511-
LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout);
526+
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);
512527
break;
513528
}
514529
}

src/chainparamsbase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
2222
"This is intended for regression testing tools and app development. Equivalent to -chain=regtest.", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
2323
argsman.AddArg("-segwitheight=<n>", "Set the activation height of segwit. -1 to disable. (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
2424
argsman.AddArg("-testnet", "Use the test chain. Equivalent to -chain=test.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
25-
argsman.AddArg("-vbparams=deployment:start:end", "Use given start/end times for specified version bits deployment (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
25+
argsman.AddArg("-vbparams=deployment:start:end[:min_activation_height]", "Use given start/end times and min_activation_height for specified version bits deployment (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
2626
argsman.AddArg("-signet", "Use the signet chain. Equivalent to -chain=signet. Note that the network is defined by the -signetchallenge parameter", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
2727
argsman.AddArg("-signetchallenge", "Blocks must satisfy the given script to be considered valid (only for signet networks; defaults to the global default signet test network challenge)", ArgsManager::ALLOW_STRING, OptionsCategory::CHAINPARAMS);
2828
argsman.AddArg("-signetseednode", "Specify a seed node for the signet network, in the hostname[:port] format, e.g. sig.net:1234 (may be used multiple times to specify multiple seed nodes; defaults to the global default signet test network seed node(s))", ArgsManager::ALLOW_STRING, OptionsCategory::CHAINPARAMS);

src/consensus/params.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ struct BIP9Deployment {
2929
int64_t nStartTime;
3030
/** Timeout/expiry MedianTime for the deployment attempt. */
3131
int64_t nTimeout;
32+
/** If lock in occurs, delay activation until at least this block
33+
* height. Note that activation will only occur on a retarget
34+
* boundary.
35+
*/
36+
int min_activation_height{0};
3237

3338
/** Constant for nTimeout very far in the future. */
3439
static constexpr int64_t NO_TIMEOUT = std::numeric_limits<int64_t>::max();
@@ -38,6 +43,11 @@ struct BIP9Deployment {
3843
* process (which takes at least 3 BIP9 intervals). Only tests that specifically test the
3944
* behaviour during activation cannot use this. */
4045
static constexpr int64_t ALWAYS_ACTIVE = -1;
46+
47+
/** Special value for nStartTime indicating that the deployment is never active.
48+
* This is useful for integrating the code changes for a new feature
49+
* prior to deploying it on some or all networks. */
50+
static constexpr int64_t NEVER_ACTIVE = -2;
4151
};
4252

4353
/**

src/rpc/blockchain.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,10 +1228,8 @@ static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name,
12281228
static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
12291229
{
12301230
// For BIP9 deployments.
1231-
// Deployments (e.g. testdummy) with timeout value before Jan 1, 2009 are hidden.
1232-
// A timeout value of 0 guarantees a softfork will never be activated.
1233-
// This is used when merging logic to implement a proposed softfork without a specified deployment schedule.
1234-
if (consensusParams.vDeployments[id].nTimeout <= 1230768000) return;
1231+
// Deployments that are never active are hidden.
1232+
if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
12351233

12361234
UniValue bip9(UniValue::VOBJ);
12371235
const ThresholdState thresholdState = VersionBitsState(::ChainActive().Tip(), consensusParams, id, versionbitscache);
@@ -1261,6 +1259,7 @@ static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &nam
12611259
statsUV.pushKV("possible", statsStruct.possible);
12621260
bip9.pushKV("statistics", statsUV);
12631261
}
1262+
bip9.pushKV("min_activation_height", consensusParams.vDeployments[id].min_activation_height);
12641263

12651264
UniValue rv(UniValue::VOBJ);
12661265
rv.pushKV("type", "bip9");
@@ -1307,6 +1306,7 @@ RPCHelpMan getblockchaininfo()
13071306
{RPCResult::Type::NUM_TIME, "start_time", "the minimum median time past of a block at which the bit gains its meaning"},
13081307
{RPCResult::Type::NUM_TIME, "timeout", "the median time past of a block at which the deployment is considered failed if not yet locked in"},
13091308
{RPCResult::Type::NUM, "since", "height of the first block to which the status applies"},
1309+
{RPCResult::Type::NUM, "min_activation_height", "minimum height of blocks for which the rules may be enforced"},
13101310
{RPCResult::Type::OBJ, "statistics", "numeric statistics about BIP9 signalling for a softfork (only for \"started\" status)",
13111311
{
13121312
{RPCResult::Type::NUM, "period", "the length in blocks of the BIP9 signalling period"},

0 commit comments

Comments
 (0)