Bitcoin Core 28.99.0
P2P Digital Currency
versionbits_tests.cpp
Go to the documentation of this file.
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>
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 */
16static int32_t TestTime(int nHeight) { return 1415926536 + 600 * nHeight; }
17
18static std::string StateName(ThresholdState state)
19{
20 switch (state) {
21 case ThresholdState::DEFINED: return "DEFINED";
22 case ThresholdState::STARTED: return "STARTED";
23 case ThresholdState::LOCKED_IN: return "LOCKED_IN";
24 case ThresholdState::ACTIVE: return "ACTIVE";
25 case ThresholdState::FAILED: return "FAILED";
26 } // no default case, so the compiler can warn about missing cases
27 return "";
28}
29
31
33{
34private:
36
37public:
38 int64_t BeginTime(const Consensus::Params& params) const override { return TestTime(10000); }
39 int64_t EndTime(const Consensus::Params& params) const override { return TestTime(20000); }
40 int Period(const Consensus::Params& params) const override { return 1000; }
41 int Threshold(const Consensus::Params& params) const override { return 900; }
42 bool Condition(const CBlockIndex* pindex, const Consensus::Params& params) const override { return (pindex->nVersion & 0x100); }
43
46};
47
49{
50public:
51 int MinActivationHeight(const Consensus::Params& params) const override { return 15000; }
52};
53
55{
56public:
57 int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::ALWAYS_ACTIVE; }
58};
59
61{
62public:
63 int64_t BeginTime(const Consensus::Params& params) const override { return Consensus::BIP9Deployment::NEVER_ACTIVE; }
64};
65
66#define CHECKERS 6
67
69{
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.
78 // Another 6 that assume delayed activation
80 // Another 6 that assume always active activation
82 // Another 6 that assume never active activation
84
85 // Test counter (to identify failures)
86 int num{1000};
87
88public:
90
92 // Have each group of tests be counted by the 1000s part, starting at 1000
93 num = num - (num % 1000) + 1000;
94
95 for (unsigned int i = 0; i < vpblock.size(); i++) {
96 delete vpblock[i];
97 }
98 for (unsigned int i = 0; i < CHECKERS; i++) {
103 }
104 vpblock.clear();
105 return *this;
106 }
107
109 Reset();
110 }
111
112 VersionBitsTester& Mine(unsigned int height, int32_t nTime, int32_t nVersion) {
113 while (vpblock.size() < height) {
114 CBlockIndex* pindex = new CBlockIndex();
115 pindex->nHeight = vpblock.size();
116 pindex->pprev = Tip();
117 pindex->nTime = nTime;
118 pindex->nVersion = nVersion;
119 pindex->BuildSkip();
120 vpblock.push_back(pindex);
121 }
122 return *this;
123 }
124
126 {
127 return TestStateSinceHeight(height, height);
128 }
129
130 VersionBitsTester& TestStateSinceHeight(int height, int height_delayed)
131 {
132 const CBlockIndex* tip = Tip();
133 for (int i = 0; i < CHECKERS; i++) {
134 if (m_rng.randbits(i) == 0) {
135 BOOST_CHECK_MESSAGE(checker[i].GetStateSinceHeightFor(tip) == height, strprintf("Test %i for StateSinceHeight", num));
136 BOOST_CHECK_MESSAGE(checker_delayed[i].GetStateSinceHeightFor(tip) == height_delayed, strprintf("Test %i for StateSinceHeight (delayed)", num));
137 BOOST_CHECK_MESSAGE(checker_always[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (always active)", num));
138 BOOST_CHECK_MESSAGE(checker_never[i].GetStateSinceHeightFor(tip) == 0, strprintf("Test %i for StateSinceHeight (never active)", num));
139 }
140 }
141 num++;
142 return *this;
143 }
144
146 {
147 return TestState(exp, exp);
148 }
149
151 {
152 if (exp != exp_delayed) {
153 // only expected differences are that delayed stays in locked_in longer
156 }
157
158 const CBlockIndex* pindex = Tip();
159 for (int i = 0; i < CHECKERS; i++) {
160 if (m_rng.randbits(i) == 0) {
161 ThresholdState got = checker[i].GetStateFor(pindex);
162 ThresholdState got_delayed = checker_delayed[i].GetStateFor(pindex);
163 ThresholdState got_always = checker_always[i].GetStateFor(pindex);
164 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 int height = pindex == nullptr ? 0 : pindex->nHeight + 1;
168 BOOST_CHECK_MESSAGE(got == exp, strprintf("Test %i for %s height %d (got %s)", num, StateName(exp), height, StateName(got)));
169 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 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 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 num++;
175 return *this;
176 }
177
183
184 // non-delayed should be active; delayed should still be locked in
186
187 CBlockIndex* Tip() { return vpblock.empty() ? nullptr : vpblock.back(); }
188};
189
191
192BOOST_AUTO_TEST_CASE(versionbits_test)
193{
194 for (int i = 0; i < 64; i++) {
195 // DEFINED -> STARTED after timeout reached -> FAILED
198 .Mine(11, TestTime(11), 0x100).TestDefined().TestStateSinceHeight(0)
199 .Mine(989, TestTime(989), 0x100).TestDefined().TestStateSinceHeight(0)
200 .Mine(999, TestTime(20000), 0x100).TestDefined().TestStateSinceHeight(0) // Timeout and start time reached simultaneously
201 .Mine(1000, TestTime(20000), 0).TestStarted().TestStateSinceHeight(1000) // Hit started, stop signalling
202 .Mine(1999, TestTime(30001), 0).TestStarted().TestStateSinceHeight(1000)
203 .Mine(2000, TestTime(30002), 0x100).TestFailed().TestStateSinceHeight(2000) // Hit failed, start signalling again
204 .Mine(2001, TestTime(30003), 0x100).TestFailed().TestStateSinceHeight(2000)
205 .Mine(2999, TestTime(30004), 0x100).TestFailed().TestStateSinceHeight(2000)
206 .Mine(3000, TestTime(30005), 0x100).TestFailed().TestStateSinceHeight(2000)
207 .Mine(4000, TestTime(30006), 0x100).TestFailed().TestStateSinceHeight(2000)
208
209 // DEFINED -> STARTED -> FAILED
212 .Mine(1000, TestTime(10000) - 1, 0x100).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
213 .Mine(2000, TestTime(10000), 0x100).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
214 .Mine(2051, TestTime(10010), 0).TestStarted().TestStateSinceHeight(2000) // 51 old blocks
215 .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 899 new blocks
216 .Mine(3000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(3000) // 50 old blocks (so 899 out of the past 1000)
217 .Mine(4000, TestTime(20010), 0x100).TestFailed().TestStateSinceHeight(3000)
218
219 // DEFINED -> STARTED -> LOCKEDIN after timeout reached -> ACTIVE
222 .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
223 .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
224 .Mine(2999, TestTime(30000), 0x100).TestStarted().TestStateSinceHeight(2000) // 999 new blocks
225 .Mine(3000, TestTime(30000), 0x100).TestLockedIn().TestStateSinceHeight(3000) // 1 new block (so 1000 out of the past 1000 are new)
226 .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
227 .Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
228 .Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
229 .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
230
231 // DEFINED -> STARTED -> LOCKEDIN before timeout -> ACTIVE
232 .Reset().TestDefined()
234 .Mine(1000, TestTime(10000) - 1, 0x101).TestDefined().TestStateSinceHeight(0) // One second more and it would be defined
235 .Mine(2000, TestTime(10000), 0x101).TestStarted().TestStateSinceHeight(2000) // So that's what happens the next period
236 .Mine(2050, TestTime(10010), 0x200).TestStarted().TestStateSinceHeight(2000) // 50 old blocks
237 .Mine(2950, TestTime(10020), 0x100).TestStarted().TestStateSinceHeight(2000) // 900 new blocks
238 .Mine(2999, TestTime(19999), 0x200).TestStarted().TestStateSinceHeight(2000) // 49 old blocks
239 .Mine(3000, TestTime(29999), 0x200).TestLockedIn().TestStateSinceHeight(3000) // 1 old block (so 900 out of the past 1000)
240 .Mine(3999, TestTime(30001), 0).TestLockedIn().TestStateSinceHeight(3000)
241 .Mine(4000, TestTime(30002), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000) // delayed will not become active until height=15000
242 .Mine(14333, TestTime(30003), 0).TestActiveDelayed().TestStateSinceHeight(4000, 3000)
243 .Mine(15000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
244 .Mine(24000, TestTime(40000), 0).TestActive().TestStateSinceHeight(4000, 15000)
245
246 // DEFINED multiple periods -> STARTED multiple periods -> FAILED
249 .Mine(1000, TestTime(1000), 0).TestDefined().TestStateSinceHeight(0)
250 .Mine(2000, TestTime(2000), 0).TestDefined().TestStateSinceHeight(0)
251 .Mine(3000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
252 .Mine(4000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
253 .Mine(5000, TestTime(10000), 0).TestStarted().TestStateSinceHeight(3000)
254 .Mine(5999, TestTime(20000), 0).TestStarted().TestStateSinceHeight(3000)
255 .Mine(6000, TestTime(20000), 0).TestFailed().TestStateSinceHeight(6000)
256 .Mine(7000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000)
257 .Mine(24000, TestTime(20000), 0x100).TestFailed().TestStateSinceHeight(6000) // stay in FAILED no matter how much we signal
258 ;
259 }
260}
261
265{
266 // Clear the cache every time
267 versionbitscache.Clear();
268
269 int64_t bit = params.vDeployments[dep].bit;
270 int64_t nStartTime = params.vDeployments[dep].nStartTime;
271 int64_t nTimeout = params.vDeployments[dep].nTimeout;
272 int min_activation_height = params.vDeployments[dep].min_activation_height;
273
274 // should not be any signalling for first block
275 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(nullptr, params), VERSIONBITS_TOP_BITS);
276
277 // always/never active deployments shouldn't need to be tested further
280 {
281 BOOST_CHECK_EQUAL(min_activation_height, 0);
283 return;
284 }
285
286 BOOST_REQUIRE(nStartTime < nTimeout);
287 BOOST_REQUIRE(nStartTime >= 0);
288 BOOST_REQUIRE(nTimeout <= std::numeric_limits<uint32_t>::max() || nTimeout == Consensus::BIP9Deployment::NO_TIMEOUT);
289 BOOST_REQUIRE(0 <= bit && bit < 32);
290 // Make sure that no deployment tries to set an invalid bit.
291 BOOST_REQUIRE(((1 << bit) & VERSIONBITS_TOP_MASK) == 0);
292 BOOST_REQUIRE(min_activation_height >= 0);
293 // Check min_activation_height is on a retarget boundary
294 BOOST_REQUIRE_EQUAL(min_activation_height % params.nMinerConfirmationWindow, 0U);
295
296 const uint32_t bitmask{versionbitscache.Mask(params, dep)};
297 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 VersionBitsTester firstChain{m_rng}, secondChain{m_rng};
303
304 int64_t nTime = nStartTime;
305
306 const CBlockIndex *lastBlock = nullptr;
307
308 // Before MedianTimePast of the chain has crossed nStartTime, the bit
309 // should not be set.
310 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 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
315 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
316 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
317 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 --nTime;
322
323 // Start generating blocks before nStartTime
324 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
325 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 for (uint32_t i = 1; i < params.nMinerConfirmationWindow - 4; i++) {
329 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
330 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 nTime = nStartTime;
335 for (uint32_t i = params.nMinerConfirmationWindow - 4; i <= params.nMinerConfirmationWindow; i++) {
336 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow + i, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
337 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 lastBlock = firstChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
343 // so ComputeBlockVersion should now set the bit,
344 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
345 // and should also be using the VERSIONBITS_TOP_BITS.
347
348 // Check that ComputeBlockVersion will set the bit until nTimeout
349 nTime += 600;
350 uint32_t blocksToMine = params.nMinerConfirmationWindow * 2; // test blocks for up to 2 time periods
351 uint32_t nHeight = params.nMinerConfirmationWindow * 3;
352 // These blocks are all before nTimeout is reached.
353 while (nTime < nTimeout && blocksToMine > 0) {
354 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
355 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
357 blocksToMine--;
358 nTime += 600;
359 nHeight += 1;
360 }
361
363 // can reach any nTimeout other than NO_TIMEOUT due to earlier BOOST_REQUIRE
364
365 nTime = nTimeout;
366
367 // finish the last period before we start timing out
368 while (nHeight % params.nMinerConfirmationWindow != 0) {
369 lastBlock = firstChain.Mine(nHeight+1, nTime - 1, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
370 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
371 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 for (uint32_t i = 0; i < params.nMinerConfirmationWindow - 1; i++) {
377 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
378 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
379 nHeight += 1;
380 }
381 // The next block should trigger no longer setting the bit.
382 lastBlock = firstChain.Mine(nHeight+1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
383 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 nTime = nStartTime;
390
391 // Mine one period worth of blocks, and check that the bit will be on for the
392 // next period.
393 lastBlock = secondChain.Mine(params.nMinerConfirmationWindow, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
394 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
395
396 // Mine another period worth of blocks, signaling the new bit.
397 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 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 lastBlock = secondChain.Mine((params.nMinerConfirmationWindow * 3) - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
405 BOOST_CHECK((versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit)) != 0);
406 lastBlock = secondChain.Mine(params.nMinerConfirmationWindow * 3, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
407
408 if (lastBlock->nHeight + 1 < min_activation_height) {
409 // check signalling continues while min_activation_height is not reached
410 lastBlock = secondChain.Mine(min_activation_height - 1, nTime, VERSIONBITS_LAST_OLD_BLOCK_VERSION).Tip();
411 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 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 BOOST_CHECK_EQUAL(versionbitscache.ComputeBlockVersion(lastBlock, params) & (1 << bit), 0);
418}
419}; // struct BlockVersionTest
420
421BOOST_FIXTURE_TEST_CASE(versionbits_computeblockversion, BlockVersionTest)
422{
423 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
428 const auto chainParams = CreateChainParams(*m_node.args, chain_type);
429 uint32_t chain_all_vbits{0};
430 for (int i = 0; i < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++i) {
431 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 const uint32_t dep_mask{vbcache.Mask(chainParams->GetConsensus(), dep)};
438 BOOST_CHECK(!(chain_all_vbits & dep_mask));
439 chain_all_vbits |= dep_mask;
440 check_computeblockversion(vbcache, chainParams->GetConsensus(), dep);
441 }
442 }
443
444 {
445 // Use regtest/testdummy to ensure we always exercise some
446 // deployment that's not always/never active
448 args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999"); // January 1, 2008 - December 31, 2008
449 const auto chainParams = CreateChainParams(args, ChainType::REGTEST);
450 check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
451 }
452
453 {
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
458 args.ForceSetArg("-vbparams", "testdummy:1199145601:1230767999:403200"); // January 1, 2008 - December 31, 2008, min act height 403200
459 const auto chainParams = CreateChainParams(args, ChainType::REGTEST);
460 check_computeblockversion(vbcache, chainParams->GetConsensus(), Consensus::DEPLOYMENT_TESTDUMMY);
461 }
462}
463
node::NodeContext m_node
Definition: bitcoin-gui.cpp:42
ArgsManager & args
Definition: bitcoind.cpp:277
std::unique_ptr< const CChainParams > CreateChainParams(const ArgsManager &args, const ChainType chain)
Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.
const CChainParams & Params()
Return the currently selected parameters.
Abstract class that implements BIP9-style threshold logic, and caches results.
Definition: versionbits.h:57
ThresholdState GetStateFor(const CBlockIndex *pindexPrev, const Consensus::Params &params, ThresholdConditionCache &cache) const
Returns the state for pindex A based on parent pindexPrev B.
Definition: versionbits.cpp:9
int GetStateSinceHeightFor(const CBlockIndex *pindexPrev, const Consensus::Params &params, ThresholdConditionCache &cache) const
Returns the height since when the ThresholdState has started for pindex A based on parent pindexPrev ...
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: args.cpp:546
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:141
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:147
void BuildSkip()
Build the skiplist pointer for this entry.
Definition: chain.cpp:125
uint32_t nTime
Definition: chain.h:189
int32_t nVersion
block header
Definition: chain.h:187
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:153
Fast randomness source.
Definition: random.h:377
uint64_t randbits(int bits) noexcept
Generate a random (bits)-bit integer.
Definition: random.h:204
int64_t BeginTime(const Consensus::Params &params) const override
ThresholdConditionCache cache
int Threshold(const Consensus::Params &params) const override
int Period(const Consensus::Params &params) const override
int64_t BeginTime(const Consensus::Params &params) const override
bool Condition(const CBlockIndex *pindex, const Consensus::Params &params) const override
ThresholdState GetStateFor(const CBlockIndex *pindexPrev) const
int64_t EndTime(const Consensus::Params &params) const override
int GetStateSinceHeightFor(const CBlockIndex *pindexPrev) const
int MinActivationHeight(const Consensus::Params &params) const override
int64_t BeginTime(const Consensus::Params &params) const override
BIP 9 allows multiple softforks to be deployed in parallel.
Definition: versionbits.h:81
int32_t ComputeBlockVersion(const CBlockIndex *pindexPrev, const Consensus::Params &params) EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
Determine what nVersion a new block should use.
static uint32_t Mask(const Consensus::Params &params, Consensus::DeploymentPos pos)
void Clear() EXCLUSIVE_LOCKS_REQUIRED(!m_mutex)
VersionBitsTester & TestState(ThresholdState exp, ThresholdState exp_delayed)
VersionBitsTester & TestStateSinceHeight(int height)
VersionBitsTester & TestActive()
VersionBitsTester & TestFailed()
VersionBitsTester & TestLockedIn()
VersionBitsTester & TestState(ThresholdState exp)
FastRandomContext & m_rng
VersionBitsTester & TestDefined()
TestDelayedActivationConditionChecker checker_delayed[CHECKERS]
VersionBitsTester & Mine(unsigned int height, int32_t nTime, int32_t nVersion)
VersionBitsTester & Reset()
VersionBitsTester & TestActiveDelayed()
std::vector< CBlockIndex * > vpblock
TestNeverActiveConditionChecker checker_never[CHECKERS]
TestConditionChecker checker[CHECKERS]
VersionBitsTester & TestStarted()
VersionBitsTester(FastRandomContext &rng)
TestAlwaysActiveConditionChecker checker_always[CHECKERS]
VersionBitsTester & TestStateSinceHeight(int height, int height_delayed)
BOOST_FIXTURE_TEST_SUITE(cuckoocache_tests, BasicTestingSetup)
Test Suite for CuckooCache.
BOOST_AUTO_TEST_SUITE_END()
unsigned int nHeight
DeploymentPos
Definition: params.h:32
@ DEPLOYMENT_TESTDUMMY
Definition: params.h:33
@ MAX_VERSION_BITS_DEPLOYMENTS
Definition: params.h:36
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
#define BOOST_CHECK(expr)
Definition: object.cpp:17
Basic testing setup.
Definition: setup_common.h:63
FastRandomContext m_rng
Definition: setup_common.h:67
void check_computeblockversion(VersionBitsCache &versionbitscache, const Consensus::Params &params, Consensus::DeploymentPos dep)
Check that ComputeBlockVersion will set the appropriate bit correctly.
int min_activation_height
If lock in occurs, delay activation until at least this block height.
Definition: params.h:54
int bit
Bit position to select the particular bit in nVersion.
Definition: params.h:45
static constexpr int64_t ALWAYS_ACTIVE
Special value for nStartTime indicating that the deployment is always active.
Definition: params.h:63
static constexpr int64_t NEVER_ACTIVE
Special value for nStartTime indicating that the deployment is never active.
Definition: params.h:68
int64_t nTimeout
Timeout/expiry MedianTime for the deployment attempt.
Definition: params.h:49
static constexpr int64_t NO_TIMEOUT
Constant for nTimeout very far in the future.
Definition: params.h:57
int64_t nStartTime
Start MedianTime for version bits miner confirmation.
Definition: params.h:47
Parameters that influence chain consensus.
Definition: params.h:74
uint32_t nMinerConfirmationWindow
Definition: params.h:106
BIP9Deployment vDeployments[MAX_VERSION_BITS_DEPLOYMENTS]
Definition: params.h:107
ArgsManager * args
Definition: context.h:74
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1165
std::map< const CBlockIndex *, ThresholdState > ThresholdConditionCache
Definition: versionbits.h:38
static const int32_t VERSIONBITS_TOP_BITS
What bits to set in version for versionbits blocks.
Definition: versionbits.h:16
static const int32_t VERSIONBITS_LAST_OLD_BLOCK_VERSION
What block version to use for new blocks (pre versionbits)
Definition: versionbits.h:14
static const int32_t VERSIONBITS_TOP_MASK
What bitmask determines whether versionbits is in use.
Definition: versionbits.h:18
ThresholdState
BIP 9 defines a finite-state-machine to deploy a softfork in multiple stages.
Definition: versionbits.h:27
#define CHECKERS
static const Consensus::Params paramsDummy
static std::string StateName(ThresholdState state)
BOOST_FIXTURE_TEST_CASE(versionbits_computeblockversion, BlockVersionTest)
static int32_t TestTime(int nHeight)
BOOST_AUTO_TEST_CASE(versionbits_test)