Skip to content

Commit 5191138

Browse files
fanquakeknst
authored andcommitted
Merge bitcoin#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 bitcoin#21380. ACKs for top commit: instagibbs: tACK 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
1 parent ecade9b commit 5191138

18 files changed

+337
-178
lines changed

src/chainparams.cpp

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -200,11 +200,12 @@ class CMainParams : public CChainParams {
200200
consensus.fPowNoRetargeting = false;
201201
consensus.nPowKGWHeight = 15200;
202202
consensus.nPowDGWHeight = 34140;
203-
consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016
203+
consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016
204204
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
205205
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
206-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
207-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
206+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
207+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
208+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
208209

209210
consensus.vDeployments[Consensus::DEPLOYMENT_V20].bit = 9;
210211
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nStartTime = 1700006400; // November 15, 2023
@@ -403,8 +404,9 @@ class CTestNetParams : public CChainParams {
403404
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
404405
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
405406
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
406-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
407-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
407+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
408+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
409+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
408410

409411
consensus.vDeployments[Consensus::DEPLOYMENT_V20].bit = 9;
410412
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nStartTime = 1693526400; // Friday, September 1, 2023 0:00:00
@@ -577,8 +579,9 @@ class CDevNetParams : public CChainParams {
577579
consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
578580
consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
579581
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
580-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
581-
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008
582+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE;
583+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
584+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
582585

583586
consensus.vDeployments[Consensus::DEPLOYMENT_V20].bit = 9;
584587
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nStartTime = 1661990400; // Sep 1st, 2022
@@ -815,9 +818,11 @@ class CRegTestParams : public CChainParams {
815818
consensus.nPowDGWHeight = 34140; // same as mainnet
816819
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
817820
consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
821+
818822
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
819823
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
820824
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
825+
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay
821826

822827
consensus.vDeployments[Consensus::DEPLOYMENT_V20].bit = 9;
823828
consensus.vDeployments[Consensus::DEPLOYMENT_V20].nStartTime = 0;
@@ -939,10 +944,11 @@ class CRegTestParams : public CChainParams {
939944
/**
940945
* Allows modifying the Version Bits regtest parameters.
941946
*/
942-
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int64_t nWindowSize, int64_t nThresholdStart, int64_t nThresholdMin, int64_t nFalloffCoeff, int64_t nUseEHF)
947+
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int min_activation_height, int64_t nWindowSize, int64_t nThresholdStart, int64_t nThresholdMin, int64_t nFalloffCoeff, int64_t nUseEHF)
943948
{
944949
consensus.vDeployments[d].nStartTime = nStartTime;
945950
consensus.vDeployments[d].nTimeout = nTimeout;
951+
consensus.vDeployments[d].min_activation_height = min_activation_height;
946952
if (nWindowSize != -1) {
947953
consensus.vDeployments[d].nWindowSize = nWindowSize;
948954
}
@@ -1022,45 +1028,50 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args)
10221028

10231029
for (const std::string& strDeployment : args.GetArgs("-vbparams")) {
10241030
std::vector<std::string> vDeploymentParams = SplitString(strDeployment, ':');
1025-
if (vDeploymentParams.size() != 3 && vDeploymentParams.size() != 5 && vDeploymentParams.size() != 8) {
1031+
if (vDeploymentParams.size() != 3 && vDeploymentParams.size() != 4 && vDeploymentParams.size() != 6 && vDeploymentParams.size() != 9) {
10261032
throw std::runtime_error("Version bits parameters malformed, expecting "
10271033
"<deployment>:<start>:<end> or "
1028-
"<deployment>:<start>:<end>:<window>:<threshold> or "
1029-
"<deployment>:<start>:<end>:<window>:<thresholdstart>:<thresholdmin>:<falloffcoeff>:<useehf>");
1034+
"<deployment>:<start>:<end>:<min_activation_height> or "
1035+
"<deployment>:<start>:<end>:<min_activation_height>:<window>:<threshold> or "
1036+
"<deployment>:<start>:<end>:<min_activation_height>:<window>:<thresholdstart>:<thresholdmin>:<falloffcoeff>:<useehf>");
10301037
}
10311038
int64_t nStartTime, nTimeout, nWindowSize = -1, nThresholdStart = -1, nThresholdMin = -1, nFalloffCoeff = -1, nUseEHF = -1;
1039+
int min_activation_height = 0;
10321040
if (!ParseInt64(vDeploymentParams[1], &nStartTime)) {
10331041
throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1]));
10341042
}
10351043
if (!ParseInt64(vDeploymentParams[2], &nTimeout)) {
10361044
throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2]));
10371045
}
1038-
if (vDeploymentParams.size() >= 5) {
1039-
if (!ParseInt64(vDeploymentParams[3], &nWindowSize)) {
1040-
throw std::runtime_error(strprintf("Invalid nWindowSize (%s)", vDeploymentParams[3]));
1046+
if (vDeploymentParams.size() >= 4 && !ParseInt32(vDeploymentParams[3], &min_activation_height)) {
1047+
throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3]));
1048+
}
1049+
if (vDeploymentParams.size() >= 6) {
1050+
if (!ParseInt64(vDeploymentParams[4], &nWindowSize)) {
1051+
throw std::runtime_error(strprintf("Invalid nWindowSize (%s)", vDeploymentParams[4]));
10411052
}
1042-
if (!ParseInt64(vDeploymentParams[4], &nThresholdStart)) {
1043-
throw std::runtime_error(strprintf("Invalid nThresholdStart (%s)", vDeploymentParams[4]));
1053+
if (!ParseInt64(vDeploymentParams[5], &nThresholdStart)) {
1054+
throw std::runtime_error(strprintf("Invalid nThresholdStart (%s)", vDeploymentParams[5]));
10441055
}
10451056
}
1046-
if (vDeploymentParams.size() == 8) {
1047-
if (!ParseInt64(vDeploymentParams[5], &nThresholdMin)) {
1048-
throw std::runtime_error(strprintf("Invalid nThresholdMin (%s)", vDeploymentParams[5]));
1057+
if (vDeploymentParams.size() == 9) {
1058+
if (!ParseInt64(vDeploymentParams[6], &nThresholdMin)) {
1059+
throw std::runtime_error(strprintf("Invalid nThresholdMin (%s)", vDeploymentParams[6]));
10491060
}
1050-
if (!ParseInt64(vDeploymentParams[6], &nFalloffCoeff)) {
1051-
throw std::runtime_error(strprintf("Invalid nFalloffCoeff (%s)", vDeploymentParams[6]));
1061+
if (!ParseInt64(vDeploymentParams[7], &nFalloffCoeff)) {
1062+
throw std::runtime_error(strprintf("Invalid nFalloffCoeff (%s)", vDeploymentParams[7]));
10521063
}
1053-
if (!ParseInt64(vDeploymentParams[7], &nUseEHF)) {
1054-
throw std::runtime_error(strprintf("Invalid nUseEHF (%s)", vDeploymentParams[7]));
1064+
if (!ParseInt64(vDeploymentParams[8], &nUseEHF)) {
1065+
throw std::runtime_error(strprintf("Invalid nUseEHF (%s)", vDeploymentParams[8]));
10551066
}
10561067
}
10571068
bool found = false;
10581069
for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) {
10591070
if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) {
1060-
UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, nWindowSize, nThresholdStart, nThresholdMin, nFalloffCoeff, nUseEHF);
1071+
UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, min_activation_height, nWindowSize, nThresholdStart, nThresholdMin, nFalloffCoeff, nUseEHF);
10611072
found = true;
1062-
LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, window=%ld, thresholdstart=%ld, thresholdmin=%ld, falloffcoeff=%ld, useehf=%ld\n",
1063-
vDeploymentParams[0], nStartTime, nTimeout, nWindowSize, nThresholdStart, nThresholdMin, nFalloffCoeff, nUseEHF);
1073+
LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, min_activation_height=%ld, window=%ld, thresholdstart=%ld, thresholdmin=%ld, falloffcoeff=%ld, useehf=%ld\n",
1074+
vDeploymentParams[0], nStartTime, nTimeout, min_activation_height, nWindowSize, nThresholdStart, nThresholdMin, nFalloffCoeff, nUseEHF);
10641075
break;
10651076
}
10661077
}

src/chainparamsbase.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
3737
argsman.AddArg("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. "
3838
"This is intended for regression testing tools and app development. Equivalent to -chain=regtest", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
3939
argsman.AddArg("-testnet", "Use the test chain. Equivalent to -chain=test", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
40-
argsman.AddArg("-vbparams=<deployment>:<start>:<end>(:<window>:<threshold/thresholdstart>(:<thresholdmin>:<falloffcoeff>:<mnactivation>))",
41-
"Use given start/end times for specified version bits deployment (regtest-only). "
40+
argsman.AddArg("-vbparams=<deployment>:<start>:<end>(:min_activation_height(:<window>:<threshold/thresholdstart>(:<thresholdmin>:<falloffcoeff>:<mnactivation>)))",
41+
"Use given start/end times and min_activation_height for specified version bits deployment (regtest-only). "
4242
"Specifying window, threshold/thresholdstart, thresholdmin, falloffcoeff and mnactivation is optional.", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
4343

4444
}

src/consensus/params.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ struct BIP9Deployment {
5151
int64_t nStartTime;
5252
/** Timeout/expiry MedianTime for the deployment attempt. */
5353
int64_t nTimeout;
54+
/** If lock in occurs, delay activation until at least this block
55+
* height. Note that activation will only occur on a retarget
56+
* boundary.
57+
*/
58+
int min_activation_height{0};
5459
/** The number of past blocks (including the block under consideration) to be taken into account for locking in a fork. */
5560
int64_t nWindowSize{0};
5661
/** A starting number of blocks, in the range of 1..nWindowSize, which must signal for a fork in order to lock it in. */
@@ -73,6 +78,11 @@ struct BIP9Deployment {
7378
* process (which takes at least 3 BIP9 intervals). Only tests that specifically test the
7479
* behaviour during activation cannot use this. */
7580
static constexpr int64_t ALWAYS_ACTIVE = -1;
81+
82+
/** Special value for nStartTime indicating that the deployment is never active.
83+
* This is useful for integrating the code changes for a new feature
84+
* prior to deploying it on some or all networks. */
85+
static constexpr int64_t NEVER_ACTIVE = -2;
7686
};
7787

7888
/**

src/evo/mnhftx.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ CMNHFManager::~CMNHFManager()
5555
CMNHFManager::Signals CMNHFManager::GetSignalsStage(const CBlockIndex* const pindexPrev)
5656
{
5757
Signals signals = GetForBlock(pindexPrev);
58+
if (pindexPrev == nullptr) return {};
5859
const int height = pindexPrev->nHeight + 1;
5960
for (auto it = signals.begin(); it != signals.end(); ) {
6061
bool found{false};

src/rpc/blockchain.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,10 +1636,8 @@ static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, UniValue&
16361636
static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, const std::unordered_map<uint8_t, int>& signals, UniValue& softforks, const Consensus::Params& consensusParams, Consensus::DeploymentPos id)
16371637
{
16381638
// For BIP9 deployments.
1639-
// Deployments (e.g. testdummy) with timeout value before Jan 1, 2009 are hidden.
1640-
// A timeout value of 0 guarantees a softfork will never be activated.
1641-
// This is used when merging logic to implement a proposed softfork without a specified deployment schedule.
1642-
if (consensusParams.vDeployments[id].nTimeout <= 1230768000) return;
1639+
// Deployments that are never active are hidden.
1640+
if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return;
16431641

16441642
UniValue bip9(UniValue::VOBJ);
16451643
const ThresholdState thresholdState = g_versionbitscache.State(active_chain_tip, consensusParams, id);
@@ -1676,6 +1674,7 @@ static void SoftForkDescPushBack(const CBlockIndex* active_chain_tip, const std:
16761674
else if (ThresholdState::LOCKED_IN == thresholdState) {
16771675
bip9.pushKV("activation_height", since_height + static_cast<int>(consensusParams.vDeployments[id].nWindowSize));
16781676
}
1677+
bip9.pushKV("min_activation_height", consensusParams.vDeployments[id].min_activation_height);
16791678

16801679
UniValue rv(UniValue::VOBJ);
16811680
rv.pushKV("type", "bip9");
@@ -1725,6 +1724,7 @@ RPCHelpMan getblockchaininfo()
17251724
{RPCResult::Type::NUM, "ehf_height", /* optional */ true, "the minimum height when miner's signals for the deployment matter. Below this height miner signaling cannot trigger hard fork lock-in. Not specified for non-EHF forks"},
17261725
{RPCResult::Type::NUM, "since", "height of the first block to which the status applies"},
17271726
{RPCResult::Type::NUM, "activation_height", "expected activation height for this softfork (only for \"locked_in\" status)"},
1727+
{RPCResult::Type::NUM, "min_activation_height", "minimum height of blocks for which the rules may be enforced"},
17281728
{RPCResult::Type::OBJ, "statistics", "numeric statistics about BIP9 signalling for a softfork",
17291729
{
17301730
{RPCResult::Type::NUM, "period", "the length in blocks of the BIP9 signalling period"},

src/test/block_reward_reallocation_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ using SimpleUTXOMap = std::map<COutPoint, std::pair<int, CAmount>>;
4141
struct TestChainBRRBeforeActivationSetup : public TestChainSetup
4242
{
4343
// Force fast DIP3 activation
44-
TestChainBRRBeforeActivationSetup() : TestChainSetup(497, {"-dip3params=30:50", "-vbparams=mn_rr:0:999999999999:20:16:12:5:1"}) {}
44+
TestChainBRRBeforeActivationSetup() : TestChainSetup(497, {"-dip3params=30:50", "-vbparams=mn_rr:0:999999999999:0:20:16:12:5:1"}) {}
4545
};
4646

4747
static SimpleUTXOMap BuildSimpleUtxoMap(const std::vector<CTransactionRef>& txs)

src/test/dynamic_activation_thresholds_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ static constexpr int threshold(int attempt)
3636

3737
struct TestChainDATSetup : public TestChainSetup
3838
{
39-
TestChainDATSetup() : TestChainSetup(window - 2, {"-vbparams=testdummy:0:999999999999:100:80:60:5:0"}) {}
39+
TestChainDATSetup() : TestChainSetup(window - 2, {"-vbparams=testdummy:0:999999999999:0:100:80:60:5:0"}) {}
4040

4141
void signal(int num_blocks, bool expected_lockin)
4242
{

0 commit comments

Comments
 (0)