|
|
@ -6,6 +6,9 @@ |
|
|
|
#include "random.h" |
|
|
|
#include "random.h" |
|
|
|
#include "versionbits.h" |
|
|
|
#include "versionbits.h" |
|
|
|
#include "test/test_bitcoin.h" |
|
|
|
#include "test/test_bitcoin.h" |
|
|
|
|
|
|
|
#include "chainparams.h" |
|
|
|
|
|
|
|
#include "main.h" |
|
|
|
|
|
|
|
#include "consensus/params.h" |
|
|
|
|
|
|
|
|
|
|
|
#include <boost/test/unit_test.hpp> |
|
|
|
#include <boost/test/unit_test.hpp> |
|
|
|
|
|
|
|
|
|
|
@ -124,6 +127,8 @@ public: |
|
|
|
num++; |
|
|
|
num++; |
|
|
|
return *this; |
|
|
|
return *this; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CBlockIndex * Tip() { return vpblock.size() ? vpblock.back() : NULL; } |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup) |
|
|
|
BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup) |
|
|
@ -182,4 +187,108 @@ BOOST_AUTO_TEST_CASE(versionbits_test) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(versionbits_computeblockversion) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Check that ComputeBlockVersion will set the appropriate bit correctly
|
|
|
|
|
|
|
|
// on mainnet.
|
|
|
|
|
|
|
|
const Consensus::Params &mainnetParams = Params(CBaseChainParams::MAIN).GetConsensus(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Use the TESTDUMMY deployment for testing purposes.
|
|
|
|
|
|
|
|
int64_t bit = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit; |
|
|
|
|
|
|
|
int64_t nStartTime = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime; |
|
|
|
|
|
|
|
int64_t nTimeout = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(nStartTime < nTimeout); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Before MedianTimePast of the chain has crossed nStartTime, the bit
|
|
|
|
|
|
|
|
// should not be set.
|
|
|
|
|
|
|
|
CBlockIndex *lastBlock = NULL; |
|
|
|
|
|
|
|
lastBlock = firstChain.Mine(2016, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); |
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Mine 2011 more blocks at the old time, and check that CBV isn't setting the bit yet.
|
|
|
|
|
|
|
|
for (int i=1; i<2012; i++) { |
|
|
|
|
|
|
|
lastBlock = firstChain.Mine(2016+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.
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (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 (int i=2012; i<=2016; i++) { |
|
|
|
|
|
|
|
lastBlock = firstChain.Mine(2016+i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); |
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Advance to the next period and transition to STARTED,
|
|
|
|
|
|
|
|
lastBlock = firstChain.Mine(6048, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); |
|
|
|
|
|
|
|
// so ComputeBlockVersion should now set the bit,
|
|
|
|
|
|
|
|
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0); |
|
|
|
|
|
|
|
// and should also be using the VERSIONBITS_TOP_BITS.
|
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check that ComputeBlockVersion will set the bit until nTimeout
|
|
|
|
|
|
|
|
nTime += 600; |
|
|
|
|
|
|
|
int blocksToMine = 4032; // test blocks for up to 2 time periods
|
|
|
|
|
|
|
|
int nHeight = 6048; |
|
|
|
|
|
|
|
// These blocks are all before nTimeout is reached.
|
|
|
|
|
|
|
|
while (nTime < nTimeout && blocksToMine > 0) { |
|
|
|
|
|
|
|
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); |
|
|
|
|
|
|
|
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0); |
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS); |
|
|
|
|
|
|
|
blocksToMine--; |
|
|
|
|
|
|
|
nTime += 600; |
|
|
|
|
|
|
|
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 (int i=0; i<2015; i++) { |
|
|
|
|
|
|
|
lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); |
|
|
|
|
|
|
|
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (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, mainnetParams) & (1<<bit), 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// On a new chain:
|
|
|
|
|
|
|
|
// verify that the bit will be set after lock-in, and then stop being set
|
|
|
|
|
|
|
|
// after activation.
|
|
|
|
|
|
|
|
nTime = nStartTime; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Mine one period worth of blocks, and check that the bit will be on for the
|
|
|
|
|
|
|
|
// next period.
|
|
|
|
|
|
|
|
lastBlock = secondChain.Mine(2016, nStartTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); |
|
|
|
|
|
|
|
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Mine another period worth of blocks, signaling the new bit.
|
|
|
|
|
|
|
|
lastBlock = secondChain.Mine(4032, nStartTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip(); |
|
|
|
|
|
|
|
// After one period of setting the bit on each block, it should have locked in.
|
|
|
|
|
|
|
|
// We keep setting the bit for one more period though, until activation.
|
|
|
|
|
|
|
|
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Now check that we keep mining the block until the end of this period, and
|
|
|
|
|
|
|
|
// then stop at the beginning of the next period.
|
|
|
|
|
|
|
|
lastBlock = secondChain.Mine(6047, nStartTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); |
|
|
|
|
|
|
|
BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0); |
|
|
|
|
|
|
|
lastBlock = secondChain.Mine(6048, nStartTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip(); |
|
|
|
|
|
|
|
BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (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_SUITE_END() |
|
|
|
BOOST_AUTO_TEST_SUITE_END() |
|
|
|