Skip to content

Commit 5932744

Browse files
committed
tests: test ComputeBlockVersion for all deployments
This generalises the ComputeBlockVersion test so that it can apply to any activation parameters we might set, and checks all the parameters set for each deployment on each chain, to simultaneously ensure that the deployments we have configured work sensibly, and that the test code does not suffer bitrot in the event that all interesting deployments are buried.
1 parent 63879f0 commit 5932744

File tree

1 file changed

+71
-35
lines changed

1 file changed

+71
-35
lines changed

src/test/versionbits_tests.cpp

Lines changed: 71 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -252,38 +252,61 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
252252
int64_t nStartTime = params.vDeployments[dep].nStartTime;
253253
int64_t nTimeout = params.vDeployments[dep].nTimeout;
254254

255-
assert(nStartTime < nTimeout);
255+
// should not be any signalling for first block
256+
BOOST_CHECK_EQUAL(ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
257+
258+
// always active deployments shouldn't need to be tested further
259+
if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE) return;
260+
261+
BOOST_REQUIRE(nStartTime < nTimeout);
262+
BOOST_REQUIRE(nStartTime >= 0);
263+
BOOST_REQUIRE(nTimeout <= std::numeric_limits<uint32_t>::max() || nTimeout == Consensus::BIP9Deployment::NO_TIMEOUT);
264+
BOOST_REQUIRE(0 <= bit && bit < 32);
265+
BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0);
256266

257267
// In the first chain, test that the bit is set by CBV until it has failed.
258268
// In the second chain, test the bit is set by CBV while STARTED and
259269
// LOCKED-IN, and then no longer set while ACTIVE.
260270
VersionBitsTester firstChain, secondChain;
261271

262-
// Start generating blocks before nStartTime
263-
int64_t nTime = nStartTime - 1;
272+
int64_t nTime = nStartTime;
264273

265-
// Before MedianTimePast of the chain has crossed nStartTime, the bit
266-
// should not be set.
267274
CBlockIndex *lastBlock = nullptr;
268-
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
269-
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
270275

271-
// Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
272-
for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
273-
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
274-
// This works because VERSIONBITS_LAST_OLD_BLOCK_VERSION happens
275-
// to be 4, and the bit we're testing happens to be bit 28.
276+
// Before MedianTimePast of the chain has crossed nStartTime, the bit
277+
// should not be set.
278+
if (nTime == 0) {
279+
// since CBlockIndex::nTime is uint32_t we can't represent any
280+
// earlier time, so will transition from DEFINED to STARTED at the
281+
// end of the first period by mining blocks at nTime == 0
282+
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
276283
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
277-
}
278-
// Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
279-
// CBV should still not yet set the bit.
280-
nTime = nStartTime;
281-
for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
282-
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
284+
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
285+
BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
286+
// then we'll keep mining at nStartTime...
287+
} else {
288+
// use a time 1s earlier than start time to check we stay DEFINED
289+
--nTime;
290+
291+
// Start generating blocks before nStartTime
292+
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
283293
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
294+
295+
// Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
296+
for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
297+
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
298+
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
299+
}
300+
// Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
301+
// CBV should still not yet set the bit.
302+
nTime = nStartTime;
303+
for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
304+
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
305+
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
306+
}
307+
// Next we will advance to the next period and transition to STARTED,
284308
}
285309

286-
// Advance to the next period and transition to STARTED,
287310
lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
288311
// so ComputeBlockVersion should now set the bit,
289312
BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
@@ -304,17 +327,29 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
304327
nHeight += 1;
305328
}
306329

307-
nTime = nTimeout;
308-
// FAILED is only triggered at the end of a period, so CBV should be setting
309-
// the bit until the period transition.
310-
for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
330+
if (nTimeout != Consensus::BIP9Deployment::NO_TIMEOUT) {
331+
// can reach any nTimeout other than NO_TIMEOUT due to earlier BOOST_REQUIRE
332+
333+
nTime = nTimeout;
334+
335+
// finish the last period before we start timing out
336+
while (nHeight % params.nMinerConfirmationWindow != 0) {
337+
lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
338+
BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
339+
nHeight += 1;
340+
}
341+
342+
// FAILED is only triggered at the end of a period, so CBV should be setting
343+
// the bit until the period transition.
344+
for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
345+
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
346+
BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
347+
nHeight += 1;
348+
}
349+
// The next block should trigger no longer setting the bit.
311350
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
312-
BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1<<bit)) != 0);
313-
nHeight += 1;
351+
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
314352
}
315-
// The next block should trigger no longer setting the bit.
316-
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
317-
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
318353

319354
// On a new chain:
320355
// 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
338373
BOOST_CHECK((ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
339374
lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
340375
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, params) & (1<<bit), 0);
341-
342-
// Finally, verify that after a soft fork has activated, CBV no longer uses
343-
// VERSIONBITS_LAST_OLD_BLOCK_VERSION.
344-
//BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
345376
}
346377

347378
BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
348379
{
349-
// Use the TESTDUMMY deployment for testing purposes.
350-
const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
351-
check_computeblockversion(chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
380+
// check that any deployment on any chain can conceivably reach both
381+
// ACTIVE and FAILED states in roughly the way we expect
382+
for (const auto& chain_name : {CBaseChainParams::MAIN, CBaseChainParams::TESTNET, CBaseChainParams::SIGNET, CBaseChainParams::REGTEST}) {
383+
const auto chainParams = CreateChainParams(*m_node.args, chain_name);
384+
for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
385+
check_computeblockversion(chainParams->GetConsensus(), static_cast<Consensus::DeploymentPos>(i));
386+
}
387+
}
352388
}
353389

354390
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)