Branch data Line data Source code
1 : : // Copyright (c) 2014-2022 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.
4 : :
5 : : #include <chain.h>
6 : : #include <chainparams.h>
7 : : #include <consensus/params.h>
8 : : #include <test/util/random.h>
9 : : #include <test/util/setup_common.h>
10 : : #include <util/chaintype.h>
11 : : #include <versionbits.h>
12 : :
13 : : #include <boost/test/unit_test.hpp>
14 : :
15 : : /* Define a virtual block time, one block per 10 minutes after Nov 14 2014, 0:55:36am */
16 : 142696 : static int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; }
17 : :
18 : 40752 : static std::string StateName(ThresholdState state)
19 : : {
20 [ + + + + : 40752 : switch (state) {
+ - ]
21 : 9048 : case ThresholdState::DEFINED: return "DEFINED";
22 : 7548 : case ThresholdState::STARTED: return "STARTED";
23 : 2972 : case ThresholdState::LOCKED_IN: return "LOCKED_IN";
24 : 9272 : case ThresholdState::ACTIVE: return "ACTIVE";
25 : 11912 : case ThresholdState::FAILED: return "FAILED";
26 : : } // no default case, so the compiler can warn about missing cases
27 : 0 : return "";
28 : : }
29 : :
30 : : static const Consensus::Params paramsDummy = Consensus::Params();
31 : :
32 : 444 : class TestConditionChecker : public AbstractThresholdConditionChecker
33 : : {
34 : : private:
35 : : mutable ThresholdConditionCache cache;
36 : :
37 : : public:
38 : 70599 : int64_t BeginTime(const Consensus::Params& params) const override { return TestTime(10000); }
39 : 70753 : int64_t EndTime(const Consensus::Params& params) const override { return TestTime(20000); }
40 : 79871 : int Period(const Consensus::Params& params) const override { return 1000; }
41 : 70753 : int Threshold(const Consensus::Params& params) const override { return 900; }
42 : 3750000 : bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override { return (pindex->nVersion & 0x100); }
43 : :
44 : 27168 : ThresholdState GetStateFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateFor(pindexPrev, paramsDummy, cache); }
45 [ + - + - : 26860 : int GetStateSinceHeightFor(const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor(pindexPrev, paramsDummy, cache); }
+ - + - ]
46 : : };
47 : :
48 : 444 : class TestDelayedActivationConditionChecker : public TestConditionChecker
49 : : {
50 : : public:
51 : 26738 : int MinActivationHeight(const Consensus::Params& params) const override { return 15000; }
52 : : };
53 : :
54 : 444 : class TestAlwaysActiveConditionChecker : public TestConditionChecker
55 : : {
56 : : public:
57 : 13507 : int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::ALWAYS_ACTIVE; }
58 : : };
59 : :
60 : 444 : class TestNeverActiveConditionChecker : public TestConditionChecker
61 : : {
62 : : public:
63 : 13507 : int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::NEVER_ACTIVE; }
64 : : };
65 : :
66 : : #define CHECKERS 6
67 : :
68 : : class VersionBitsTester
69 : : {
70 : : FastRandomContext& m_rng;
71 : : // A fake blockchain
72 : : std::vector<CBlockIndex*> vpblock;
73 : :
74 : : // 6 independent checkers for the same bit.
75 : : // The first one performs all checks, the second only 50%, the third only 25%, etc...
76 : : // This is to test whether lack of cached information leads to the same results.
77 : : TestConditionChecker checker[CHECKERS];
78 : : // Another 6 that assume delayed activation
79 : : TestDelayedActivationConditionChecker checker_delayed[CHECKERS];
80 : : // Another 6 that assume always active activation
81 : : TestAlwaysActiveConditionChecker checker_always[CHECKERS];
82 : : // Another 6 that assume never active activation
83 : : TestNeverActiveConditionChecker checker_never[CHECKERS];
84 : :
85 : : // Test counter (to identify failures)
86 : : int num{1000};
87 : :
88 : : public:
89 [ + + + + : 1850 : VersionBitsTester(FastRandomContext& rng) : m_rng{rng} {}
+ + + + ]
90 : :
91 : 330 : VersionBitsTester& Reset() {
92 : : // Have each group of tests be counted by the 1000s part, starting at 1000
93 : 330 : num = num - (num % 1000) + 1000;
94 : :
95 [ + + ]: 6266714 : for (unsigned int i = 0; i < vpblock.size(); i++) {
96 [ + - ]: 6266384 : delete vpblock[i];
97 : : }
98 [ + + ]: 2310 : for (unsigned int i = 0; i < CHECKERS; i++) {
99 : 1980 : checker[i] = TestConditionChecker();
100 : 1980 : checker_delayed[i] = TestDelayedActivationConditionChecker();
101 : 1980 : checker_always[i] = TestAlwaysActiveConditionChecker();
102 : 1980 : checker_never[i] = TestNeverActiveConditionChecker();
103 : : }
104 [ + - ]: 330 : vpblock.clear();
105 : 330 : return *this;
106 : : }
107 : :
108 [ + - + - : 2072 : ~VersionBitsTester() {
+ - + - ]
109 : 74 : Reset();
110 [ + + + + : 2146 : }
+ + + + ]
111 : :
112 : 20739 : VersionBitsTester& Mine(unsigned int height, int32_t nTime, int32_t nVersion) {
113 [ + + ]: 6287123 : while (vpblock.size() < height) {
114 : 6266384 : CBlockIndex* pindex = new CBlockIndex();
115 : 6266384 : pindex->nHeight = vpblock.size();
116 : 6266384 : pindex->pprev = Tip();
117 : 6266384 : pindex->nTime = nTime;
118 : 6266384 : pindex->nVersion = nVersion;
119 : 6266384 : pindex->BuildSkip();
120 : 6266384 : vpblock.push_back(pindex);
121 : : }
122 : 20739 : return *this;
123 : : }
124 : :
125 : 2944 : VersionBitsTester& TestStateSinceHeight(int height)
126 : : {
127 : 2944 : return TestStateSinceHeight(height, height);
128 : : }
129 : :
130 : 3392 : VersionBitsTester& TestStateSinceHeight(int height, int height_delayed)
131 : : {
132 : 3392 : const CBlockIndex* tip = Tip();
133 [ + + ]: 23744 : for (int i = 0; i < CHECKERS; i++) {
134 [ + + ]: 20352 : if (m_rng.randbits(i) == 0) {
135 [ + - + - ]: 13430 : BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(tip) == height, strprintf("Test %i for StateSinceHeight", num));
136 [ + - + - ]: 13430 : BOOST_CHECK_MESSAGE(checker_delayed[i].GetStateSinceHeightFor(tip) == height_delayed, strprintf("Test %i for StateSinceHeight (delayed)", num));
137 [ + - + - ]: 13430 : BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (always active)", num));
138 [ + - + - ]: 13430 : BOOST_CHECK_MESSAGE(checker_never[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (never active)", num));
139 : : }
140 : : }
141 : 3392 : num++;
142 : 3392 : return *this;
143 : : }
144 : :
145 : 3200 : VersionBitsTester& TestState(ThresholdState exp)
146 : : {
147 : 3200 : return TestState(exp, exp);
148 : : }
149 : :
150 : 3456 : VersionBitsTester& TestState(ThresholdState exp, ThresholdState exp_delayed)
151 : : {
152 [ + + ]: 3456 : if (exp != exp_delayed) {
153 : : // only expected differences are that delayed stays in locked_in longer
154 [ + - ]: 256 : BOOST_CHECK_EQUAL(exp, ThresholdState::ACTIVE);
155 [ + - ]: 256 : BOOST_CHECK_EQUAL(exp_delayed, ThresholdState::LOCKED_IN);
156 : : }
157 : :
158 : 3456 : const CBlockIndex* pindex = Tip();
159 [ + + ]: 24192 : for (int i = 0; i < CHECKERS; i++) {
160 [ + + ]: 20736 : if (m_rng.randbits(i) == 0) {
161 : 6792 : ThresholdState got = checker[i].GetStateFor(pindex);
162 : 6792 : ThresholdState got_delayed = checker_delayed[i].GetStateFor(pindex);
163 : 6792 : ThresholdState got_always = checker_always[i].GetStateFor(pindex);
164 : 6792 : ThresholdState got_never = checker_never[i].GetStateFor(pindex);
165 : : // nHeight of the next block. If vpblock is empty, the next (ie first)
166 : : // block should be the genesis block with nHeight == 0.
167 [ + + ]: 6792 : int height = pindex == nullptr ? 0 : pindex->nHeight + 1;
168 [ + - + - : 13584 : BOOST_CHECK_MESSAGE(got == exp, strprintf("Test %i for %s height %d (got %s)", num, StateName(exp), height, StateName(got)));
+ - ]
169 [ + - + - : 13584 : BOOST_CHECK_MESSAGE(got_delayed == exp_delayed, strprintf("Test %i for %s height %d (got %s; delayed case)", num, StateName(exp_delayed), height, StateName(got_delayed)));
+ - ]
170 [ + - + - ]: 13584 : BOOST_CHECK_MESSAGE(got_always == ThresholdState::ACTIVE, strprintf("Test %i for ACTIVE height %d (got %s; always active case)", num, height, StateName(got_always)));
171 [ + - + - ]: 13584 : BOOST_CHECK_MESSAGE(got_never == ThresholdState::FAILED, strprintf("Test %i for FAILED height %d (got %s; never active case)", num, height, StateName(got_never)));
172 : : }
173 : : }
174 : 3456 : num++;
175 : 3456 : return *this;
176 : : }
177 : :
178 : 2304 : VersionBitsTester& TestDefined() { return TestState(ThresholdState::DEFINED); }
179 : 1920 : VersionBitsTester& TestStarted() { return TestState(ThresholdState::STARTED); }
180 : 512 : VersionBitsTester& TestLockedIn() { return TestState(ThresholdState::LOCKED_IN); }
181 : 384 : VersionBitsTester& TestActive() { return TestState(ThresholdState::ACTIVE); }
182 : 1280 : VersionBitsTester& TestFailed() { return TestState(ThresholdState::FAILED); }
183 : :
184 : : // non-delayed should be active; delayed should still be locked in
185 : 256 : VersionBitsTester& TestActiveDelayed() { return TestState(ThresholdState::ACTIVE, ThresholdState::LOCKED_IN); }
186 : :
187 [ + + ]: 6290835 : CBlockIndex* Tip() { return vpblock.empty() ? nullptr : vpblock.back(); }
188 : : };
189 : :
190 : : BOOST_FIXTURE_TEST_SUITE(versionbits_tests, BasicTestingSetup)
191 : :
192 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(versionbits_test)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
193 : : {
194 [ + + ]: 65 : for (int i = 0; i < 64; i++) {
195 : : // DEFINED -> STARTED after timeout reached -> FAILED
196 [ + - + - ]: 64 : VersionBitsTester(m_rng).TestDefined().TestStateSinceHeight(0)
197 [ + - + - : 64 : .Mine(1, TestTime(1), 0x100).TestDefined().TestStateSinceHeight(0)
+ - ]
198 [ + - + - : 64 : .Mine(11, TestTime(11), 0x100).TestDefined().TestStateSinceHeight(0)
+ - ]
199 [ + - + - : 64 : .Mine(989, TestTime(989), 0x100).TestDefined().TestStateSinceHeight(0)
+ - ]
200 [ + - + - : 64 : .Mine(999, TestTime(20000), 0x100).TestDefined().TestStateSinceHeight(0) // Timeout and start time reached simultaneously
+ - ]
201 [ + - + - : 64 : .Mine(1000, TestTime(20000), 0).TestStarted().TestStateSinceHeight(1000) // Hit started, stop signalling
+ - ]
202 [ + - + - : 64 : .Mine(1999, TestTime(30001), 0).TestStarted().TestStateSinceHeight(1000)
+ - ]
203 [ + - + - : 64 : .Mine(2000, TestTime(30002), 0x100).TestFailed().TestStateSinceHeight(2000) // Hit failed, start signalling again
+ - ]
204 [ + - + - : 64 : .Mine(2001, TestTime(30003), 0x100).TestFailed().TestStateSinceHeight(2000)
+ - ]
205 [ + - + - : 64 : .Mine(2999, TestTime(30004), 0x100).TestFailed().TestStateSinceHeight(2000)
+ - ]
206 [ + - + - : 64 : .Mine(3000, TestTime(30005), 0x100).TestFailed().TestStateSinceHeight(2000)
+ - ]
207 [ + - + - : 64 : .Mine(4000, TestTime(30006), 0x100).TestFailed().TestStateSinceHeight(2000)
+ - ]
208 : :
209 : : // DEFINED -> STARTED -> FAILED
210 [ + - + - ]: 64 : .Reset().TestDefined().TestStateSinceHeight(0)
211 [ + - + - : 64 : .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
+ - ]
212 [ + - + - : 64 : .Mine(1000, TestTime(10000) - 1, 0x100).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
+ - ]
213 [ + - + - : 64 : .Mine(2000, TestTime(10000), 0x100).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
+ - ]
214 [ + - + - : 64 : .Mine(2051, TestTime(10010), 0).TestStarted().TestStateSinceHeight(2000) // 51 old blocks
+ - ]
215 [ + - + - : 64 : .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 899 new blocks
+ - ]
216 [ + - + - : 64 : .Mine(3000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(3000) // 50 old blocks (so 899 out of the past 1000)
+ - ]
217 [ + - + - : 64 : .Mine(4000, TestTime(20010), 0x100).TestFailed().TestStateSinceHeight(3000)
+ - ]
218 : :
219 : : // DEFINED -> STARTED -> LOCKEDIN after timeout reached -> ACTIVE
220 [ + - + - ]: 64 : .Reset().TestDefined().TestStateSinceHeight(0)
221 [ + - + - : 64 : .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
+ - ]
222 [ + - + - : 64 : .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
+ - ]
223 [ + - + - : 64 : .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
+ - ]
224 [ + - + - : 64 : .Mine(2999, TestTime(30000), 0x100).TestStarted().TestStateSinceHeight(2000) // 999 new blocks
+ - ]
225 [ + - + - : 64 : .Mine(3000, TestTime(30000), 0x100).TestLockedIn().TestStateSinceHeight(3000) // 1 new block (so 1000 out of the past 1000 are new)
+ - ]
226 [ + - + - : 64 : .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
+ - ]
227 [ + - + - : 64 : .Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
+ - ]
228 [ + - + - : 64 : .Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
+ - ]
229 [ + - + - : 64 : .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
+ - ]
230 : :
231 : : // DEFINED -> STARTED -> LOCKEDIN before timeout -> ACTIVE
232 [ + - ]: 64 : .Reset().TestDefined()
233 [ + - + - : 64 : .Mine(1, TestTime(1), 0).TestDefined().TestStateSinceHeight(0)
+ - ]
234 [ + - + - : 64 : .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
+ - ]
235 [ + - + - : 64 : .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
+ - ]
236 [ + - + - : 64 : .Mine(2050, TestTime(10010), 0x200).TestStarted().TestStateSinceHeight(2000) // 50 old blocks
+ - ]
237 [ + - + - : 64 : .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 900 new blocks
+ - ]
238 [ + - + - : 64 : .Mine(2999, TestTime(19999), 0x200).TestStarted().TestStateSinceHeight(2000) // 49 old blocks
+ - ]
239 [ + - + - : 64 : .Mine(3000, TestTime(29999), 0x200).TestLockedIn().TestStateSinceHeight(3000) // 1 old block (so 900 out of the past 1000)
+ - ]
240 [ + - + - : 64 : .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
+ - ]
241 [ + - + - : 64 : .Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000) // delayed will not become active until height=15000
+ - ]
242 [ + - + - : 64 : .Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
+ - ]
243 [ + - + - : 64 : .Mine(15000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
+ - ]
244 [ + - + - : 64 : .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
+ - ]
245 : :
246 : : // DEFINED multiple periods -> STARTED multiple periods -> FAILED
247 [ + - + - ]: 64 : .Reset().TestDefined().TestStateSinceHeight(0)
248 [ + - + - : 64 : .Mine(999, TestTime(999), 0).TestDefined().TestStateSinceHeight(0)
+ - ]
249 [ + - + - : 64 : .Mine(1000, TestTime(1000), 0).TestDefined().TestStateSinceHeight(0)
+ - ]
250 [ + - + - : 64 : .Mine(2000, TestTime(2000), 0).TestDefined().TestStateSinceHeight(0)
+ - ]
251 [ + - + - : 64 : .Mine(3000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
+ - ]
252 [ + - + - : 64 : .Mine(4000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
+ - ]
253 [ + - + - : 64 : .Mine(5000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
+ - ]
254 [ + - + - : 64 : .Mine(5999, TestTime(20000), 0).TestStarted().TestStateSinceHeight(3000)
+ - ]
255 [ + - + - : 64 : .Mine(6000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(6000)
+ - ]
256 [ + - + - : 64 : .Mine(7000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000)
+ - ]
257 [ + - + - : 64 : .Mine(24000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000) // stay in FAILED no matter how much we signal
+ - ]
258 : : ;
259 : : }
260 : 1 : }
261 : :
262 : 2 : struct BlockVersionTest : BasicTestingSetup {
263 : : /** Check that ComputeBlockVersion will set the appropriate bit correctly */
264 : 12 : void check_computeblockversion(VersionBitsCache& versionbitscache, const Consensus::Params& params, Consensus::DeploymentPos dep)
265 : : {
266 : : // Clear the cache every time
267 : 12 : versionbitscache.Clear();
268 : :
269 : 12 : int64_t bit = params.vDeployments[dep].bit;
270 : 12 : int64_t nStartTime = params.vDeployments[dep].nStartTime;
271 : 12 : int64_t nTimeout = params.vDeployments[dep].nTimeout;
272 : 12 : int min_activation_height = params.vDeployments[dep].min_activation_height;
273 : :
274 : : // should not be any signalling for first block
275 [ + - ]: 12 : BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
276 : :
277 : : // always/never active deployments shouldn't need to be tested further
278 [ + + ]: 12 : if (nStartTime == Consensus::BIP9Deployment::ALWAYS_ACTIVE ||
279 : : nStartTime == Consensus::BIP9Deployment::NEVER_ACTIVE)
280 : : {
281 [ + - ]: 7 : BOOST_CHECK_EQUAL(min_activation_height, 0);
282 [ + - ]: 7 : BOOST_CHECK_EQUAL(nTimeout, Consensus::BIP9Deployment::NO_TIMEOUT);
283 : 7 : return;
284 : : }
285 : :
286 [ + - ]: 10 : BOOST_REQUIRE(nStartTime < nTimeout);
287 [ + - ]: 10 : BOOST_REQUIRE(nStartTime >= 0);
288 [ + - ]: 10 : BOOST_REQUIRE(nTimeout <= std::numeric_limits<uint32_t>::max() || nTimeout == Consensus::BIP9Deployment::NO_TIMEOUT);
289 [ + - ]: 10 : BOOST_REQUIRE(0 <= bit && bit < 32);
290 : : // Make sure that no deployment tries to set an invalid bit.
291 [ + - ]: 10 : BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0);
292 [ + - ]: 10 : BOOST_REQUIRE(min_activation_height >= 0);
293 : : // Check min_activation_height is on a retarget boundary
294 [ + - ]: 5 : BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U);
295 : :
296 : 5 : const uint32_t bitmask{versionbitscache.Mask(params, dep)};
297 [ + - ]: 5 : BOOST_CHECK_EQUAL(bitmask, uint32_t{1} << bit);
298 : :
299 : : // In the first chain, test that the bit is set by CBV until it has failed.
300 : : // In the second chain, test the bit is set by CBV while STARTED and
301 : : // LOCKED-IN, and then no longer set while ACTIVE.
302 : 5 : VersionBitsTester firstChain{m_rng}, secondChain{m_rng};
303 : :
304 : 5 : int64_t nTime = nStartTime;
305 : :
306 : 5 : const CBlockIndex *lastBlock = nullptr;
307 : :
308 : : // Before MedianTimePast of the chain has crossed nStartTime, the bit
309 : : // should not be set.
310 [ + + ]: 5 : if (nTime == 0) {
311 : : // since CBlockIndex::nTime is uint32_t we can't represent any
312 : : // earlier time, so will transition from DEFINED to STARTED at the
313 : : // end of the first period by mining blocks at nTime == 0
314 [ + - ]: 1 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
315 [ + - + - : 1 : BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ - ]
316 [ + - ]: 1 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
317 [ + - + - : 2 : BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ - ]
318 : : // then we'll keep mining at nStartTime...
319 : : } else {
320 : : // use a time 1s earlier than start time to check we stay DEFINED
321 : 4 : --nTime;
322 : :
323 : : // Start generating blocks before nStartTime
324 [ + - ]: 4 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
325 [ + - + - : 4 : BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ - ]
326 : :
327 : : // Mine more blocks (4 less than the adjustment period) at the old time, and check that CBV isn't setting the bit yet.
328 [ + + ]: 4304 : for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
329 [ + - ]: 4300 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
330 [ + - + - : 4300 : BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ - ]
331 : : }
332 : : // Now mine 5 more blocks at the start time -- MTP should not have passed yet, so
333 : : // CBV should still not yet set the bit.
334 : 24 : nTime = nStartTime;
335 [ + + ]: 24 : for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
336 [ + - ]: 20 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
337 [ + - + - : 20 : BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ - ]
338 : : }
339 : : // Next we will advance to the next period and transition to STARTED,
340 : : }
341 : :
342 [ + - ]: 5 : lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
343 : : // so ComputeBlockVersion should now set the bit,
344 [ + - + - : 10 : BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ - + - ]
345 : : // and should also be using the VERSIONBITS_TOP_BITS.
346 [ + - + - : 5 : BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
+ - ]
347 : :
348 : : // Check that ComputeBlockVersion will set the bit until nTimeout
349 : 5 : nTime += 600;
350 : 5 : uint32_t blocksToMine = params.nMinerConfirmationWindow * 2; // test blocks for up to 2 time periods
351 : 5 : uint32_t nHeight = params.nMinerConfirmationWindow * 3;
352 : : // These blocks are all before nTimeout is reached.
353 [ + - + + ]: 8933 : while (nTime < nTimeout && blocksToMine > 0) {
354 [ + - ]: 8928 : lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
355 [ + - + - : 17856 : BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ - + - ]
356 [ + - + - : 8928 : BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & VERSIONBITS_TOP_MASK, VERSIONBITS_TOP_BITS);
+ - ]
357 : 8928 : blocksToMine--;
358 : 8928 : nTime += 600;
359 : 8928 : nHeight += 1;
360 : : }
361 : :
362 [ + + ]: 5 : if (nTimeout != Consensus::BIP9Deployment::NO_TIMEOUT) {
363 : : // can reach any nTimeout other than NO_TIMEOUT due to earlier BOOST_REQUIRE
364 : :
365 : 4 : nTime = nTimeout;
366 : :
367 : : // finish the last period before we start timing out
368 [ - + ]: 4 : while (nHeight % params.nMinerConfirmationWindow != 0) {
369 [ # # ]: 0 : lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
370 [ # # # # : 0 : BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
# # ]
371 : 0 : nHeight += 1;
372 : : }
373 : :
374 : : // FAILED is only triggered at the end of a period, so CBV should be setting
375 : : // the bit until the period transition.
376 [ + + ]: 4320 : for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
377 [ + - ]: 4316 : lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
378 [ + - + - : 8632 : BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ - ]
379 : 4316 : nHeight += 1;
380 : : }
381 : : // The next block should trigger no longer setting the bit.
382 [ + - ]: 4 : lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
383 [ + - + - : 4 : BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ - ]
384 : : }
385 : :
386 : : // On a new chain:
387 : : // verify that the bit will be set after lock-in, and then stop being set
388 : : // after activation.
389 : 5 : nTime = nStartTime;
390 : :
391 : : // Mine one period worth of blocks, and check that the bit will be on for the
392 : : // next period.
393 [ + - ]: 5 : lastBlock = secondChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
394 [ + - + - : 10 : BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ - + - ]
395 : :
396 : : // Mine another period worth of blocks, signaling the new bit.
397 [ + - ]: 5 : lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 2, nTime, VERSIONBITS_TOP_BITS | (1<<bit)).Tip();
398 : : // After one period of setting the bit on each block, it should have locked in.
399 : : // We keep setting the bit for one more period though, until activation.
400 [ + - + - : 10 : BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ - + - ]
401 : :
402 : : // Now check that we keep mining the block until the end of this period, and
403 : : // then stop at the beginning of the next period.
404 [ + - ]: 5 : lastBlock = secondChain.Mine((params.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
405 [ + - + - : 10 : BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ - + - ]
406 [ + - ]: 5 : lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
407 : :
408 [ + + ]: 5 : if (lastBlock->nHeight + 1 < min_activation_height) {
409 : : // check signalling continues while min_activation_height is not reached
410 [ + - ]: 2 : lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
411 [ + - + - : 4 : BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
+ - + - ]
412 : : // then reach min_activation_height, which was already REQUIRE'd to start a new period
413 [ + - ]: 2 : lastBlock = secondChain.Mine(min_activation_height, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
414 : : }
415 : :
416 : : // Check that we don't signal after activation
417 [ + - + - : 5 : BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
+ - ]
418 : 5 : }
419 : : }; // struct BlockVersionTest
420 : :
421 [ + - + - : 7 : BOOST_FIXTURE_TEST_CASE(versionbits_computeblockversion, BlockVersionTest)
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- ]
422 : : {
423 : 1 : VersionBitsCache vbcache;
424 : :
425 : : // check that any deployment on any chain can conceivably reach both
426 : : // ACTIVE and FAILED states in roughly the way we expect
427 [ + + ]: 6 : for (const auto& chain_type: {ChainType::MAIN, ChainType::TESTNET, ChainType::TESTNET4, ChainType::SIGNET, ChainType::REGTEST}) {
428 [ + - ]: 5 : const auto chainParams = CreateChainParams(*m_node.args, chain_type);
429 : : uint32_t chain_all_vbits{0};
430 [ + + ]: 15 : for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
431 : 10 : const auto dep = static_cast<Consensus::DeploymentPos>(i);
432 : : // Check that no bits are reused (within the same chain). This is
433 : : // disallowed because the transition to FAILED (on timeout) does
434 : : // not take precedence over STARTED/LOCKED_IN. So all softforks on
435 : : // the same bit might overlap, even when non-overlapping start-end
436 : : // times are picked.
437 [ + - ]: 10 : const uint32_t dep_mask{vbcache.Mask(chainParams->GetConsensus(), dep)};
438 [ + - + - : 20 : BOOST_CHECK(!(chain_all_vbits & dep_mask));
+ - ]
439 : 10 : chain_all_vbits |= dep_mask;
440 [ + - ]: 10 : check_computeblockversion(vbcache, chainParams->GetConsensus(), dep);
441 : : }
442 : 5 : }
443 : :
444 : 1 : {
445 : : // Use regtest/testdummy to ensure we always exercise some
446 : : // deployment that's not always/never active
447 [ + - ]: 1 : ArgsManager args;
448 [ + - + - : 2 : args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008
+ - ]
449 [ + - ]: 1 : const auto chainParams = CreateChainParams(args, ChainType::REGTEST);
450 [ + - ]: 1 : check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
451 : 1 : }
452 : :
453 : 1 : {
454 : : // Use regtest/testdummy to ensure we always exercise the
455 : : // min_activation_height test, even if we're not using that in a
456 : : // live deployment
457 [ + - ]: 1 : ArgsManager args;
458 [ + - + - : 2 : args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999:403200"); // January 1, 2008 - December 31, 2008, min act height 403200
+ - ]
459 [ + - ]: 1 : const auto chainParams = CreateChainParams(args, ChainType::REGTEST);
460 [ + - ]: 1 : check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
461 : 1 : }
462 : 1 : }
463 : :
464 : : BOOST_AUTO_TEST_SUITE_END()
|