@ -252,38 +252,61 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
int64_t nStartTime = params . vDeployments [ dep ] . nStartTime ;
int64_t nStartTime = params . vDeployments [ dep ] . nStartTime ;
int64_t nTimeout = params . vDeployments [ dep ] . nTimeout ;
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 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
// In the second chain, test the bit is set by CBV while STARTED and
// LOCKED-IN, and then no longer set while ACTIVE.
// LOCKED-IN, and then no longer set while ACTIVE.
VersionBitsTester firstChain , secondChain ;
VersionBitsTester firstChain , secondChain ;
// Start generating blocks before nStartTime
int64_t nTime = nStartTime ;
int64_t nTime = nStartTime - 1 ;
// Before MedianTimePast of the chain has crossed nStartTime, the bit
// should not be set.
CBlockIndex * lastBlock = nullptr ;
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.
// Before MedianTimePast of the chain has crossed nStartTime, the bit
for ( uint32_t i = 1 ; i < params . nMinerConfirmationWindow - 4 ; i + + ) {
// should not be set.
lastBlock = firstChain . Mine ( params . nMinerConfirmationWindow + i , nTime , VERSIONBITS_LAST_OLD_BLOCK_VERSION ) . Tip ( ) ;
if ( nTime = = 0 ) {
// This works because VERSIONBITS_LAST_OLD_BLOCK_VERSION happens
// since CBlockIndex::nTime is uint32_t we can't represent any
// to be 4, and the bit we're testing happens to be bit 28.
// 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 ) ;
BOOST_CHECK_EQUAL ( ComputeBlockVersion ( lastBlock , params ) & ( 1 < < bit ) , 0 ) ;
}
lastBlock = firstChain . Mine ( params . nMinerConfirmationWindow , nTime , VERSIONBITS_LAST_OLD_BLOCK_VERSION ) . Tip ( ) ;
// Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
BOOST_CHECK ( ( ComputeBlockVersion ( lastBlock , params ) & ( 1 < < bit ) ) ! = 0 ) ;
// CBV should still not yet set the bit.
// then we'll keep mining at nStartTime...
nTime = nStartTime ;
} else {
for ( uint32_t i = params . nMinerConfirmationWindow - 4 ; i < = params . nMinerConfirmationWindow ; i + + ) {
// use a time 1s earlier than start time to check we stay DEFINED
lastBlock = firstChain . Mine ( params . nMinerConfirmationWindow + i , nTime , VERSIONBITS_LAST_OLD_BLOCK_VERSION ) . Tip ( ) ;
- - 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 ) ;
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 ( ) ;
lastBlock = firstChain . Mine ( params . nMinerConfirmationWindow * 3 , nTime , VERSIONBITS_LAST_OLD_BLOCK_VERSION ) . Tip ( ) ;
// so ComputeBlockVersion should now set the bit,
// so ComputeBlockVersion should now set the bit,
BOOST_CHECK ( ( ComputeBlockVersion ( lastBlock , params ) & ( 1 < < bit ) ) ! = 0 ) ;
BOOST_CHECK ( ( ComputeBlockVersion ( lastBlock , params ) & ( 1 < < bit ) ) ! = 0 ) ;
@ -304,17 +327,29 @@ static void check_computeblockversion(const Consensus::Params& params, Consensus
nHeight + = 1 ;
nHeight + = 1 ;
}
}
nTime = nTimeout ;
if ( nTimeout ! = Consensus : : BIP9Deployment : : NO_TIMEOUT ) {
// FAILED is only triggered at the end of a period, so CBV should be setting
// can reach any nTimeout other than NO_TIMEOUT due to earlier BOOST_REQUIRE
// the bit until the period transition.
for ( uint32_t i = 0 ; i < params . nMinerConfirmationWindow - 1 ; i + + ) {
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 ( ) ;
lastBlock = firstChain . Mine ( nHeight + 1 , nTime , VERSIONBITS_LAST_OLD_BLOCK_VERSION ) . Tip ( ) ;
BOOST_CHECK ( ( ComputeBlockVersion ( lastBlock , params ) & ( 1 < < bit ) ) ! = 0 ) ;
BOOST_CHECK_EQUAL ( 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_EQUAL ( ComputeBlockVersion ( lastBlock , params ) & ( 1 < < bit ) , 0 ) ;
// On a new chain:
// On a new chain:
// verify that the bit will be set after lock-in, and then stop being set
// 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 ) ;
BOOST_CHECK ( ( ComputeBlockVersion ( lastBlock , params ) & ( 1 < < bit ) ) ! = 0 ) ;
lastBlock = secondChain . Mine ( params . nMinerConfirmationWindow * 3 , nTime , VERSIONBITS_LAST_OLD_BLOCK_VERSION ) . Tip ( ) ;
lastBlock = secondChain . Mine ( params . nMinerConfirmationWindow * 3 , nTime , VERSIONBITS_LAST_OLD_BLOCK_VERSION ) . Tip ( ) ;
BOOST_CHECK_EQUAL ( ComputeBlockVersion ( lastBlock , params ) & ( 1 < < bit ) , 0 ) ;
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 )
BOOST_AUTO_TEST_CASE ( versionbits_computeblockversion )
{
{
// Use the TESTDUMMY deployment for testing purposes.
// check that any deployment on any chain can conceivably reach both
const auto chainParams = CreateChainParams ( * m_node . args , CBaseChainParams : : MAIN ) ;
// ACTIVE and FAILED states in roughly the way we expect
check_computeblockversion ( chainParams - > GetConsensus ( ) , Consensus : : DEPLOYMENT_TESTDUMMY ) ;
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 ( )
BOOST_AUTO_TEST_SUITE_END ( )