Motivation
The mining interface and rpc helpers (WaitAndCreateNewBlock and friends) are free functions scattered across src/node/miner.cpp, and every caller has to pass ChainstateManager and KernelNotifications into them, which is verbose. SubmitBlock spins up a short-lived CValidationInterface subscriber on every call just to read back the block validation state. This PR adds a BlockTemplateManager that holds that state and exposes those helpers as methods, so callers don't have to thread chainman/notifications (or a throwaway subscriber) around.
It also removes a redundant pattern in waitNext. Currently, to decide whether mempool fee inflow rose enough to be worth a new template, waitNext locks cs_main and assembles a full block template every tick just to sum its fees and compare. After cluster mempool see https://delvingbitcoin.org/t/determining-blocktemplate-fee-increase-using-fee-rate-diagram/2052, we shouldn't have to build a whole block template to answer that question. This PR uses the #34803 mempool notifications to record the previous template state and track the inflow above the lowest included chunk, and only assembles and returns a new template once that inflow is above the threshold.
I added a fuzz harness and unit tests for the manager. The fuzz test already caught a bug in the miner where it skips legitimate transactions due to an incorrect block chunk size limit check #35580.
Changes
- Populate the tx refs in the fee rate diagrams
- Cache fee rate diagrams as chunks in ChangeSet and add SnapshotDiagrams
- Add a
MempoolUpdatednotification that returns the before and after diagrams - Track the selected chunk information after each mempool update
- Add fee-inflow staleness detection per template
- Introduce a
BlockTemplateManagerwrapper aroundBlockAssemblerthat holds state and creates templates, and move the free functions (mining args, SubmitBlock, GetTip, WaitTipChanged, CooldownIfHeadersAhead, WaitAndCreateNewBlock) onto it as methods - Use the tracked inflow in waitNext instead of rebuilding a template each tick
- Route in-process RPC and test template creation through
BlockTemplateManagerinstead of the IPC Mining interface, which also drops the per-access block copies the IPC accessors (getBlock) forced - Add a fuzz test and unit tests
There are now two entry points for template creation. Mining clients go through the IPC Mining interface and get tracked templates, while in-process RPC and tests call BlockTemplateManager directly and get untracked ones. This is deliberate: one-shot RPC templates don't need staleness tracking, and it also avoids process-static RPC caches owning BlockTemplateImpl objects whose destructor reaches back into NodeContext at shutdown.
50% of the code addition here are tests ~1090 lines