Line data Source code
1 : // Copyright (c) The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 :
5 : #ifndef BITCOIN_NODE_BLOCK_TEMPLATE_MANAGER_H
6 : #define BITCOIN_NODE_BLOCK_TEMPLATE_MANAGER_H
7 :
8 : #include <node/mining_types.h>
9 : #include <util/time.h>
10 :
11 : #include <memory>
12 : #include <optional>
13 : #include <string>
14 :
15 : class CBlock;
16 : class ChainstateManager;
17 : class CTxMemPool;
18 : class uint256;
19 :
20 : namespace interfaces {
21 : struct BlockRef;
22 : } // namespace interfaces
23 :
24 : namespace node {
25 : class KernelNotifications;
26 : struct CBlockTemplate;
27 :
28 : /**
29 : * Creates block templates, submits solved blocks, and provides tip-waiting
30 : * helpers for mining code. Owns the init-time block creation args.
31 : */
32 210 : class BlockTemplateManager
33 : {
34 : private:
35 : CTxMemPool& m_mempool;
36 : ChainstateManager& m_chainman;
37 : KernelNotifications& m_notifications;
38 : const BlockCreateOptions m_block_create_args;
39 :
40 : public:
41 : explicit BlockTemplateManager(CTxMemPool& mempool,
42 : ChainstateManager& chainman,
43 : KernelNotifications& notifications,
44 : BlockCreateOptions block_create_args = {});
45 :
46 : /** @return the block creation args set during node init. */
47 0 : const BlockCreateOptions& BlockCreateArgs() const { return m_block_create_args; }
48 :
49 : /** Create a fresh block template, applying init-time defaults to any unset options. */
50 : std::unique_ptr<CBlockTemplate> CreateNewTemplate(const BlockCreateOptions& options);
51 :
52 : /** Submit a block via ProcessNewBlock and capture validation state.
53 : * @return whether the block was accepted as a new valid block. */
54 : bool SubmitBlock(const std::shared_ptr<const CBlock>& block, std::string& reason, std::string& debug);
55 :
56 : /** Locks cs_main.
57 : * @return the active chain tip, or nullopt if none exists. */
58 : std::optional<interfaces::BlockRef> GetTip();
59 :
60 : /** Wait for the tip to differ from @p current_tip or timeout.
61 : * Waits indefinitely during startup for a non-null tip.
62 : * @return the current tip, or nullopt if the node is shutting down or
63 : * interrupt is set (not when the timeout is reached). */
64 : std::optional<interfaces::BlockRef> WaitTipChanged(const uint256& current_tip, MillisecondsDouble& timeout, bool& interrupt);
65 :
66 : /** Convenience overload for in-process callers (e.g. RPC) that have no
67 : * interrupt handle. Takes the timeout by value so the caller's variable is
68 : * left unchanged; the wait still ends on chain shutdown. */
69 : std::optional<interfaces::BlockRef> WaitTipChanged(const uint256& current_tip, MillisecondsDouble timeout = MillisecondsDouble::max());
70 :
71 : /**
72 : * Wait while the best known header extends the current chain tip AND at
73 : * least one block is being added to the tip every 3 seconds. If the tip is
74 : * sufficiently far behind, allow up to 20 seconds for the next tip update.
75 : *
76 : * It's not safe to keep waiting, because a malicious miner could announce
77 : * a header and delay revealing the block, causing all other miners using
78 : * this software to stall. At the same time, we need to balance between the
79 : * default waiting time being brief, but not ending the cooldown prematurely
80 : * when a random block is slow to download (or process).
81 : *
82 : * The cooldown only applies to createNewBlock(), which is typically called
83 : * once per connected client. Subsequent templates are provided by
84 : * waitNext().
85 : *
86 : * @param last_tip tip at the start of the cooldown window.
87 : * @param interrupt_mining set to true to interrupt the cooldown.
88 : *
89 : * @returns false if interrupted.
90 : */
91 : bool CooldownIfHeadersAhead(const interfaces::BlockRef& last_tip, bool& interrupt_mining);
92 :
93 : /** Interrupt a blocking wait. */
94 : void InterruptWait(bool& interrupt_wait);
95 :
96 : /** Return a new block template when fees rise to a certain threshold or
97 : * after a new tip; return nullptr if timeout is reached. */
98 : std::unique_ptr<CBlockTemplate> WaitAndCreateNewBlock(
99 : const std::unique_ptr<CBlockTemplate>& block_template,
100 : const BlockWaitOptions& wait_options,
101 : const BlockCreateOptions& create_options,
102 : bool& interrupt_wait);
103 : };
104 : } // namespace node
105 :
106 : #endif // BITCOIN_NODE_BLOCK_TEMPLATE_MANAGER_H
|