| 979 | } |
| 980 | |
| 981 | std::unique_ptr<BlockTemplate> createNewBlock(const BlockCreateOptions& options, bool cooldown) override |
| 982 | { |
| 983 | // Ensure m_tip_block is set so consumers of BlockTemplate can rely on that. |
| 984 | std::optional<BlockRef> maybe_tip{waitTipChanged(uint256::ZERO, MillisecondsDouble::max())}; |
| 985 | |
| 986 | if (!maybe_tip) return {}; |
| 987 | |
| 988 | if (cooldown) { |
| 989 | // Do not return a template during IBD, because it can have long |
| 990 | // pauses and sometimes takes a while to get started. Although this |
| 991 | // is useful in general, it's gated behind the cooldown argument, |
| 992 | // because on regtest and single miner signets this would wait |
| 993 | // forever if no block was mined in the past day. |
| 994 | while (chainman().IsInitialBlockDownload()) { |
| 995 | maybe_tip = waitTipChanged(maybe_tip->hash, MillisecondsDouble{1000}); |
| 996 | if (!maybe_tip || chainman().m_interrupt || WITH_LOCK(notifications().m_tip_block_mutex, return m_interrupt_mining)) return {}; |
| 997 | } |
| 998 | |
| 999 | // Also wait during the final catch-up moments after IBD. |
| 1000 | if (!CooldownIfHeadersAhead(chainman(), notifications(), *maybe_tip, m_interrupt_mining)) return {}; |
| 1001 | } |
| 1002 | const BlockCreateOptions create_options{MergeMiningOptions(options, m_node.mining_args)}; |
| 1003 | return std::make_unique<BlockTemplateImpl>(create_options, |
| 1004 | BlockAssembler{ |
| 1005 | chainman().ActiveChainstate(), |
| 1006 | m_node.mempool.get(), |
| 1007 | create_options, |
| 1008 | }.CreateNewBlock(), |
| 1009 | m_node); |
| 1010 | } |
| 1011 | |
| 1012 | void interrupt() override |
| 1013 | { |