mining: move BlockAssembler statics into BlockTemplateManager #36357

pull w0xlt wants to merge 3 commits into bitcoin:master from w0xlt:block-template-manager-last-block-stats changing 5 files +201 −44
  1. w0xlt commented at 9:09 AM on September 27, 2026: contributor

    Based on #36356. Together with it, this completes the "Remove remaining global states" TODO in #33758.

    getmininginfo reports currentblockweight and currentblocktx from two process-wide statics, BlockAssembler::m_last_block_weight and m_last_block_num_txs, which every BlockAssembler::CreateNewBlock() call overwrites.

    Like the getblocktemplate statics, they are shared by every node context in the process and nothing checks their locking. They also record templates that were not built for mining: the mempool fee estimator builds its own templates with BlockAssembler, so getmininginfo can report the fee estimator's template instead of the last mining template.

    This PR:

    • makes the two fields per-BlockAssembler instance, still set at the same point in CreateNewBlock();
    • has BlockTemplateManager::CreateNewTemplate() record them in a member guarded by cs_main, which getmininginfo reads. CreateNewTemplate() now holds cs_main across the build, as CreateNewBlock() already did internally, so concurrent builds cannot record their stats out of order;
    • adds a unit test showing that manager builds are recorded, that the latest one wins, and that a direct BlockAssembler build is ignored.

    In short: the last global mining state moves out of BlockAssembler, and getmininginfo reports the last template built for mining rather than whatever the node assembled last.

  2. node: cache a getblocktemplate template in BlockTemplateManager
    Add a CachedBlockTemplate member to BlockTemplateManager, guarded by
    cs_main, along with GetCachedTransactionsUpdated() and
    RefreshCachedTemplate().
    
    RefreshCachedTemplate() follows the rules of the function-local statics
    in the getblocktemplate RPC, which the next commit replaces: the template
    is rebuilt when the tip changes, or when the mempool changed and the
    cached template is more than 5 seconds old. A failed rebuild leaves the
    cached template unset so that the next call tries again. The deprecated
    GetTime() is replaced with the equivalent Now<NodeSeconds>().
    
    Unlike the RPC, RefreshCachedTemplate() does not take the tip from the
    caller or cache its CBlockIndex. It reads the active chain tip itself
    and compares it with the template's hashPrevBlock, so the cache cannot
    pair a template with a tip it does not build on.
    ccb8e84039
  3. rpc: use the BlockTemplateManager cache in getblocktemplate
    Replace the function-local statics in getblocktemplate with the template
    cached by BlockTemplateManager. The state now lives as long as the node
    context instead of the process, and its synchronization is checked
    through GUARDED_BY(::cs_main).
    
    The static CBlockIndex pointer is not carried over: pindexPrev is looked
    up from the template's hashPrevBlock, so it can no longer outlive the
    ChainstateManager that owns it. The longpollid is built from
    hashPrevBlock as well, so it always names the block the template builds
    on, and the tip no longer needs to be re-read after longpolling.
    5cbfbc6b92
  4. node: move last block stats into BlockTemplateManager
    BlockAssembler::m_last_block_num_txs and m_last_block_weight were
    process-wide statics, written by every BlockAssembler::CreateNewBlock()
    call and read by getmininginfo as currentblocktx and currentblockweight.
    
    Make them per-instance, and have
    BlockTemplateManager::CreateNewTemplate() copy them into a member
    guarded by cs_main, which getmininginfo reads.
    CreateNewTemplate() now holds cs_main across the build, as
    CreateNewBlock() already did internally, so concurrent builds cannot
    record their stats out of order.
    
    Behavior change: only templates built through BlockTemplateManager
    (getblocktemplate, the generate RPCs and the mining interface) update
    these fields. Templates that the mempool fee estimator builds with
    BlockAssembler directly no longer do, and neither does a build that
    throws after assembling the block (e.g. a TestBlockValidity() failure).
    
    Update the getmininginfo help text to match.
    e47e7acca3
  5. DrahtBot added the label Mining on Sep 27, 2026
  6. DrahtBot commented at 9:10 AM on September 27, 2026: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--006a51241073e994b41acfe9ec718e94-->

    Code Coverage & Benchmarks

    For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/36357.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline and AI policy for information on the review process.

    Type Reviewers
    Concept ACK ismaelsadeeq

    If your review is incorrectly listed, please copy-paste <code>&lt;!--meta-tag:bot-skip--&gt;</code> into the comment that the bot should ignore.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #36525 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36525.svg"></sub> (mining: add getTotalFees(), protect m_block_template with mutex by Sjors)
    • #36451 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/36451.svg"></sub> (refactor: Use NotNull for CreateNewBlock and pimpls by maflcko)
    • #35671 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/35671.svg"></sub> (mining: add TxCollection to bandwidth-efficiently validate external block templates by Sjors)
    • #35569 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/35569.svg"></sub> (Encapsulation for CTransaction by purpleKarrot)
    • #35511 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/35511.svg"></sub> (RFC: consensus: Make CAmount a class by hodlinator)
    • #33922 <sub><img src="https://drahtbot.space/ack_count/bitcoin/bitcoin/33922.svg"></sub> (mining: add getMemoryLoad() and track template non-mempool memory footprint by Sjors)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

    <!--5faf32d7da4f0f540f40219e4f7537a3-->

  7. w0xlt marked this as a draft on Sep 27, 2026
  8. ismaelsadeeq commented at 9:05 AM on September 28, 2026: member

    Concept ACK

    Now that #34075 is merged, we can also move its cache in there, i.e cache the block template based on time and tip changes. This brings us multiple advantages

    i) We consolidate the block template caching for the RPC and fees to the block template manager for better code organisation and reuse. ii) The mempool fee rate estimator's reliance on the chainstate manager is reduced; the only dependence after that will be on the chain tip, which can also be removed by using chain tip change validation signals. After that, the mempool fee rate estimator will be independent of the mempool and chainstate manager, in replacement with block template manager.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-10-30 09:40 UTC