diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/chainparams.cpp | 20 | ||||
-rw-r--r-- | src/consensus/params.h | 5 | ||||
-rw-r--r-- | src/rpc/blockchain.cpp | 6 | ||||
-rw-r--r-- | src/test/fuzz/versionbits.cpp | 27 | ||||
-rw-r--r-- | src/test/versionbits_tests.cpp | 24 | ||||
-rw-r--r-- | src/versionbits.cpp | 7 |
6 files changed, 48 insertions, 41 deletions
diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 7e2c2ac7cf..318b5c9a71 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -81,14 +81,14 @@ public: consensus.nRuleChangeActivationThreshold = 1916; // 95% of 2016 consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay // Deployment of Taproot (BIPs 340-342) consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1199145601; // January 1, 2008 - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1230767999; // December 31, 2008 + consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000001533efd8d716a517fe2c5008"); @@ -200,14 +200,14 @@ public: consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay // Deployment of Taproot (BIPs 340-342) consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1199145601; // January 1, 2008 - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1230767999; // December 31, 2008 + consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000000001db6ec4ac88cf2272c6"); @@ -337,8 +337,8 @@ public: consensus.MinBIP9WarningHeight = 0; consensus.powLimit = uint256S("00000377ae000000000000000000000000000000000000000000000000000000"); consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008 - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008 + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE; + consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay // Activation of Taproot (BIPs 340-342) diff --git a/src/consensus/params.h b/src/consensus/params.h index 705205c95b..28c95e0884 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -43,6 +43,11 @@ struct BIP9Deployment { * process (which takes at least 3 BIP9 intervals). Only tests that specifically test the * behaviour during activation cannot use this. */ static constexpr int64_t ALWAYS_ACTIVE = -1; + + /** Special value for nStartTime indicating that the deployment is never active. + * This is useful for integrating the code changes for a new feature + * prior to deploying it on some or all networks. */ + static constexpr int64_t NEVER_ACTIVE = -2; }; /** diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index acf2f5d6b4..1130a384e5 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1225,10 +1225,8 @@ static void BuriedForkDescPushBack(UniValue& softforks, const std::string &name, static void BIP9SoftForkDescPushBack(UniValue& softforks, const std::string &name, const Consensus::Params& consensusParams, Consensus::DeploymentPos id) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { // For BIP9 deployments. - // Deployments (e.g. testdummy) with timeout value before Jan 1, 2009 are hidden. - // A timeout value of 0 guarantees a softfork will never be activated. - // This is used when merging logic to implement a proposed softfork without a specified deployment schedule. - if (consensusParams.vDeployments[id].nTimeout <= 1230768000) return; + // Deployments that are never active are hidden. + if (consensusParams.vDeployments[id].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return; UniValue bip9(UniValue::VOBJ); const ThresholdState thresholdState = VersionBitsState(::ChainActive().Tip(), consensusParams, id, versionbitscache); diff --git a/src/test/fuzz/versionbits.cpp b/src/test/fuzz/versionbits.cpp index 11640d1ee9..4177323233 100644 --- a/src/test/fuzz/versionbits.cpp +++ b/src/test/fuzz/versionbits.cpp @@ -163,13 +163,12 @@ FUZZ_TARGET_INIT(versionbits, initialize) } else { if (fuzzed_data_provider.ConsumeBool()) { start_time = Consensus::BIP9Deployment::ALWAYS_ACTIVE; - timeout = Consensus::BIP9Deployment::NO_TIMEOUT; always_active_test = true; } else { - start_time = 1199145601; // January 1, 2008 - timeout = 1230767999; // December 31, 2008 + start_time = Consensus::BIP9Deployment::NEVER_ACTIVE; never_active_test = true; } + timeout = fuzzed_data_provider.ConsumeBool() ? Consensus::BIP9Deployment::NO_TIMEOUT : fuzzed_data_provider.ConsumeIntegral<int64_t>(); } int min_activation = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, period * max_periods); @@ -323,7 +322,7 @@ FUZZ_TARGET_INIT(versionbits, initialize) assert(exp_state == ThresholdState::ACTIVE || exp_state == ThresholdState::LOCKED_IN); break; case ThresholdState::FAILED: - assert(current_block->GetMedianTimePast() >= checker.m_end); + assert(never_active_test || current_block->GetMedianTimePast() >= checker.m_end); assert(exp_state != ThresholdState::LOCKED_IN && exp_state != ThresholdState::ACTIVE); break; default: @@ -335,26 +334,20 @@ FUZZ_TARGET_INIT(versionbits, initialize) assert(state == ThresholdState::ACTIVE || state == ThresholdState::FAILED); } - // "always active" has additional restrictions if (always_active_test) { + // "always active" has additional restrictions assert(state == ThresholdState::ACTIVE); assert(exp_state == ThresholdState::ACTIVE); assert(since == 0); + } else if (never_active_test) { + // "never active" does too + assert(state == ThresholdState::FAILED); + assert(exp_state == ThresholdState::FAILED); + assert(since == 0); } else { - // except for always active, the initial state is always DEFINED + // for signalled deployments, the initial state is always DEFINED assert(since > 0 || state == ThresholdState::DEFINED); assert(exp_since > 0 || exp_state == ThresholdState::DEFINED); } - - // "never active" does too - if (never_active_test) { - assert(state == ThresholdState::FAILED); - assert(since == period); - if (exp_since == 0) { - assert(exp_state == ThresholdState::DEFINED); - } else { - assert(exp_state == ThresholdState::FAILED); - } - } } } // namespace diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp index 1ce31c9af9..80072eff9c 100644 --- a/src/test/versionbits_tests.cpp +++ b/src/test/versionbits_tests.cpp @@ -59,8 +59,7 @@ public: class TestNeverActiveConditionChecker : public TestConditionChecker { public: - int64_t BeginTime(const Consensus::Params& params) const override { return 0; } - int64_t EndTime(const Consensus::Params& params) const override { return 1230768000; } + int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::NEVER_ACTIVE; } }; #define CHECKERS 6 @@ -134,10 +133,7 @@ public: BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(tip) == height, strprintf("Test %i for StateSinceHeight", num)); BOOST_CHECK_MESSAGE(checker_delayed[i].GetStateSinceHeightFor(tip) == height_delayed, strprintf("Test %i for StateSinceHeight (delayed)", num)); BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (always active)", num)); - - // never active may go from DEFINED -> FAILED at the first period - const auto never_height = checker_never[i].GetStateSinceHeightFor(tip); - BOOST_CHECK_MESSAGE(never_height == 0 || never_height == checker_never[i].Period(paramsDummy), strprintf("Test %i for StateSinceHeight (never active)", num)); + BOOST_CHECK_MESSAGE(checker_never[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (never active)", num)); } } num++; @@ -170,7 +166,7 @@ public: BOOST_CHECK_MESSAGE(got == exp, strprintf("Test %i for %s height %d (got %s)", num, StateName(exp), height, StateName(got))); BOOST_CHECK_MESSAGE(got_delayed == exp_delayed, strprintf("Test %i for %s height %d (got %s; delayed case)", num, StateName(exp_delayed), height, StateName(got_delayed))); BOOST_CHECK_MESSAGE(got_always == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE height %d (got %s; always active case)", num, height, StateName(got_always))); - BOOST_CHECK_MESSAGE(got_never == ThresholdState::DEFINED|| got_never == ThresholdState::FAILED, strprintf("Test %i for DEFINED/FAILED height %d (got %s; never active case)", num, height, StateName(got_never))); + BOOST_CHECK_MESSAGE(got_never == ThresholdState::FAILED, strprintf("Test %i for FAILED height %d (got %s; never active case)", num, height, StateName(got_never))); } } num++; @@ -270,7 +266,7 @@ BOOST_AUTO_TEST_CASE(versionbits_sanity) // Check min_activation_height is on a retarget boundary BOOST_CHECK_EQUAL(mainnetParams.vDeployments[i].min_activation_height % mainnetParams.nMinerConfirmationWindow, 0); // Check min_activation_height is 0 for ALWAYS_ACTIVE and never active deployments - if (mainnetParams.vDeployments[i].nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE || mainnetParams.vDeployments[i].nTimeout <= 1230768000) { + if (mainnetParams.vDeployments[i].nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE || mainnetParams.vDeployments[i].nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) { BOOST_CHECK_EQUAL(mainnetParams.vDeployments[i].min_activation_height, 0); } @@ -304,8 +300,9 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus // should not be any signalling for first block BOOST_CHECK_EQUAL(ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS); - // always active deployments shouldn't need to be tested further + // always/never active deployments shouldn't need to be tested further if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE) return; + if (nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE) return; BOOST_REQUIRE(nStartTime < nTimeout); BOOST_REQUIRE(nStartTime >= 0); @@ -448,6 +445,15 @@ BOOST_AUTO_TEST_CASE(versionbits_computeblockversion) } { + // Use regtest/testdummy to ensure we always exercise some + // deployment that's not always/never active + ArgsManager args; + args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008 + const auto chainParams = CreateChainParams(args, CBaseChainParams::REGTEST); + check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY); + } + + { // Use regtest/testdummy to ensure we always exercise the // min_activation_height test, even if we're not using that in a // live deployment diff --git a/src/versionbits.cpp b/src/versionbits.cpp index 11da729596..df666c963f 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -18,6 +18,11 @@ ThresholdState AbstractThresholdConditionChecker::GetStateFor(const CBlockIndex* return ThresholdState::ACTIVE; } + // Check if this deployment is never active. + if (nTimeStart == Consensus::BIP9Deployment::NEVER_ACTIVE) { + return ThresholdState::FAILED; + } + // A block's state is always the same as that of the first of its period, so it is computed based on a pindexPrev whose height equals a multiple of nPeriod - 1. if (pindexPrev != nullptr) { pindexPrev = pindexPrev->GetAncestor(pindexPrev->nHeight - ((pindexPrev->nHeight + 1) % nPeriod)); @@ -129,7 +134,7 @@ BIP9Stats AbstractThresholdConditionChecker::GetStateStatisticsFor(const CBlockI int AbstractThresholdConditionChecker::GetStateSinceHeightFor(const CBlockIndex* pindexPrev, const Consensus::Params& params, ThresholdConditionCache& cache) const { int64_t start_time = BeginTime(params); - if (start_time == Consensus::BIP9Deployment::ALWAYS_ACTIVE) { + if (start_time == Consensus::BIP9Deployment::ALWAYS_ACTIVE || start_time == Consensus::BIP9Deployment::NEVER_ACTIVE) { return 0; } |