Line data Source code
1 : // Copyright (c) 2018-2020 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_INTERFACES_CHAIN_H
6 : #define BITCOIN_INTERFACES_CHAIN_H
7 :
8 : #include <optional.h> // For Optional and nullopt
9 : #include <primitives/transaction.h> // For CTransactionRef
10 : #include <util/settings.h> // For util::SettingsValue
11 :
12 : #include <functional>
13 : #include <memory>
14 : #include <stddef.h>
15 : #include <stdint.h>
16 : #include <string>
17 : #include <vector>
18 :
19 : class ArgsManager;
20 : class CBlock;
21 : class CFeeRate;
22 : class CRPCCommand;
23 : class CScheduler;
24 : class Coin;
25 : class uint256;
26 : enum class MemPoolRemovalReason;
27 : enum class RBFTransactionState;
28 : struct bilingual_str;
29 : struct CBlockLocator;
30 : struct FeeCalculation;
31 : struct NodeContext;
32 :
33 : namespace interfaces {
34 :
35 : class Handler;
36 : class Wallet;
37 :
38 : //! Helper for findBlock to selectively return pieces of block data.
39 365400 : class FoundBlock
40 : {
41 : public:
42 77494 : FoundBlock& hash(uint256& hash) { m_hash = &hash; return *this; }
43 585 : FoundBlock& height(int& height) { m_height = &height; return *this; }
44 28225 : FoundBlock& time(int64_t& time) { m_time = &time; return *this; }
45 2 : FoundBlock& maxTime(int64_t& max_time) { m_max_time = &max_time; return *this; }
46 277 : FoundBlock& mtpTime(int64_t& mtp_time) { m_mtp_time = &mtp_time; return *this; }
47 : //! Read block data from disk. If the block exists but doesn't have data
48 : //! (for example due to pruning), the CBlock variable will be set to null.
49 76916 : FoundBlock& data(CBlock& data) { m_data = &data; return *this; }
50 :
51 182700 : uint256* m_hash = nullptr;
52 182700 : int* m_height = nullptr;
53 182700 : int64_t* m_time = nullptr;
54 182700 : int64_t* m_max_time = nullptr;
55 182700 : int64_t* m_mtp_time = nullptr;
56 182700 : CBlock* m_data = nullptr;
57 : };
58 :
59 : //! Interface giving clients (wallet processes, maybe other analysis tools in
60 : //! the future) ability to access to the chain state, receive notifications,
61 : //! estimate fees, and submit transactions.
62 : //!
63 : //! TODO: Current chain methods are too low level, exposing too much of the
64 : //! internal workings of the bitcoin node, and not being very convenient to use.
65 : //! Chain methods should be cleaned up and simplified over time. Examples:
66 : //!
67 : //! * The initMessages() and showProgress() methods which the wallet uses to send
68 : //! notifications to the GUI should go away when GUI and wallet can directly
69 : //! communicate with each other without going through the node
70 : //! (https://github.com/bitcoin/bitcoin/pull/15288#discussion_r253321096).
71 : //!
72 : //! * The handleRpc, registerRpcs, rpcEnableDeprecated methods and other RPC
73 : //! methods can go away if wallets listen for HTTP requests on their own
74 : //! ports instead of registering to handle requests on the node HTTP port.
75 : //!
76 : //! * Move fee estimation queries to an asynchronous interface and let the
77 : //! wallet cache it, fee estimation being driven by node mempool, wallet
78 : //! should be the consumer.
79 : //!
80 : //! * The `guessVerificationProgress`, `getBlockHeight`, `getBlockHash`, etc
81 : //! methods can go away if rescan logic is moved on the node side, and wallet
82 : //! only register rescan request.
83 1118 : class Chain
84 : {
85 : public:
86 1117 : virtual ~Chain() {}
87 :
88 : //! Get current chain height, not including genesis block (returns 0 if
89 : //! chain only contains genesis block, nullopt if chain does not contain
90 : //! any blocks)
91 : virtual Optional<int> getHeight() = 0;
92 :
93 : //! Get block height above genesis block. Returns 0 for genesis block,
94 : //! 1 for following block, and so on. Returns nullopt for a block not
95 : //! included in the current chain.
96 : virtual Optional<int> getBlockHeight(const uint256& hash) = 0;
97 :
98 : //! Get block hash. Height must be valid or this function will abort.
99 : virtual uint256 getBlockHash(int height) = 0;
100 :
101 : //! Check that the block is available on disk (i.e. has not been
102 : //! pruned), and contains transactions.
103 : virtual bool haveBlockOnDisk(int height) = 0;
104 :
105 : //! Return height of the first block in the chain with timestamp equal
106 : //! or greater than the given time and height equal or greater than the
107 : //! given height, or nullopt if there is no block with a high enough
108 : //! timestamp and height. Also return the block hash as an optional output parameter
109 : //! (to avoid the cost of a second lookup in case this information is needed.)
110 : virtual Optional<int> findFirstBlockWithTimeAndHeight(int64_t time, int height, uint256* hash) = 0;
111 :
112 : //! Get locator for the current chain tip.
113 : virtual CBlockLocator getTipLocator() = 0;
114 :
115 : //! Return height of the highest block on chain in common with the locator,
116 : //! which will either be the original block used to create the locator,
117 : //! or one of its ancestors.
118 : virtual Optional<int> findLocatorFork(const CBlockLocator& locator) = 0;
119 :
120 : //! Check if transaction will be final given chain height current time.
121 : virtual bool checkFinalTx(const CTransaction& tx) = 0;
122 :
123 : //! Return whether node has the block and optionally return block metadata
124 : //! or contents.
125 : virtual bool findBlock(const uint256& hash, const FoundBlock& block={}) = 0;
126 :
127 : //! Find first block in the chain with timestamp >= the given time
128 : //! and height >= than the given height, return false if there is no block
129 : //! with a high enough timestamp and height. Optionally return block
130 : //! information.
131 : virtual bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block={}) = 0;
132 :
133 : //! Find next block if block is part of current chain. Also flag if
134 : //! there was a reorg and the specified block hash is no longer in the
135 : //! current chain, and optionally return block information.
136 : virtual bool findNextBlock(const uint256& block_hash, int block_height, const FoundBlock& next={}, bool* reorg=nullptr) = 0;
137 :
138 : //! Find ancestor of block at specified height and optionally return
139 : //! ancestor information.
140 : virtual bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out={}) = 0;
141 :
142 : //! Return whether block descends from a specified ancestor, and
143 : //! optionally return ancestor information.
144 : virtual bool findAncestorByHash(const uint256& block_hash,
145 : const uint256& ancestor_hash,
146 : const FoundBlock& ancestor_out={}) = 0;
147 :
148 : //! Find most recent common ancestor between two blocks and optionally
149 : //! return block information.
150 : virtual bool findCommonAncestor(const uint256& block_hash1,
151 : const uint256& block_hash2,
152 : const FoundBlock& ancestor_out={},
153 : const FoundBlock& block1_out={},
154 : const FoundBlock& block2_out={}) = 0;
155 :
156 : //! Look up unspent output information. Returns coins in the mempool and in
157 : //! the current chain UTXO set. Iterates through all the keys in the map and
158 : //! populates the values.
159 : virtual void findCoins(std::map<COutPoint, Coin>& coins) = 0;
160 :
161 : //! Estimate fraction of total transactions verified if blocks up to
162 : //! the specified block hash are verified.
163 : virtual double guessVerificationProgress(const uint256& block_hash) = 0;
164 :
165 : //! Return true if data is available for all blocks in the specified range
166 : //! of blocks. This checks all blocks that are ancestors of block_hash in
167 : //! the height range from min_height to max_height, inclusive.
168 : virtual bool hasBlocks(const uint256& block_hash, int min_height = 0, Optional<int> max_height = {}) = 0;
169 :
170 : //! Check if transaction is RBF opt in.
171 : virtual RBFTransactionState isRBFOptIn(const CTransaction& tx) = 0;
172 :
173 : //! Check if transaction has descendants in mempool.
174 : virtual bool hasDescendantsInMempool(const uint256& txid) = 0;
175 :
176 : //! Transaction is added to memory pool, if the transaction fee is below the
177 : //! amount specified by max_tx_fee, and broadcast to all peers if relay is set to true.
178 : //! Return false if the transaction could not be added due to the fee or for another reason.
179 : virtual bool broadcastTransaction(const CTransactionRef& tx,
180 : const CAmount& max_tx_fee,
181 : bool relay,
182 : std::string& err_string) = 0;
183 :
184 : //! Calculate mempool ancestor and descendant counts for the given transaction.
185 : virtual void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants) = 0;
186 :
187 : //! Get the node's package limits.
188 : //! Currently only returns the ancestor and descendant count limits, but could be enhanced to
189 : //! return more policy settings.
190 : virtual void getPackageLimits(unsigned int& limit_ancestor_count, unsigned int& limit_descendant_count) = 0;
191 :
192 : //! Check if transaction will pass the mempool's chain limits.
193 : virtual bool checkChainLimits(const CTransactionRef& tx) = 0;
194 :
195 : //! Estimate smart fee.
196 : virtual CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc = nullptr) = 0;
197 :
198 : //! Fee estimator max target.
199 : virtual unsigned int estimateMaxBlocks() = 0;
200 :
201 : //! Mempool minimum fee.
202 : virtual CFeeRate mempoolMinFee() = 0;
203 :
204 : //! Relay current minimum fee (from -minrelaytxfee and -incrementalrelayfee settings).
205 : virtual CFeeRate relayMinFee() = 0;
206 :
207 : //! Relay incremental fee setting (-incrementalrelayfee), reflecting cost of relay.
208 : virtual CFeeRate relayIncrementalFee() = 0;
209 :
210 : //! Relay dust fee setting (-dustrelayfee), reflecting lowest rate it's economical to spend.
211 : virtual CFeeRate relayDustFee() = 0;
212 :
213 : //! Check if any block has been pruned.
214 : virtual bool havePruned() = 0;
215 :
216 : //! Check if the node is ready to broadcast transactions.
217 : virtual bool isReadyToBroadcast() = 0;
218 :
219 : //! Check if in IBD.
220 : virtual bool isInitialBlockDownload() = 0;
221 :
222 : //! Check if shutdown requested.
223 : virtual bool shutdownRequested() = 0;
224 :
225 : //! Get adjusted time.
226 : virtual int64_t getAdjustedTime() = 0;
227 :
228 : //! Send init message.
229 : virtual void initMessage(const std::string& message) = 0;
230 :
231 : //! Send init warning.
232 : virtual void initWarning(const bilingual_str& message) = 0;
233 :
234 : //! Send init error.
235 : virtual void initError(const bilingual_str& message) = 0;
236 :
237 : //! Send progress indicator.
238 : virtual void showProgress(const std::string& title, int progress, bool resume_possible) = 0;
239 :
240 : //! Chain notifications.
241 873 : class Notifications
242 : {
243 : public:
244 873 : virtual ~Notifications() {}
245 0 : virtual void transactionAddedToMempool(const CTransactionRef& tx) {}
246 0 : virtual void transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason) {}
247 0 : virtual void blockConnected(const CBlock& block, int height) {}
248 0 : virtual void blockDisconnected(const CBlock& block, int height) {}
249 0 : virtual void updatedBlockTip() {}
250 0 : virtual void chainStateFlushed(const CBlockLocator& locator) {}
251 : };
252 :
253 : //! Register handler for notifications.
254 : virtual std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) = 0;
255 :
256 : //! Wait for pending notifications to be processed unless block hash points to the current
257 : //! chain tip.
258 : virtual void waitForNotificationsIfTipChanged(const uint256& old_tip) = 0;
259 :
260 : //! Register handler for RPC. Command is not copied, so reference
261 : //! needs to remain valid until Handler is disconnected.
262 : virtual std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) = 0;
263 :
264 : //! Check if deprecated RPC is enabled.
265 : virtual bool rpcEnableDeprecated(const std::string& method) = 0;
266 :
267 : //! Run function after given number of seconds. Cancel any previous calls with same name.
268 : virtual void rpcRunLater(const std::string& name, std::function<void()> fn, int64_t seconds) = 0;
269 :
270 : //! Current RPC serialization flags.
271 : virtual int rpcSerializationFlags() = 0;
272 :
273 : //! Return <datadir>/settings.json setting value.
274 : virtual util::SettingsValue getRwSetting(const std::string& name) = 0;
275 :
276 : //! Write a setting to <datadir>/settings.json.
277 : virtual bool updateRwSetting(const std::string& name, const util::SettingsValue& value) = 0;
278 :
279 : //! Synchronously send transactionAddedToMempool notifications about all
280 : //! current mempool transactions to the specified handler and return after
281 : //! the last one is sent. These notifications aren't coordinated with async
282 : //! notifications sent by handleNotifications, so out of date async
283 : //! notifications from handleNotifications can arrive during and after
284 : //! synchronous notifications from requestMempoolTransactions. Clients need
285 : //! to be prepared to handle this by ignoring notifications about unknown
286 : //! removed transactions and already added new transactions.
287 : virtual void requestMempoolTransactions(Notifications& notifications) = 0;
288 : };
289 :
290 : //! Interface to let node manage chain clients (wallets, or maybe tools for
291 : //! monitoring and analysis in the future).
292 1001 : class ChainClient
293 : {
294 : public:
295 1000 : virtual ~ChainClient() {}
296 :
297 : //! Register rpcs.
298 : virtual void registerRpcs() = 0;
299 :
300 : //! Check for errors before loading.
301 : virtual bool verify() = 0;
302 :
303 : //! Load saved state.
304 : virtual bool load() = 0;
305 :
306 : //! Start client execution and provide a scheduler.
307 : virtual void start(CScheduler& scheduler) = 0;
308 :
309 : //! Save state to disk.
310 : virtual void flush() = 0;
311 :
312 : //! Shut down client.
313 : virtual void stop() = 0;
314 :
315 : //! Set mock time.
316 : virtual void setMockTime(int64_t time) = 0;
317 : };
318 :
319 : //! Return implementation of Chain interface.
320 : std::unique_ptr<Chain> MakeChain(NodeContext& node);
321 :
322 : } // namespace interfaces
323 :
324 : #endif // BITCOIN_INTERFACES_CHAIN_H
|