scripted-diff: Use the C++11 keyword nullptr to denote the pointer literal instead...
[bitcoinplatinum.git] / src / test / versionbits_tests.cpp
blobf433aad889c1926f3e7064adf4e65def4fbaf42a
1 // Copyright (c) 2014-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "chain.h"
6 #include "versionbits.h"
7 #include "test/test_bitcoin.h"
8 #include "chainparams.h"
9 #include "validation.h"
10 #include "consensus/params.h"
12 #include <boost/test/unit_test.hpp>
14 /* Define a virtual block time, one block per 10 minutes after Nov 14 2014, 0:55:36am */
15 int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; }
17 static const Consensus::Params paramsDummy = Consensus::Params();
19 class TestConditionChecker : public AbstractThresholdConditionChecker
21 private:
22 mutable ThresholdConditionCache cache;
24 public:
25 int64_t BeginTime(const Consensus::Params& params) const override { return TestTime(10000); }
26 int64_t EndTime(const Consensus::Params& params) const override { return TestTime(20000); }
27 int Period(const Consensus::Params& params) const override { return 1000; }
28 int Threshold(const Consensus::Params& params) const override { return 900; }
29 bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override { return (pindex->nVersion & 0x100); }
31 ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, paramsDummy, cache); }
32 int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, paramsDummy, cache); }
35 #define CHECKERS 6
37 class VersionBitsTester
39 // A fake blockchain
40 std::vector<CBlockIndex*> vpblock;
42 // 6 independent checkers for the same bit.
43 // The first one performs all checks, the second only 50%, the third only 25%, etc...
44 // This is to test whether lack of cached information leads to the same results.
45 TestConditionChecker checker[CHECKERS];
47 // Test counter (to identify failures)
48 int num;
50 public:
51 VersionBitsTester() : num(0) {}
53 VersionBitsTester& Reset() {
54 for (unsigned int i = 0; i < vpblock.size(); i++) {
55 delete vpblock[i];
57 for (unsigned int i = 0; i < CHECKERS; i++) {
58 checker[i] = TestConditionChecker();
60 vpblock.clear();
61 return *this;
64 ~VersionBitsTester() {
65 Reset();
68 VersionBitsTester& Mine(unsigned int height, int32_t nTime, int32_t nVersion) {
69 while (vpblock.size() < height) {
70 CBlockIndex* pindex = new CBlockIndex();
71 pindex->nHeight = vpblock.size();
72 pindex->pprev = vpblock.size() > 0 ? vpblock.back() : nullptr;
73 pindex->nTime = nTime;
74 pindex->nVersion = nVersion;
75 pindex->BuildSkip();
76 vpblock.push_back(pindex);
78 return *this;
81 VersionBitsTester& TestStateSinceHeight(int height) {
82 for (int i = 0; i < CHECKERS; i++) {
83 if (InsecureRandBits(i) == 0) {
84 BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()) == height, strprintf("Test %i for StateSinceHeight", num));
87 num++;
88 return *this;
91 VersionBitsTester& TestDefined() {
92 for (int i = 0; i < CHECKERS; i++) {
93 if (InsecureRandBits(i) == 0) {
94 BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_DEFINED, strprintf("Test %i for DEFINED", num));
97 num++;
98 return *this;
101 VersionBitsTester& TestStarted() {
102 for (int i = 0; i < CHECKERS; i++) {
103 if (InsecureRandBits(i) == 0) {
104 BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_STARTED, strprintf("Test %i for STARTED", num));
107 num++;
108 return *this;
111 VersionBitsTester& TestLockedIn() {
112 for (int i = 0; i < CHECKERS; i++) {
113 if (InsecureRandBits(i) == 0) {
114 BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_LOCKED_IN, strprintf("Test %i for LOCKED_IN", num));
117 num++;
118 return *this;
121 VersionBitsTester& TestActive() {
122 for (int i = 0; i < CHECKERS; i++) {
123 if (InsecureRandBits(i) == 0) {
124 BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE", num));
127 num++;
128 return *this;
131 VersionBitsTester& TestFailed() {
132 for (int i = 0; i < CHECKERS; i++) {
133 if (InsecureRandBits(i) == 0) {
134 BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_FAILED, strprintf("Test %i for FAILED", num));
137 num++;
138 return *this;
141 CBlockIndex * Tip() { return vpblock.size() ? vpblock.back() : nullptr; }
144 BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup)
146 BOOST_AUTO_TEST_CASE(versionbits_test)
148 for (int i = 0; i < 64; i++) {
149 // DEFINED -> FAILED
150 VersionBitsTester().TestDefined().TestStateSinceHeight(0)
151 .Mine(1, TestTime(1), 0x100).TestDefined().TestStateSinceHeight(0)
152 .Mine(11, TestTime(11), 0x100).TestDefined().TestStateSinceHeight(0)
153 .Mine(989, TestTime(989), 0x100).TestDefined().TestStateSinceHeight(0)
154 .Mine(999, TestTime(20000), 0x100).TestDefined().TestStateSinceHeight(0)
155 .Mine(1000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(1000)
156 .Mine(1999, TestTime(30001), 0x100).TestFailed().TestStateSinceHeight(1000)
157 .Mine(2000, TestTime(30002), 0x100).TestFailed().TestStateSinceHeight(1000)
158 .Mine(2001, TestTime(30003), 0x100).TestFailed().TestStateSinceHeight(1000)
159 .Mine(2999, TestTime(30004), 0x100).TestFailed().TestStateSinceHeight(1000)
160 .Mine(3000, TestTime(30005), 0x100).TestFailed().TestStateSinceHeight(1000)
162 // DEFINED -> STARTED -> FAILED
163 .Reset().TestDefined().TestStateSinceHeight(0)
164 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
165 .Mine(1000, TestTime(10000) - 1, 0x100).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
166 .Mine(2000, TestTime(10000), 0x100).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
167 .Mine(2051, TestTime(10010), 0).TestStarted().TestStateSinceHeight(2000) // 51 old blocks
168 .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 899 new blocks
169 .Mine(3000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(3000) // 50 old blocks (so 899 out of the past 1000)
170 .Mine(4000, TestTime(20010), 0x100).TestFailed().TestStateSinceHeight(3000)
172 // DEFINED -> STARTED -> FAILED while threshold reached
173 .Reset().TestDefined().TestStateSinceHeight(0)
174 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
175 .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
176 .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
177 .Mine(2999, TestTime(30000), 0x100).TestStarted().TestStateSinceHeight(2000) // 999 new blocks
178 .Mine(3000, TestTime(30000), 0x100).TestFailed().TestStateSinceHeight(3000) // 1 new block (so 1000 out of the past 1000 are new)
179 .Mine(3999, TestTime(30001), 0).TestFailed().TestStateSinceHeight(3000)
180 .Mine(4000, TestTime(30002), 0).TestFailed().TestStateSinceHeight(3000)
181 .Mine(14333, TestTime(30003), 0).TestFailed().TestStateSinceHeight(3000)
182 .Mine(24000, TestTime(40000), 0).TestFailed().TestStateSinceHeight(3000)
184 // DEFINED -> STARTED -> LOCKEDIN at the last minute -> ACTIVE
185 .Reset().TestDefined()
186 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
187 .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
188 .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
189 .Mine(2050, TestTime(10010), 0x200).TestStarted().TestStateSinceHeight(2000) // 50 old blocks
190 .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 900 new blocks
191 .Mine(2999, TestTime(19999), 0x200).TestStarted().TestStateSinceHeight(2000) // 49 old blocks
192 .Mine(3000, TestTime(29999), 0x200).TestLockedIn().TestStateSinceHeight(3000) // 1 old block (so 900 out of the past 1000)
193 .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
194 .Mine(4000, TestTime(30002), 0).TestActive().TestStateSinceHeight(4000)
195 .Mine(14333, TestTime(30003), 0).TestActive().TestStateSinceHeight(4000)
196 .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000)
198 // DEFINED multiple periods -> STARTED multiple periods -> FAILED
199 .Reset().TestDefined().TestStateSinceHeight(0)
200 .Mine(999, TestTime(999), 0).TestDefined().TestStateSinceHeight(0)
201 .Mine(1000, TestTime(1000), 0).TestDefined().TestStateSinceHeight(0)
202 .Mine(2000, TestTime(2000), 0).TestDefined().TestStateSinceHeight(0)
203 .Mine(3000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
204 .Mine(4000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
205 .Mine(5000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
206 .Mine(6000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(6000)
207 .Mine(7000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000);
210 // Sanity checks of version bit deployments
211 const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
212 const Consensus::Params &mainnetParams = chainParams->GetConsensus();
213 for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
214 uint32_t bitmask = VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)i);
215 // Make sure that no deployment tries to set an invalid bit.
216 BOOST_CHECK_EQUAL(bitmask & ~(uint32_t)VERSIONBITS_TOP_MASK, bitmask);
218 // Verify that the deployment windows of different deployment using the
219 // same bit are disjoint.
220 // This test may need modification at such time as a new deployment
221 // is proposed that reuses the bit of an activated soft fork, before the
222 // end time of that soft fork. (Alternatively, the end time of that
223 // activated soft fork could be later changed to be earlier to avoid
224 // overlap.)
225 for (int j=i+1; j<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; j++) {
226 if (VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)j) == bitmask) {
227 BOOST_CHECK(mainnetParams.vDeployments[j].nStartTime > mainnetParams.vDeployments[i].nTimeout ||
228 mainnetParams.vDeployments[i].nStartTime > mainnetParams.vDeployments[j].nTimeout);
234 BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
236 // Check that ComputeBlockVersion will set the appropriate bit correctly
237 // on mainnet.
238 const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
239 const Consensus::Params &mainnetParams = chainParams->GetConsensus();
241 // Use the TESTDUMMY deployment for testing purposes.
242 int64_t bit = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit;
243 int64_t nStartTime = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime;
244 int64_t nTimeout = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout;
246 assert(nStartTime < nTimeout);
248 // In the first chain, test that the bit is set by CBV until it has failed.
249 // In the second chain, test the bit is set by CBV while STARTED and
250 // LOCKED-IN, and then no longer set while ACTIVE.
251 VersionBitsTester firstChain, secondChain;
253 // Start generating blocks before nStartTime
254 int64_t nTime = nStartTime - 1;
256 // Before MedianTimePast of the chain has crossed nStartTime, the bit
257 // should not be set.
258 CBlockIndex *lastBlock = nullptr;
259 lastBlock = firstChain.Mine(2016, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
260 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
262 // Mine 2011 more blocks at the old time, and check that CBV isn't setting the bit yet.
263 for (int i=1; i<2012; i++) {
264 lastBlock = firstChain.Mine(2016+i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
265 // This works because VERSIONBITS_LAST_OLD_BLOCK_VERSION happens
266 // to be 4, and the bit we're testing happens to be bit 28.
267 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
269 // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
270 // CBV should still not yet set the bit.
271 nTime = nStartTime;
272 for (int i=2012; i<=2016; i++) {
273 lastBlock = firstChain.Mine(2016+i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
274 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
277 // Advance to the next period and transition to STARTED,
278 lastBlock = firstChain.Mine(6048, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
279 // so ComputeBlockVersion should now set the bit,
280 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
281 // and should also be using the VERSIONBITS_TOP_BITS.
282 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
284 // Check that ComputeBlockVersion will set the bit until nTimeout
285 nTime += 600;
286 int blocksToMine = 4032; // test blocks for up to 2 time periods
287 int nHeight = 6048;
288 // These blocks are all before nTimeout is reached.
289 while (nTime < nTimeout && blocksToMine > 0) {
290 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
291 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
292 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
293 blocksToMine--;
294 nTime += 600;
295 nHeight += 1;
298 nTime = nTimeout;
299 // FAILED is only triggered at the end of a period, so CBV should be setting
300 // the bit until the period transition.
301 for (int i=0; i<2015; i++) {
302 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
303 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
304 nHeight += 1;
306 // The next block should trigger no longer setting the bit.
307 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
308 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
310 // On a new chain:
311 // verify that the bit will be set after lock-in, and then stop being set
312 // after activation.
313 nTime = nStartTime;
315 // Mine one period worth of blocks, and check that the bit will be on for the
316 // next period.
317 lastBlock = secondChain.Mine(2016, nStartTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
318 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
320 // Mine another period worth of blocks, signaling the new bit.
321 lastBlock = secondChain.Mine(4032, nStartTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
322 // After one period of setting the bit on each block, it should have locked in.
323 // We keep setting the bit for one more period though, until activation.
324 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
326 // Now check that we keep mining the block until the end of this period, and
327 // then stop at the beginning of the next period.
328 lastBlock = secondChain.Mine(6047, nStartTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
329 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
330 lastBlock = secondChain.Mine(6048, nStartTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
331 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
333 // Finally, verify that after a soft fork has activated, CBV no longer uses
334 // VERSIONBITS_LAST_OLD_BLOCK_VERSION.
335 //BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
339 BOOST_AUTO_TEST_SUITE_END()