aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/test/versionbits_tests.cpp106
1 files changed, 71 insertions, 35 deletions
diff --git a/src/test/versionbits_tests.cpp b/src/test/versionbits_tests.cpp
index b09827ffe5..7e96ef923e 100644
--- a/src/test/versionbits_tests.cpp
+++ b/src/test/versionbits_tests.cpp
@@ -252,38 +252,61 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
int64_t nStartTime = params.vDeployments[dep].nStartTime;
int64_t nTimeout = params.vDeployments[dep].nTimeout;
- assert(nStartTime < nTimeout);
+ // 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
+ if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE) return;
+
+ BOOST_REQUIRE(nStartTime < nTimeout);
+ BOOST_REQUIRE(nStartTime >= 0);
+ BOOST_REQUIRE(nTimeout <= std::numeric_limits<uint32_t>::max() || nTimeout == Consensus::BIP9Deployment::NO_TIMEOUT);
+ BOOST_REQUIRE(0 <= bit && bit < 32);
+ BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0);
// In the first chain, test that the bit is set by CBV until it has failed.
// In the second chain, test the bit is set by CBV while STARTED and
// LOCKED-IN, and then no longer set while ACTIVE.
VersionBitsTester firstChain, secondChain;
- // Start generating blocks before nStartTime
- int64_t nTime = nStartTime - 1;
+ int64_t nTime = nStartTime;
- // Before MedianTimePast of the chain has crossed nStartTime, the bit
- // should not be set.
CBlockIndex *lastBlock = nullptr;
- lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
- // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
- for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
- lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- // This works because VERSIONBITS_LAST_OLD_BLOCK_VERSION happens
- // to be 4, and the bit we're testing happens to be bit 28.
+ // Before MedianTimePast of the chain has crossed nStartTime, the bit
+ // should not be set.
+ if (nTime == 0) {
+ // since CBlockIndex::nTime is uint32_t we can't represent any
+ // earlier time, so will transition from DEFINED to STARTED at the
+ // end of the first period by mining blocks at nTime == 0
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
- }
- // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
- // CBV should still not yet set the bit.
- nTime = nStartTime;
- for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
- lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ // then we'll keep mining at nStartTime...
+ } else {
+ // use a time 1s earlier than start time to check we stay DEFINED
+ --nTime;
+
+ // Start generating blocks before nStartTime
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+
+ // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
+ for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ }
+ // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
+ // CBV should still not yet set the bit.
+ nTime = nStartTime;
+ for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
+ lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
+ }
+ // Next we will advance to the next period and transition to STARTED,
}
- // Advance to the next period and transition to STARTED,
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
// so ComputeBlockVersion should now set the bit,
BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
@@ -304,17 +327,29 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
nHeight += 1;
}
- nTime = nTimeout;
- // FAILED is only triggered at the end of a period, so CBV should be setting
- // the bit until the period transition.
- for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
+ if (nTimeout != Consensus::BIP9Deployment::NO_TIMEOUT) {
+ // can reach any nTimeout other than NO_TIMEOUT due to earlier BOOST_REQUIRE
+
+ nTime = nTimeout;
+
+ // finish the last period before we start timing out
+ while (nHeight % params.nMinerConfirmationWindow != 0) {
+ lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ nHeight += 1;
+ }
+
+ // FAILED is only triggered at the end of a period, so CBV should be setting
+ // the bit until the period transition.
+ for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
+ lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
+ BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
+ nHeight += 1;
+ }
+ // The next block should trigger no longer setting the bit.
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
- nHeight += 1;
+ BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
}
- // The next block should trigger no longer setting the bit.
- lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
- BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
// On a new chain:
// verify that the bit will be set after lock-in, and then stop being set
@@ -338,17 +373,18 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
-
- // Finally, verify that after a soft fork has activated, CBV no longer uses
- // VERSIONBITS_LAST_OLD_BLOCK_VERSION.
- //BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
}
BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
{
- // Use the TESTDUMMY deployment for testing purposes.
- const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
- check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
+ // check that any deployment on any chain can conceivably reach both
+ // ACTIVE and FAILED states in roughly the way we expect
+ for (const auto& chain_name : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET, CBaseChainParams::REGTEST}) {
+ const auto chainParams = CreateChainParams(*m_node.args, chain_name);
+ for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
+ check_computeblockversion(chainParams->GetConsensus(), static_cast<Consensus::DeploymentPos>(i));
+ }
+ }
}
BOOST_AUTO_TEST_SUITE_END()