Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251if (exp_state == ThresholdState::STARTED) {252// double check that stats.possible is sane253if (blocks_sig >= dep.threshold - 1) assert(last_stats.possible);254}256// mine the final block257bool signal = (signalling_mask >> (period % 32)) & 1;258if (signal) ++blocks_sig;259CBlockIndex* current_block = blocks.mine_block(signal);260assert(checker.Condition(current_block->nVersion) == signal);262const BIP9Stats stats = checker.GetStateStatisticsFor(current_block);263assert(stats.period == period);264assert(stats.threshold == dep.threshold);265assert(stats.elapsed == period);266assert(stats.count == blocks_sig);267assert(stats.possible == (stats.count + period >= stats.elapsed + dep.threshold));269// More interesting is whether the state changed.270const ThresholdState state = checker.GetStateFor(current_block);271const int since = checker.GetStateSinceHeightFor(current_block);273// since is straightforward:274assert(since % period == 0);275assert(0 <= since && since <= current_block->nHeight + 1);276if (state == exp_state) {277assert(since == exp_since);278} else {279assert(since == current_block->nHeight + 1);280}282// state is where everything interesting is283[&]() {284switch (state) {285case ThresholdState::DEFINED:286assert(since == 0);287assert(exp_state == ThresholdState::DEFINED);288assert(current_block->GetMedianTimePast() < dep.nStartTime);289return;290case ThresholdState::STARTED:291assert(current_block->GetMedianTimePast() >= dep.nStartTime);292if (exp_state == ThresholdState::STARTED) {293assert(blocks_sig < dep.threshold);294assert(current_block->GetMedianTimePast() < dep.nTimeout);295} else {296assert(exp_state == ThresholdState::DEFINED);297}298return;299case ThresholdState::LOCKED_IN:300if (exp_state == ThresholdState::LOCKED_IN) {301assert(current_block->nHeight + 1 < dep.min_activation_height);302} else {303assert(exp_state == ThresholdState::STARTED);304assert(blocks_sig >= dep.threshold);305}306return;307case ThresholdState::ACTIVE:308assert(always_active_test || dep.min_activation_height <= current_block->nHeight + 1);309assert(exp_state == ThresholdState::ACTIVE || exp_state == ThresholdState::LOCKED_IN);310return;311case ThresholdState::FAILED:312assert(never_active_test || current_block->GetMedianTimePast() >= dep.nTimeout);313if (exp_state == ThresholdState::STARTED) {314assert(blocks_sig < dep.threshold);315} else {316assert(exp_state == ThresholdState::FAILED);317}318return;319} // no default case, so the compiler can warn about missing cases320assert(false);321}();323if (blocks.size() >= period * max_periods) {324// we chose the timeout (and block times) so that by the time we have this many blocks it's all over325assert(state == ThresholdState::ACTIVE || state == ThresholdState::FAILED);326}328if (always_active_test) {329// "always active" has additional restrictions330assert(state == ThresholdState::ACTIVE);331assert(exp_state == ThresholdState::ACTIVE);332assert(since == 0);333} else if (never_active_test) {334// "never active" does too335assert(state == ThresholdState::FAILED);336assert(exp_state == ThresholdState::FAILED);337assert(since == 0);338} else {339// for signalled deployments, the initial state is always DEFINED340assert(since > 0 || state == ThresholdState::DEFINED);341assert(exp_since > 0 || exp_state == ThresholdState::DEFINED);342}343}344} // namespace
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.