Inside Bitcoin
Opening the selected file…
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.
501* (approximate) fees for the next block increased, perhaps more so after502* Cluster Mempool.503*504* We'll also create a new template if the tip changed during this iteration.505*/506if (wait_options.fee_threshold < MAX_MONEY || tip_changed) {507auto new_tmpl{BlockAssembler{508chainman.ActiveChainstate(),509mempool,510create_options511}.CreateNewBlock()};513// If the tip changed, return the new template regardless of its fees.514if (tip_changed) return new_tmpl;516// Calculate the original template total fees if we haven't already517if (current_fees == -1) {518current_fees = std::accumulate(block_template->vTxFees.begin(), block_template->vTxFees.end(), CAmount{0});519}521// Check if fees increased enough to return the new template522const CAmount new_fees = std::accumulate(new_tmpl->vTxFees.begin(), new_tmpl->vTxFees.end(), CAmount{0});523Assume(wait_options.fee_threshold != MAX_MONEY);524if (new_fees >= current_fees + wait_options.fee_threshold) return new_tmpl;525}527now = NodeClock::now();528} while (now < deadline);530return nullptr;531}533std::optional<BlockRef> GetTip(ChainstateManager& chainman)534{535LOCK(::cs_main);536CBlockIndex* tip{chainman.ActiveChain().Tip()};537if (!tip) return {};538return BlockRef{tip->GetBlockHash(), tip->nHeight};539}541bool CooldownIfHeadersAhead(ChainstateManager& chainman, KernelNotifications& kernel_notifications, const BlockRef& last_tip, bool& interrupt_mining)542{543uint256 last_tip_hash{last_tip.hash};545while (const std::optional<int> remaining = chainman.BlocksAheadOfTip()) {546const int cooldown_seconds = std::clamp(*remaining, 3, 20);547const auto cooldown_deadline{MockableSteadyClock::now() + std::chrono::seconds{cooldown_seconds}};549{550WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock);551kernel_notifications.m_tip_block_cv.wait_until(lock, cooldown_deadline, [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) {552const auto tip_block = kernel_notifications.TipBlock();553return chainman.m_interrupt || interrupt_mining || (tip_block && *tip_block != last_tip_hash);554});555if (chainman.m_interrupt || interrupt_mining) {556interrupt_mining = false;557return false;558}560// If the tip changed during the wait, extend the deadline561const auto tip_block = kernel_notifications.TipBlock();562if (tip_block && *tip_block != last_tip_hash) {563last_tip_hash = *tip_block;564continue;565}566}568// No tip change and the cooldown window has expired.569if (MockableSteadyClock::now() >= cooldown_deadline) break;570}572return true;573}575std::optional<BlockRef> WaitTipChanged(ChainstateManager& chainman, KernelNotifications& kernel_notifications, const uint256& current_tip, MillisecondsDouble& timeout, bool& interrupt)576{577Assume(timeout >= 0ms); // No internal callers should use a negative timeout578if (timeout < 0ms) timeout = 0ms;579if (timeout > std::chrono::years{100}) timeout = std::chrono::years{100}; // Upper bound to avoid UB in std::chrono580auto deadline{std::chrono::steady_clock::now() + timeout};581{582WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock);583// For callers convenience, wait longer than the provided timeout584// during startup for the tip to be non-null. That way this function585// always returns valid tip information when possible and only586// returns null when shutting down, not when timing out.587kernel_notifications.m_tip_block_cv.wait(lock, [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) {588return kernel_notifications.TipBlock() || chainman.m_interrupt || interrupt;589});590if (chainman.m_interrupt || interrupt) {591interrupt = false;592return {};593}594// At this point TipBlock is set, so continue to wait until it is595// different then `current_tip` provided by caller.596kernel_notifications.m_tip_block_cv.wait_until(lock, deadline, [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) {597return Assume(kernel_notifications.TipBlock()) != current_tip || chainman.m_interrupt || interrupt;598});599if (chainman.m_interrupt || interrupt) {600interrupt = false;601return {};602}603}605// Must release m_tip_block_mutex before getTip() locks cs_main, to606// avoid deadlocks.607return GetTip(chainman);608}610} // namespace node