tests: Add missing locks to tests
[bitcoinplatinum.git] / src / test / versionbits_tests.cpp
blobdb537d3932d5f9f410546d2388ee7a57ea5d6120
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 class TestAlwaysActiveConditionChecker : public TestConditionChecker
37 public:
38 int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::ALWAYS_ACTIVE; }
41 #define CHECKERS 6
43 class VersionBitsTester
45 // A fake blockchain
46 std::vector<CBlockIndex*> vpblock;
48 // 6 independent checkers for the same bit.
49 // The first one performs all checks, the second only 50%, the third only 25%, etc...
50 // This is to test whether lack of cached information leads to the same results.
51 TestConditionChecker checker[CHECKERS];
52 // Another 6 that assume always active activation
53 TestAlwaysActiveConditionChecker checker_always[CHECKERS];
55 // Test counter (to identify failures)
56 int num;
58 public:
59 VersionBitsTester() : num(0) {}
61 VersionBitsTester& Reset() {
62 for (unsigned int i = 0; i < vpblock.size(); i++) {
63 delete vpblock[i];
65 for (unsigned int i = 0; i < CHECKERS; i++) {
66 checker[i] = TestConditionChecker();
67 checker_always[i] = TestAlwaysActiveConditionChecker();
69 vpblock.clear();
70 return *this;
73 ~VersionBitsTester() {
74 Reset();
77 VersionBitsTester& Mine(unsigned int height, int32_t nTime, int32_t nVersion) {
78 while (vpblock.size() < height) {
79 CBlockIndex* pindex = new CBlockIndex();
80 pindex->nHeight = vpblock.size();
81 pindex->pprev = vpblock.size() > 0 ? vpblock.back() : nullptr;
82 pindex->nTime = nTime;
83 pindex->nVersion = nVersion;
84 pindex->BuildSkip();
85 vpblock.push_back(pindex);
87 return *this;
90 VersionBitsTester& TestStateSinceHeight(int height) {
91 for (int i = 0; i < CHECKERS; i++) {
92 if (InsecureRandBits(i) == 0) {
93 BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()) == height, strprintf("Test %i for StateSinceHeight", num));
94 BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(vpblock.empty() ? nullptr : vpblock.back()) == 0, strprintf("Test %i for StateSinceHeight (always active)", num));
97 num++;
98 return *this;
101 VersionBitsTester& TestDefined() {
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_DEFINED, strprintf("Test %i for DEFINED", num));
105 BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE (always active)", num));
108 num++;
109 return *this;
112 VersionBitsTester& TestStarted() {
113 for (int i = 0; i < CHECKERS; i++) {
114 if (InsecureRandBits(i) == 0) {
115 BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_STARTED, strprintf("Test %i for STARTED", num));
116 BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE (always active)", num));
119 num++;
120 return *this;
123 VersionBitsTester& TestLockedIn() {
124 for (int i = 0; i < CHECKERS; i++) {
125 if (InsecureRandBits(i) == 0) {
126 BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_LOCKED_IN, strprintf("Test %i for LOCKED_IN", num));
127 BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE (always active)", num));
130 num++;
131 return *this;
134 VersionBitsTester& TestActive() {
135 for (int i = 0; i < CHECKERS; i++) {
136 if (InsecureRandBits(i) == 0) {
137 BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE", num));
138 BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE (always active)", num));
141 num++;
142 return *this;
145 VersionBitsTester& TestFailed() {
146 for (int i = 0; i < CHECKERS; i++) {
147 if (InsecureRandBits(i) == 0) {
148 BOOST_CHECK_MESSAGE(checker[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_FAILED, strprintf("Test %i for FAILED", num));
149 BOOST_CHECK_MESSAGE(checker_always[i].GetStateFor(vpblock.empty() ? nullptr : vpblock.back()) == THRESHOLD_ACTIVE, strprintf("Test %i for ACTIVE (always active)", num));
152 num++;
153 return *this;
156 CBlockIndex * Tip() { return vpblock.size() ? vpblock.back() : nullptr; }
159 BOOST_FIXTURE_TEST_SUITE(versionbits_tests, TestingSetup)
161 BOOST_AUTO_TEST_CASE(versionbits_test)
163 for (int i = 0; i < 64; i++) {
164 // DEFINED -> FAILED
165 VersionBitsTester().TestDefined().TestStateSinceHeight(0)
166 .Mine(1, TestTime(1), 0x100).TestDefined().TestStateSinceHeight(0)
167 .Mine(11, TestTime(11), 0x100).TestDefined().TestStateSinceHeight(0)
168 .Mine(989, TestTime(989), 0x100).TestDefined().TestStateSinceHeight(0)
169 .Mine(999, TestTime(20000), 0x100).TestDefined().TestStateSinceHeight(0)
170 .Mine(1000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(1000)
171 .Mine(1999, TestTime(30001), 0x100).TestFailed().TestStateSinceHeight(1000)
172 .Mine(2000, TestTime(30002), 0x100).TestFailed().TestStateSinceHeight(1000)
173 .Mine(2001, TestTime(30003), 0x100).TestFailed().TestStateSinceHeight(1000)
174 .Mine(2999, TestTime(30004), 0x100).TestFailed().TestStateSinceHeight(1000)
175 .Mine(3000, TestTime(30005), 0x100).TestFailed().TestStateSinceHeight(1000)
177 // DEFINED -> STARTED -> FAILED
178 .Reset().TestDefined().TestStateSinceHeight(0)
179 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
180 .Mine(1000, TestTime(10000) - 1, 0x100).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
181 .Mine(2000, TestTime(10000), 0x100).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
182 .Mine(2051, TestTime(10010), 0).TestStarted().TestStateSinceHeight(2000) // 51 old blocks
183 .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 899 new blocks
184 .Mine(3000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(3000) // 50 old blocks (so 899 out of the past 1000)
185 .Mine(4000, TestTime(20010), 0x100).TestFailed().TestStateSinceHeight(3000)
187 // DEFINED -> STARTED -> FAILED while threshold reached
188 .Reset().TestDefined().TestStateSinceHeight(0)
189 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
190 .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
191 .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
192 .Mine(2999, TestTime(30000), 0x100).TestStarted().TestStateSinceHeight(2000) // 999 new blocks
193 .Mine(3000, TestTime(30000), 0x100).TestFailed().TestStateSinceHeight(3000) // 1 new block (so 1000 out of the past 1000 are new)
194 .Mine(3999, TestTime(30001), 0).TestFailed().TestStateSinceHeight(3000)
195 .Mine(4000, TestTime(30002), 0).TestFailed().TestStateSinceHeight(3000)
196 .Mine(14333, TestTime(30003), 0).TestFailed().TestStateSinceHeight(3000)
197 .Mine(24000, TestTime(40000), 0).TestFailed().TestStateSinceHeight(3000)
199 // DEFINED -> STARTED -> LOCKEDIN at the last minute -> ACTIVE
200 .Reset().TestDefined()
201 .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
202 .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
203 .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
204 .Mine(2050, TestTime(10010), 0x200).TestStarted().TestStateSinceHeight(2000) // 50 old blocks
205 .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 900 new blocks
206 .Mine(2999, TestTime(19999), 0x200).TestStarted().TestStateSinceHeight(2000) // 49 old blocks
207 .Mine(3000, TestTime(29999), 0x200).TestLockedIn().TestStateSinceHeight(3000) // 1 old block (so 900 out of the past 1000)
208 .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
209 .Mine(4000, TestTime(30002), 0).TestActive().TestStateSinceHeight(4000)
210 .Mine(14333, TestTime(30003), 0).TestActive().TestStateSinceHeight(4000)
211 .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000)
213 // DEFINED multiple periods -> STARTED multiple periods -> FAILED
214 .Reset().TestDefined().TestStateSinceHeight(0)
215 .Mine(999, TestTime(999), 0).TestDefined().TestStateSinceHeight(0)
216 .Mine(1000, TestTime(1000), 0).TestDefined().TestStateSinceHeight(0)
217 .Mine(2000, TestTime(2000), 0).TestDefined().TestStateSinceHeight(0)
218 .Mine(3000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
219 .Mine(4000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
220 .Mine(5000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
221 .Mine(6000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(6000)
222 .Mine(7000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000);
225 // Sanity checks of version bit deployments
226 const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
227 const Consensus::Params &mainnetParams = chainParams->GetConsensus();
228 for (int i=0; i<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; i++) {
229 uint32_t bitmask = VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)i);
230 // Make sure that no deployment tries to set an invalid bit.
231 BOOST_CHECK_EQUAL(bitmask & ~(uint32_t)VERSIONBITS_TOP_MASK, bitmask);
233 // Verify that the deployment windows of different deployment using the
234 // same bit are disjoint.
235 // This test may need modification at such time as a new deployment
236 // is proposed that reuses the bit of an activated soft fork, before the
237 // end time of that soft fork. (Alternatively, the end time of that
238 // activated soft fork could be later changed to be earlier to avoid
239 // overlap.)
240 for (int j=i+1; j<(int) Consensus::MAX_VERSION_BITS_DEPLOYMENTS; j++) {
241 if (VersionBitsMask(mainnetParams, (Consensus::DeploymentPos)j) == bitmask) {
242 BOOST_CHECK(mainnetParams.vDeployments[j].nStartTime > mainnetParams.vDeployments[i].nTimeout ||
243 mainnetParams.vDeployments[i].nStartTime > mainnetParams.vDeployments[j].nTimeout);
249 BOOST_AUTO_TEST_CASE(versionbits_computeblockversion)
251 // Check that ComputeBlockVersion will set the appropriate bit correctly
252 // on mainnet.
253 const auto chainParams = CreateChainParams(CBaseChainParams::MAIN);
254 const Consensus::Params &mainnetParams = chainParams->GetConsensus();
256 // Use the TESTDUMMY deployment for testing purposes.
257 int64_t bit = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit;
258 int64_t nStartTime = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime;
259 int64_t nTimeout = mainnetParams.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout;
261 assert(nStartTime < nTimeout);
263 // In the first chain, test that the bit is set by CBV until it has failed.
264 // In the second chain, test the bit is set by CBV while STARTED and
265 // LOCKED-IN, and then no longer set while ACTIVE.
266 VersionBitsTester firstChain, secondChain;
268 // Start generating blocks before nStartTime
269 int64_t nTime = nStartTime - 1;
271 // Before MedianTimePast of the chain has crossed nStartTime, the bit
272 // should not be set.
273 CBlockIndex *lastBlock = nullptr;
274 lastBlock = firstChain.Mine(2016, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
275 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
277 // Mine 2011 more blocks at the old time, and check that CBV isn't setting the bit yet.
278 for (int i=1; i<2012; i++) {
279 lastBlock = firstChain.Mine(2016+i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
280 // This works because VERSIONBITS_LAST_OLD_BLOCK_VERSION happens
281 // to be 4, and the bit we're testing happens to be bit 28.
282 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
284 // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
285 // CBV should still not yet set the bit.
286 nTime = nStartTime;
287 for (int i=2012; i<=2016; i++) {
288 lastBlock = firstChain.Mine(2016+i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
289 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
292 // Advance to the next period and transition to STARTED,
293 lastBlock = firstChain.Mine(6048, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
294 // so ComputeBlockVersion should now set the bit,
295 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
296 // and should also be using the VERSIONBITS_TOP_BITS.
297 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
299 // Check that ComputeBlockVersion will set the bit until nTimeout
300 nTime += 600;
301 int blocksToMine = 4032; // test blocks for up to 2 time periods
302 int nHeight = 6048;
303 // These blocks are all before nTimeout is reached.
304 while (nTime < nTimeout && blocksToMine > 0) {
305 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
306 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
307 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
308 blocksToMine--;
309 nTime += 600;
310 nHeight += 1;
313 nTime = nTimeout;
314 // FAILED is only triggered at the end of a period, so CBV should be setting
315 // the bit until the period transition.
316 for (int i=0; i<2015; i++) {
317 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
318 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
319 nHeight += 1;
321 // The next block should trigger no longer setting the bit.
322 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
323 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
325 // On a new chain:
326 // verify that the bit will be set after lock-in, and then stop being set
327 // after activation.
328 nTime = nStartTime;
330 // Mine one period worth of blocks, and check that the bit will be on for the
331 // next period.
332 lastBlock = secondChain.Mine(2016, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
333 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
335 // Mine another period worth of blocks, signaling the new bit.
336 lastBlock = secondChain.Mine(4032, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
337 // After one period of setting the bit on each block, it should have locked in.
338 // We keep setting the bit for one more period though, until activation.
339 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
341 // Now check that we keep mining the block until the end of this period, and
342 // then stop at the beginning of the next period.
343 lastBlock = secondChain.Mine(6047, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
344 BOOST_CHECK((ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit)) != 0);
345 lastBlock = secondChain.Mine(6048, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
346 BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & (1<<bit), 0);
348 // Finally, verify that after a soft fork has activated, CBV no longer uses
349 // VERSIONBITS_LAST_OLD_BLOCK_VERSION.
350 //BOOST_CHECK_EQUAL(ComputeBlockVersion(lastBlock, mainnetParams) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
354 BOOST_AUTO_TEST_SUITE_END()