Skip to content

Commit e03abd4

Browse files
Merge pull request #6 from luke-jr/achow101_bip8-speedy-trial-0.21
Achow101 bip8 speedy trial 0.21
2 parents 21fc55f + bdafb8d commit e03abd4

17 files changed

+503
-300
lines changed

doc/bips.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.21.0**):
22

3-
* [`BIP 9`](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki): The changes allowing multiple soft-forks to be deployed in parallel have been implemented since **v0.12.1** ([PR #7575](https://github.com/bitcoin/bitcoin/pull/7575))
3+
* [`BIP 8`](https://github.com/bitcoin/bips/blob/master/bip-0008.mediawiki): The changes for parallel, rapid deployment based on block height miner activation have been implemented since **v0.21.1** ([PR #21392](https://github.com/bitcoin/bitcoin/pull/21392)). The UASF fallback with forced signaling (`LOT=true`) has not yet been implemented. The current implementation is the equivalent of `LOT=false`.
4+
* [`BIP 9`](https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki): The changes allowing multiple soft-forks to be deployed in parallel have been implemented since **v0.12.1** ([PR #7575](https://github.com/bitcoin/bitcoin/pull/7575)) Support was removed in **v0.21.1** ([PR #21392](https://github.com/bitcoin/bitcoin/pull/21392)).
45
* [`BIP 11`](https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki): Multisig outputs are standard since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
56
* [`BIP 13`](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki): The address format for P2SH addresses has been implemented since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
67
* [`BIP 14`](https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki): The subversion string is being used as User Agent since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).

doc/release-notes-21392.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Low-level changes
2+
=================
3+
4+
RPC
5+
---
6+
7+
* BIP 9 has been replaced with a partial implementation of BIP 8. This change is reflected in `getblockchaininfo` where references to BIP 9 have been replaced with references to BIP 8.

src/chainparams.cpp

+93-32
Original file line numberDiff line numberDiff line change
@@ -80,16 +80,18 @@ class CMainParams : public CChainParams {
8080
consensus.nPowTargetSpacing = 10 * 60;
8181
consensus.fPowAllowMinDifficultyBlocks = false;
8282
consensus.fPowNoRetargeting = false;
83-
consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016
83+
consensus.m_vbits_min_threshold = 1512; // 75%
8484
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
8585
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
86-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
87-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
86+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].startheight = Consensus::BIP9Deployment::NEVER_ACTIVE;
87+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].timeoutheight = Consensus::BIP9Deployment::NEVER_ACTIVE;
88+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1916; // 95% of 2016
8889

8990
// Deployment of Taproot (BIPs 340-342)
9091
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
91-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1199145601; // January 1, 2008
92-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1230767999; // December 31, 2008
92+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].startheight = Consensus::BIP9Deployment::NEVER_ACTIVE;
93+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].timeoutheight = Consensus::BIP9Deployment::NEVER_ACTIVE;
94+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].threshold = 1916; // 95% of 2016
9395

9496
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000001533efd8d716a517fe2c5008");
9597
consensus.defaultAssumeValid = uint256S("0x0000000000000000000b9d2ec5a352ecba0592946514a92f14319dc2b367fc72"); // 654683
@@ -193,16 +195,18 @@ class CTestNetParams : public CChainParams {
193195
consensus.nPowTargetSpacing = 10 * 60;
194196
consensus.fPowAllowMinDifficultyBlocks = true;
195197
consensus.fPowNoRetargeting = false;
196-
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
198+
consensus.m_vbits_min_threshold = 1512; // 75%
197199
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
198200
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
199-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
200-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
201+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].startheight = Consensus::BIP9Deployment::NEVER_ACTIVE;
202+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].timeoutheight = Consensus::BIP9Deployment::NEVER_ACTIVE;
203+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1512; // 75% of 2016
201204

202205
// Deployment of Taproot (BIPs 340-342)
203206
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
204-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1199145601; // January 1, 2008
205-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1230767999; // December 31, 2008
207+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].startheight = Consensus::BIP9Deployment::NEVER_ACTIVE;
208+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].timeoutheight = Consensus::BIP9Deployment::NEVER_ACTIVE;
209+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].threshold = 1512; // 75% of 2016
206210

207211
consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000001db6ec4ac88cf2272c6");
208212
consensus.defaultAssumeValid = uint256S("0x000000000000006433d1efec504c53ca332b64963c425395515b01977bd7b3b0"); // 1864000
@@ -322,18 +326,20 @@ class SigNetParams : public CChainParams {
322326
consensus.nPowTargetSpacing = 10 * 60;
323327
consensus.fPowAllowMinDifficultyBlocks = false;
324328
consensus.fPowNoRetargeting = false;
325-
consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016
329+
consensus.m_vbits_min_threshold = 1512; // 75%
326330
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
327331
consensus.MinBIP9WarningHeight = 0;
328332
consensus.powLimit = uint256S("00000377ae000000000000000000000000000000000000000000000000000000");
329333
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
330-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
331-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
334+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].startheight = Consensus::BIP9Deployment::NEVER_ACTIVE;
335+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].timeoutheight = Consensus::BIP9Deployment::NEVER_ACTIVE;
336+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1916; // 95% of 2016
332337

333338
// Activation of Taproot (BIPs 340-342)
334339
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
335-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
336-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
340+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].startheight = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
341+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].timeoutheight = Consensus::BIP9Deployment::NO_TIMEOUT;
342+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].threshold = 1916; // 95% of 2016
337343

338344
// message start is defined as the first 4 bytes of the sha256d of the block script
339345
CHashWriter h(SER_DISK, 0);
@@ -389,14 +395,16 @@ class CRegTestParams : public CChainParams {
389395
consensus.nPowTargetSpacing = 10 * 60;
390396
consensus.fPowAllowMinDifficultyBlocks = true;
391397
consensus.fPowNoRetargeting = true;
392-
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
398+
consensus.m_vbits_min_threshold = 108; // 75%
393399
consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
394400
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
395-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
396-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
401+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].startheight = 144;
402+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].timeoutheight = Consensus::BIP9Deployment::NO_TIMEOUT;
403+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 108; // 75% of 144
397404
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2;
398-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
399-
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
405+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].startheight = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
406+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].timeoutheight = Consensus::BIP9Deployment::NO_TIMEOUT;
407+
consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].threshold = 108; // 75% of 144
400408

401409
consensus.nMinimumChainWork = uint256{};
402410
consensus.defaultAssumeValid = uint256{};
@@ -449,14 +457,60 @@ class CRegTestParams : public CChainParams {
449457
/**
450458
* Allows modifying the Version Bits regtest parameters.
451459
*/
452-
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout)
460+
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int startheight, int timeoutheight, int min_activation_height)
453461
{
454-
consensus.vDeployments[d].nStartTime = nStartTime;
455-
consensus.vDeployments[d].nTimeout = nTimeout;
462+
consensus.vDeployments[d].startheight = startheight;
463+
consensus.vDeployments[d].timeoutheight = timeoutheight;
464+
consensus.vDeployments[d].m_min_activation_height = min_activation_height;
456465
}
457466
void UpdateActivationParametersFromArgs(const ArgsManager& args);
458467
};
459468

469+
bool CheckVBitsHeights(std::string& error, const Consensus::Params& consensus, int startheight, int timeoutheight, int min_activation_height)
470+
{
471+
// Special always or never active cases
472+
if ((startheight == Consensus::BIP9Deployment::NEVER_ACTIVE && timeoutheight == Consensus::BIP9Deployment::NEVER_ACTIVE)
473+
|| startheight == Consensus::BIP9Deployment::ALWAYS_ACTIVE) {
474+
return true;
475+
}
476+
if ((startheight == Consensus::BIP9Deployment::NEVER_ACTIVE && timeoutheight != Consensus::BIP9Deployment::NEVER_ACTIVE)
477+
|| (startheight != Consensus::BIP9Deployment::NEVER_ACTIVE && timeoutheight == Consensus::BIP9Deployment::NEVER_ACTIVE)) {
478+
error = strprintf("When one of startheight or timeoutheight is %d, both must be %d", int(Consensus::BIP9Deployment::NEVER_ACTIVE), int(Consensus::BIP9Deployment::NEVER_ACTIVE));
479+
return false;
480+
}
481+
482+
// Actual params must be on retarget block
483+
if (startheight < 0) {
484+
error = strprintf("Invalid startheight (%d), cannot be negative (except for never or always active special cases)", startheight);
485+
return false;
486+
}
487+
if (timeoutheight < 0) {
488+
error = strprintf("Invalid timeoutheight (%d), cannot be negative (except for never or always active special cases)", timeoutheight);
489+
return false;
490+
}
491+
if (startheight % consensus.nMinerConfirmationWindow != 0) {
492+
error = strprintf("Invalid startheight (%d), must be a multiple of %d", startheight, consensus.nMinerConfirmationWindow);
493+
return false;
494+
}
495+
if (timeoutheight != Consensus::BIP9Deployment::NO_TIMEOUT && timeoutheight % consensus.nMinerConfirmationWindow != 0) {
496+
error = strprintf("Invalid timeoutheight (%d), must be a multiple of %d", timeoutheight, consensus.nMinerConfirmationWindow);
497+
return false;
498+
}
499+
if (min_activation_height < 0) {
500+
error = strprintf("Invalid minimum activation height (%d), cannot be negative", min_activation_height);
501+
return false;
502+
}
503+
if (min_activation_height % consensus.nMinerConfirmationWindow != 0) {
504+
error = strprintf("Invalid minimum activation height (%d), must be a multiple of %d", min_activation_height, consensus.nMinerConfirmationWindow);
505+
return false;
506+
}
507+
if (timeoutheight < startheight + (2 * (int)consensus.nMinerConfirmationWindow)) {
508+
error = strprintf("Invalid timeoutheight (%d), must be at least two periods greater than the startheight (%d)", timeoutheight, startheight);
509+
return false;
510+
}
511+
return true;
512+
}
513+
460514
void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args)
461515
{
462516
if (args.IsArgSet("-segwitheight")) {
@@ -475,22 +529,29 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args)
475529
for (const std::string& strDeployment : args.GetArgs("-vbparams")) {
476530
std::vector<std::string> vDeploymentParams;
477531
boost::split(vDeploymentParams, strDeployment, boost::is_any_of(":"));
478-
if (vDeploymentParams.size() != 3) {
479-
throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end");
532+
if (vDeploymentParams.size() < 3 || vDeploymentParams.size() > 4) {
533+
throw std::runtime_error("Version bits parameters malformed, expecting deployment:@startheight:@timeoutheight[:@min_activation_height]");
534+
}
535+
int32_t startheight = 0, timeoutheight = 0, min_activation_height = 0;
536+
if (vDeploymentParams[1].empty() || vDeploymentParams[1].front() != '@' || !ParseInt32(vDeploymentParams[1].substr(1), &startheight)) {
537+
throw std::runtime_error(strprintf("Invalid startheight (%s)", vDeploymentParams[1]));
538+
}
539+
if (vDeploymentParams[2].empty() || vDeploymentParams[2].front() != '@' || !ParseInt32(vDeploymentParams[2].substr(1), &timeoutheight)) {
540+
throw std::runtime_error(strprintf("Invalid timeoutheight (%s)", vDeploymentParams[2]));
480541
}
481-
int64_t nStartTime, nTimeout;
482-
if (!ParseInt64(vDeploymentParams[1], &nStartTime)) {
483-
throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
542+
if (vDeploymentParams.size() == 4 && (vDeploymentParams[3].front() != '@' || !ParseInt32(vDeploymentParams[3].substr(1), &min_activation_height))) {
543+
throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3]));
484544
}
485-
if (!ParseInt64(vDeploymentParams[2], &nTimeout)) {
486-
throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2]));
545+
std::string error;
546+
if (!CheckVBitsHeights(error, consensus, startheight, timeoutheight, min_activation_height)) {
547+
throw std::runtime_error(error);
487548
}
488549
bool found = false;
489550
for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
490551
if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) {
491-
UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout);
552+
UpdateVersionBitsParameters(Consensus::DeploymentPos(j), startheight, timeoutheight, min_activation_height);
492553
found = true;
493-
LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld\n", vDeploymentParams[0], nStartTime, nTimeout);
554+
LogPrintf("Setting version bits activation parameters for %s to startheight=%ld, timeoutheight=%ld, min_activation_height=%ld\n", vDeploymentParams[0], startheight, timeoutheight, min_activation_height);
494555
break;
495556
}
496557
}

src/chainparams.h

+3
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,7 @@ const CChainParams &Params();
133133
*/
134134
void SelectParams(const std::string& chain);
135135

136+
/** Check that the given heights make sense */
137+
bool CheckVBitsHeights(std::string& error, const Consensus::Params& consensus, int startheight, int timeoutheight, int min_activation_height);
138+
136139
#endif // BITCOIN_CHAINPARAMS_H

src/chainparamsbase.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
2323
"This is intended for regression testing tools and app development. Equivalent to -chain=regtest.", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
2424
argsman.AddArg("-segwitheight=<n>", "Set the activation height of segwit. -1 to disable. (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
2525
argsman.AddArg("-testnet", "Use the test chain. Equivalent to -chain=test.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
26-
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);
26+
argsman.AddArg("-vbparams=deployment:@startheight:@timeoutheight[:@min_activation_height]", "Use given start, timeout, and minimum activation heights for specified version bits deployment (regtest-only). For an always active deployment, use @-1:@-1. For a never active deployment, use @-2:@-2.", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
2727
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);
2828
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);
2929
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);

0 commit comments

Comments
 (0)