29 const int64_t m_begin;
32 const int m_threshold;
33 const int m_min_activation_height;
36 TestConditionChecker(int64_t begin, int64_t end,
int period,
int threshold,
int min_activation_height,
int bit)
37 : m_begin{begin}, m_end{end}, m_period{period}, m_threshold{threshold}, m_min_activation_height{min_activation_height}, m_bit{bit}
40 assert(0 <= m_threshold && m_threshold <= m_period);
42 assert(0 <= m_min_activation_height);
58 uint32_t mask = ((uint32_t)1) << m_bit;
69 std::vector<std::unique_ptr<CBlockIndex>> m_blocks;
70 const uint32_t m_start_time;
71 const uint32_t m_interval;
72 const int32_t m_signal;
73 const int32_t m_no_signal;
76 Blocks(uint32_t start_time, uint32_t interval, int32_t signal, int32_t no_signal)
77 : m_start_time{start_time}, m_interval{interval}, m_signal{signal}, m_no_signal{no_signal} {}
79 size_t size()
const {
return m_blocks.size(); }
83 return m_blocks.empty() ? nullptr : m_blocks.back().get();
89 header.
nVersion = signal ? m_signal : m_no_signal;
90 header.
nTime = m_start_time + m_blocks.size() * m_interval;
91 header.
nBits = 0x1d00ffff;
93 auto current_block = std::make_unique<CBlockIndex>(header);
94 current_block->pprev = tip();
95 current_block->nHeight = m_blocks.size();
96 current_block->BuildSkip();
98 return m_blocks.emplace_back(std::move(current_block)).get();
102 std::unique_ptr<const CChainParams> g_params;
108 assert(g_params !=
nullptr);
111 constexpr uint32_t MAX_START_TIME = 4102444800;
118 assert(interval < std::numeric_limits<int32_t>::max());
123 const int period = 32;
124 const size_t max_periods = 16;
125 const size_t max_blocks = 2 * period * max_periods;
127 const int threshold = fuzzed_data_provider.ConsumeIntegralInRange(1, period);
128 assert(0 < threshold && threshold <= period);
132 assert(std::numeric_limits<uint32_t>::max() - MAX_START_TIME > interval * max_blocks);
134 const int64_t block_start_time = fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(params.
GenesisBlock().
nTime, MAX_START_TIME);
137 const int32_t ver_signal = fuzzed_data_provider.ConsumeIntegral<int32_t>();
138 const int32_t ver_nosignal = fuzzed_data_provider.ConsumeIntegral<int32_t>();
143 bool always_active_test =
false;
144 bool never_active_test =
false;
147 if (fuzzed_data_provider.ConsumeBool()) {
150 int start_block = fuzzed_data_provider.ConsumeIntegralInRange<
int>(0, period * (max_periods - 3));
151 int end_block = fuzzed_data_provider.ConsumeIntegralInRange<
int>(0, period * (max_periods - 3));
153 start_time = block_start_time + start_block * interval;
154 timeout = block_start_time + end_block * interval;
157 if (fuzzed_data_provider.ConsumeBool()) start_time += interval / 2;
158 if (fuzzed_data_provider.ConsumeBool()) timeout += interval / 2;
160 if (fuzzed_data_provider.ConsumeBool()) {
162 always_active_test =
true;
165 never_active_test =
true;
169 int min_activation = fuzzed_data_provider.ConsumeIntegralInRange<
int>(0, period * max_periods);
174 if (!checker.Condition(ver_signal))
return;
175 if (checker.Condition(ver_nosignal))
return;
176 if (ver_nosignal < 0)
return;
184 Blocks blocks(block_start_time, interval, ver_signal, ver_nosignal);
199 const uint32_t signalling_mask = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
202 while (fuzzed_data_provider.remaining_bytes() > 0) {
204 bool signal = fuzzed_data_provider.ConsumeBool();
205 for (
int b = 0; b < period; ++b) {
206 blocks.mine_block(signal);
210 if (blocks.size() + 2 * period > max_blocks)
break;
221 const int exp_since = checker.GetStateSinceHeightFor(prev);
226 last_stats.
period = period;
229 last_stats.
possible = (period >= threshold);
230 std::vector<bool> last_signals{};
232 int prev_next_height = (prev ==
nullptr ? 0 : prev->
nHeight + 1);
233 assert(exp_since <= prev_next_height);
236 for (
int b = 1; b < period; ++b) {
237 const bool signal = (signalling_mask >> (b % 32)) & 1;
238 if (signal) ++blocks_sig;
240 CBlockIndex* current_block = blocks.mine_block(signal);
243 assert(checker.Condition(current_block) == signal);
247 const int since = checker.GetStateSinceHeightFor(current_block);
248 assert(state == exp_state);
249 assert(since == exp_since);
252 std::vector<bool> signals;
253 const BIP9Stats stats = checker.GetStateStatisticsFor(current_block, &signals);
254 const BIP9Stats stats_no_signals = checker.GetStateStatisticsFor(current_block);
266 assert(signals.size() == last_signals.size() + 1);
267 assert(signals.back() == signal);
268 last_signals.push_back(signal);
269 assert(signals == last_signals);
278 bool signal = (signalling_mask >> (period % 32)) & 1;
279 if (signal) ++blocks_sig;
280 CBlockIndex* current_block = blocks.mine_block(signal);
281 assert(checker.Condition(current_block) == signal);
283 const BIP9Stats stats = checker.GetStateStatisticsFor(current_block);
292 const int since = checker.GetStateSinceHeightFor(current_block);
295 assert(since % period == 0);
297 if (state == exp_state) {
298 assert(since == exp_since);
313 assert(blocks_sig < threshold);
324 assert(blocks_sig >= threshold);
328 assert(always_active_test || min_activation <= current_block->
nHeight + 1);
334 assert(blocks_sig < threshold);
343 if (blocks.size() >= period * max_periods) {
348 if (always_active_test) {
353 }
else if (never_active_test) {