@@ -25,18 +25,18 @@ class TestConditionChecker : public AbstractThresholdConditionChecker
25
25
const Consensus::Params dummy_params{};
26
26
27
27
public:
28
- const int64_t m_begin = 0 ;
29
- const int64_t m_end = 0 ;
30
- const int m_period = 0 ;
31
- const int m_threshold = 0 ;
32
- const int m_bit = 0 ;
28
+ const int64_t m_begin;
29
+ const int64_t m_end;
30
+ const int m_period;
31
+ const int m_threshold;
32
+ const int m_bit;
33
33
34
34
TestConditionChecker (int64_t begin, int64_t end, int period, int threshold, int bit)
35
35
: m_begin{begin}, m_end{end}, m_period{period}, m_threshold{threshold}, m_bit{bit}
36
36
{
37
37
assert (m_period > 0 );
38
38
assert (0 <= m_threshold && m_threshold <= m_period);
39
- assert (0 <= m_bit && m_bit <= 32 && m_bit < VERSIONBITS_NUM_BITS);
39
+ assert (0 <= m_bit && m_bit < 32 && m_bit < VERSIONBITS_NUM_BITS);
40
40
}
41
41
42
42
bool Condition (const CBlockIndex* pindex, const Consensus::Params& params) const override { return Condition (pindex->nVersion ); }
@@ -49,9 +49,10 @@ class TestConditionChecker : public AbstractThresholdConditionChecker
49
49
int GetStateSinceHeightFor (const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateSinceHeightFor (pindexPrev, dummy_params, m_cache); }
50
50
BIP9Stats GetStateStatisticsFor (const CBlockIndex* pindexPrev) const { return AbstractThresholdConditionChecker::GetStateStatisticsFor (pindexPrev, dummy_params); }
51
51
52
- bool Condition (int64_t version) const
52
+ bool Condition (int32_t version) const
53
53
{
54
- return ((version >> m_bit) & 1 ) != 0 && (version & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS;
54
+ uint32_t mask = ((uint32_t )1 ) << m_bit;
55
+ return (((version & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS) && (version & mask) != 0 );
55
56
}
56
57
57
58
bool Condition (const CBlockIndex* pindex) const { return Condition (pindex->nVersion ); }
@@ -94,18 +95,20 @@ class Blocks
94
95
}
95
96
};
96
97
98
+ std::unique_ptr<const CChainParams> g_params;
99
+
97
100
void initialize ()
98
101
{
99
- SelectParams (CBaseChainParams::MAIN);
102
+ // this is actually comparatively slow, so only do it once
103
+ g_params = CreateChainParams (ArgsManager{}, CBaseChainParams::MAIN);
104
+ assert (g_params != nullptr );
100
105
}
101
- } // namespace
102
106
103
- constexpr uint32_t MAX_TIME = 4102444800 ; // 2100-01-01
107
+ constexpr uint32_t MAX_START_TIME = 4102444800 ; // 2100-01-01
104
108
105
109
FUZZ_TARGET_INIT (versionbits, initialize)
106
110
{
107
- const CChainParams& params = Params ();
108
-
111
+ const CChainParams& params = *g_params;
109
112
const int64_t interval = params.GetConsensus ().nPowTargetSpacing ;
110
113
assert (interval > 1 ); // need to be able to halve it
111
114
assert (interval < std::numeric_limits<int32_t >::max ());
@@ -122,9 +125,9 @@ FUZZ_TARGET_INIT(versionbits, initialize)
122
125
123
126
// too many blocks at 10min each might cause uint32_t time to overflow if
124
127
// block_start_time is at the end of the range above
125
- assert (std::numeric_limits<uint32_t >::max () - MAX_TIME > interval * max_blocks);
128
+ assert (std::numeric_limits<uint32_t >::max () - MAX_START_TIME > interval * max_blocks);
126
129
127
- const int64_t block_start_time = fuzzed_data_provider.ConsumeIntegralInRange <uint32_t >(params.GenesisBlock ().nTime , MAX_TIME );
130
+ const int64_t block_start_time = fuzzed_data_provider.ConsumeIntegralInRange <uint32_t >(params.GenesisBlock ().nTime , MAX_START_TIME );
128
131
129
132
// what values for version will we use to signal / not signal?
130
133
const int32_t ver_signal = fuzzed_data_provider.ConsumeIntegral <int32_t >();
@@ -173,8 +176,10 @@ FUZZ_TARGET_INIT(versionbits, initialize)
173
176
if (checker.Condition (ver_nosignal)) return ;
174
177
if (ver_nosignal < 0 ) return ;
175
178
176
- // TOP_BITS should ensure version will be positive
179
+ // TOP_BITS should ensure version will be positive and meet min
180
+ // version requirement
177
181
assert (ver_signal > 0 );
182
+ assert (ver_signal >= VERSIONBITS_LAST_OLD_BLOCK_VERSION);
178
183
179
184
// Now that we have chosen time and versions, setup to mine blocks
180
185
Blocks blocks (block_start_time, interval, ver_signal, ver_nosignal);
@@ -203,7 +208,7 @@ FUZZ_TARGET_INIT(versionbits, initialize)
203
208
}
204
209
205
210
// don't risk exceeding max_blocks or times may wrap around
206
- if (blocks.size () + period* 2 > max_blocks) break ;
211
+ if (blocks.size () + 2 * period > max_blocks) break ;
207
212
}
208
213
// NOTE: fuzzed_data_provider may be fully consumed at this point and should not be used further
209
214
@@ -316,7 +321,7 @@ FUZZ_TARGET_INIT(versionbits, initialize)
316
321
assert (false );
317
322
}
318
323
319
- if (blocks.size () >= max_periods * period ) {
324
+ if (blocks.size () >= period * max_periods ) {
320
325
// we chose the timeout (and block times) so that by the time we have this many blocks it's all over
321
326
assert (state == ThresholdState::ACTIVE || state == ThresholdState::FAILED);
322
327
}
@@ -343,3 +348,4 @@ FUZZ_TARGET_INIT(versionbits, initialize)
343
348
}
344
349
}
345
350
}
351
+ } // namespace
0 commit comments