Bitcoin Core  31.0.0
P2P Digital Currency
interfaces.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-present 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 #include <addrdb.h>
6 #include <banman.h>
7 #include <blockfilter.h>
8 #include <chain.h>
9 #include <chainparams.h>
10 #include <common/args.h>
11 #include <consensus/merkle.h>
12 #include <consensus/validation.h>
13 #include <deploymentstatus.h>
14 #include <external_signer.h>
15 #include <index/blockfilterindex.h>
16 #include <init.h>
17 #include <interfaces/chain.h>
18 #include <interfaces/handler.h>
19 #include <interfaces/mining.h>
20 #include <interfaces/node.h>
21 #include <interfaces/types.h>
22 #include <interfaces/wallet.h>
23 #include <kernel/chain.h>
24 #include <kernel/context.h>
25 #include <kernel/mempool_entry.h>
26 #include <logging.h>
27 #include <mapport.h>
28 #include <net.h>
29 #include <net_processing.h>
30 #include <netaddress.h>
31 #include <netbase.h>
32 #include <node/blockstorage.h>
33 #include <node/coin.h>
34 #include <node/context.h>
35 #include <node/interface_ui.h>
36 #include <node/mini_miner.h>
37 #include <node/miner.h>
39 #include <node/transaction.h>
40 #include <node/types.h>
41 #include <node/warnings.h>
42 #include <policy/feerate.h>
44 #include <policy/policy.h>
45 #include <policy/rbf.h>
46 #include <policy/settings.h>
47 #include <primitives/block.h>
48 #include <primitives/transaction.h>
49 #include <rpc/blockchain.h>
50 #include <rpc/protocol.h>
51 #include <rpc/server.h>
53 #include <sync.h>
54 #include <txmempool.h>
55 #include <uint256.h>
56 #include <univalue.h>
57 #include <util/check.h>
58 #include <util/result.h>
59 #include <util/signalinterrupt.h>
60 #include <util/string.h>
61 #include <util/translation.h>
62 #include <validation.h>
63 #include <validationinterface.h>
64 
65 #include <bitcoin-build-config.h> // IWYU pragma: keep
66 
67 #include <any>
68 #include <memory>
69 #include <optional>
70 #include <stdexcept>
71 #include <utility>
72 
73 #include <boost/signals2/signal.hpp>
74 
78 using interfaces::Chain;
82 using interfaces::Mining;
83 using interfaces::Node;
88 using node::CoinbaseTx;
89 using util::Join;
90 
91 namespace node {
92 // All members of the classes in this namespace are intentionally public, as the
93 // classes themselves are private.
94 namespace {
95 #ifdef ENABLE_EXTERNAL_SIGNER
96 class ExternalSignerImpl : public interfaces::ExternalSigner
97 {
98 public:
99  ExternalSignerImpl(::ExternalSigner signer) : m_signer(std::move(signer)) {}
100  std::string getName() override { return m_signer.m_name; }
102 };
103 #endif
104 
105 class NodeImpl : public Node
106 {
107 public:
108  explicit NodeImpl(NodeContext& context) { setContext(&context); }
109  void initLogging() override { InitLogging(args()); }
110  void initParameterInteraction() override { InitParameterInteraction(args()); }
111  bilingual_str getWarnings() override { return Join(Assert(m_context->warnings)->GetMessages(), Untranslated("<hr />")); }
112  int getExitStatus() override { return Assert(m_context)->exit_status.load(); }
113  BCLog::CategoryMask getLogCategories() override { return LogInstance().GetCategoryMask(); }
114  bool baseInitialize() override
115  {
116  if (!AppInitBasicSetup(args(), Assert(context())->exit_status)) return false;
117  if (!AppInitParameterInteraction(args())) return false;
118 
119  m_context->warnings = std::make_unique<node::Warnings>();
120  m_context->kernel = std::make_unique<kernel::Context>();
121  m_context->ecc_context = std::make_unique<ECC_Context>();
122  if (!AppInitSanityChecks(*m_context->kernel)) return false;
123 
124  if (!AppInitLockDirectories()) return false;
125  if (!AppInitInterfaces(*m_context)) return false;
126 
127  return true;
128  }
129  bool appInitMain(interfaces::BlockAndHeaderTipInfo* tip_info) override
130  {
131  if (AppInitMain(*m_context, tip_info)) return true;
132  // Error during initialization, set exit status before continue
133  m_context->exit_status.store(EXIT_FAILURE);
134  return false;
135  }
136  void appShutdown() override
137  {
139  }
140  void startShutdown() override
141  {
142  NodeContext& ctx{*Assert(m_context)};
143  if (!(Assert(ctx.shutdown_request))()) {
144  LogError("Failed to send shutdown signal\n");
145  }
147  }
148  bool shutdownRequested() override { return ShutdownRequested(*Assert(m_context)); };
149  bool isSettingIgnored(const std::string& name) override
150  {
151  bool ignored = false;
152  args().LockSettings([&](common::Settings& settings) {
153  if (auto* options = common::FindKey(settings.command_line_options, name)) {
154  ignored = !options->empty();
155  }
156  });
157  return ignored;
158  }
159  common::SettingsValue getPersistentSetting(const std::string& name) override { return args().GetPersistentSetting(name); }
160  void updateRwSetting(const std::string& name, const common::SettingsValue& value) override
161  {
162  args().LockSettings([&](common::Settings& settings) {
163  if (value.isNull()) {
164  settings.rw_settings.erase(name);
165  } else {
166  settings.rw_settings[name] = value;
167  }
168  });
170  }
171  void forceSetting(const std::string& name, const common::SettingsValue& value) override
172  {
173  args().LockSettings([&](common::Settings& settings) {
174  if (value.isNull()) {
175  settings.forced_settings.erase(name);
176  } else {
177  settings.forced_settings[name] = value;
178  }
179  });
180  }
181  void resetSettings() override
182  {
183  args().WriteSettingsFile(/*errors=*/nullptr, /*backup=*/true);
184  args().LockSettings([&](common::Settings& settings) {
185  settings.rw_settings.clear();
186  });
188  }
189  void mapPort(bool enable) override { StartMapPort(enable); }
190  bool getProxy(Network net, Proxy& proxy_info) override { return GetProxy(net, proxy_info); }
191  size_t getNodeCount(ConnectionDirection flags) override
192  {
193  return m_context->connman ? m_context->connman->GetNodeCount(flags) : 0;
194  }
195  bool getNodesStats(NodesStats& stats) override
196  {
197  stats.clear();
198 
199  if (m_context->connman) {
200  std::vector<CNodeStats> stats_temp;
201  m_context->connman->GetNodeStats(stats_temp);
202 
203  stats.reserve(stats_temp.size());
204  for (auto& node_stats_temp : stats_temp) {
205  stats.emplace_back(std::move(node_stats_temp), false, CNodeStateStats());
206  }
207 
208  // Try to retrieve the CNodeStateStats for each node.
209  if (m_context->peerman) {
210  TRY_LOCK(::cs_main, lockMain);
211  if (lockMain) {
212  for (auto& node_stats : stats) {
213  std::get<1>(node_stats) =
214  m_context->peerman->GetNodeStateStats(std::get<0>(node_stats).nodeid, std::get<2>(node_stats));
215  }
216  }
217  }
218  return true;
219  }
220  return false;
221  }
222  bool getBanned(banmap_t& banmap) override
223  {
224  if (m_context->banman) {
225  m_context->banman->GetBanned(banmap);
226  return true;
227  }
228  return false;
229  }
230  bool ban(const CNetAddr& net_addr, int64_t ban_time_offset) override
231  {
232  if (m_context->banman) {
233  m_context->banman->Ban(net_addr, ban_time_offset);
234  return true;
235  }
236  return false;
237  }
238  bool unban(const CSubNet& ip) override
239  {
240  if (m_context->banman) {
241  m_context->banman->Unban(ip);
242  return true;
243  }
244  return false;
245  }
246  bool disconnectByAddress(const CNetAddr& net_addr) override
247  {
248  if (m_context->connman) {
249  return m_context->connman->DisconnectNode(net_addr);
250  }
251  return false;
252  }
253  bool disconnectById(NodeId id) override
254  {
255  if (m_context->connman) {
256  return m_context->connman->DisconnectNode(id);
257  }
258  return false;
259  }
260  std::vector<std::unique_ptr<interfaces::ExternalSigner>> listExternalSigners() override
261  {
262 #ifdef ENABLE_EXTERNAL_SIGNER
263  std::vector<ExternalSigner> signers = {};
264  const std::string command = args().GetArg("-signer", "");
265  if (command == "") return {};
266  ExternalSigner::Enumerate(command, signers, Params().GetChainTypeString());
267  std::vector<std::unique_ptr<interfaces::ExternalSigner>> result;
268  result.reserve(signers.size());
269  for (auto& signer : signers) {
270  result.emplace_back(std::make_unique<ExternalSignerImpl>(std::move(signer)));
271  }
272  return result;
273 #else
274  // This result is indistinguishable from a successful call that returns
275  // no signers. For the current GUI this doesn't matter, because the wallet
276  // creation dialog disables the external signer checkbox in both
277  // cases. The return type could be changed to std::optional<std::vector>
278  // (or something that also includes error messages) if this distinction
279  // becomes important.
280  return {};
281 #endif // ENABLE_EXTERNAL_SIGNER
282  }
283  int64_t getTotalBytesRecv() override { return m_context->connman ? m_context->connman->GetTotalBytesRecv() : 0; }
284  int64_t getTotalBytesSent() override { return m_context->connman ? m_context->connman->GetTotalBytesSent() : 0; }
285  size_t getMempoolSize() override { return m_context->mempool ? m_context->mempool->size() : 0; }
286  size_t getMempoolDynamicUsage() override { return m_context->mempool ? m_context->mempool->DynamicMemoryUsage() : 0; }
287  size_t getMempoolMaxUsage() override { return m_context->mempool ? m_context->mempool->m_opts.max_size_bytes : 0; }
288  bool getHeaderTip(int& height, int64_t& block_time) override
289  {
290  LOCK(::cs_main);
291  auto best_header = chainman().m_best_header;
292  if (best_header) {
293  height = best_header->nHeight;
294  block_time = best_header->GetBlockTime();
295  return true;
296  }
297  return false;
298  }
299  std::map<CNetAddr, LocalServiceInfo> getNetLocalAddresses() override
300  {
301  if (m_context->connman)
302  return m_context->connman->getNetLocalAddresses();
303  else
304  return {};
305  }
306  int getNumBlocks() override
307  {
308  LOCK(::cs_main);
309  return chainman().ActiveChain().Height();
310  }
311  uint256 getBestBlockHash() override
312  {
313  const CBlockIndex* tip = WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip());
314  return tip ? tip->GetBlockHash() : chainman().GetParams().GenesisBlock().GetHash();
315  }
316  int64_t getLastBlockTime() override
317  {
318  LOCK(::cs_main);
319  if (chainman().ActiveChain().Tip()) {
320  return chainman().ActiveChain().Tip()->GetBlockTime();
321  }
322  return chainman().GetParams().GenesisBlock().GetBlockTime(); // Genesis block's time of current network
323  }
324  double getVerificationProgress() override
325  {
326  LOCK(chainman().GetMutex());
327  return chainman().GuessVerificationProgress(chainman().ActiveTip());
328  }
329  bool isInitialBlockDownload() override
330  {
331  return chainman().IsInitialBlockDownload();
332  }
333  bool isLoadingBlocks() override { return chainman().m_blockman.LoadingBlocks(); }
334  void setNetworkActive(bool active) override
335  {
336  if (m_context->connman) {
337  m_context->connman->SetNetworkActive(active);
338  }
339  }
340  bool getNetworkActive() override { return m_context->connman && m_context->connman->GetNetworkActive(); }
341  CFeeRate getDustRelayFee() override
342  {
343  if (!m_context->mempool) return CFeeRate{DUST_RELAY_TX_FEE};
344  return m_context->mempool->m_opts.dust_relay_feerate;
345  }
346  UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
347  {
348  JSONRPCRequest req;
349  req.context = m_context;
350  req.params = params;
351  req.strMethod = command;
352  req.URI = uri;
354  }
355  std::vector<std::string> listRpcCommands() override { return ::tableRPC.listCommands(); }
356  std::optional<Coin> getUnspentOutput(const COutPoint& output) override
357  {
358  LOCK(::cs_main);
359  return chainman().ActiveChainstate().CoinsTip().GetCoin(output);
360  }
361  TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, std::string& err_string) override
362  {
364  std::move(tx),
365  err_string,
366  max_tx_fee,
368  /*wait_callback=*/false);
369  }
370  WalletLoader& walletLoader() override
371  {
372  return *Assert(m_context->wallet_loader);
373  }
374  std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
375  {
376  return MakeSignalHandler(::uiInterface.InitMessage_connect(fn));
377  }
378  std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) override
379  {
380  return MakeSignalHandler(::uiInterface.ThreadSafeMessageBox_connect(fn));
381  }
382  std::unique_ptr<Handler> handleQuestion(QuestionFn fn) override
383  {
384  return MakeSignalHandler(::uiInterface.ThreadSafeQuestion_connect(fn));
385  }
386  std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
387  {
388  return MakeSignalHandler(::uiInterface.ShowProgress_connect(fn));
389  }
390  std::unique_ptr<Handler> handleInitWallet(InitWalletFn fn) override
391  {
392  return MakeSignalHandler(::uiInterface.InitWallet_connect(fn));
393  }
394  std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
395  {
396  return MakeSignalHandler(::uiInterface.NotifyNumConnectionsChanged_connect(fn));
397  }
398  std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) override
399  {
400  return MakeSignalHandler(::uiInterface.NotifyNetworkActiveChanged_connect(fn));
401  }
402  std::unique_ptr<Handler> handleNotifyAlertChanged(NotifyAlertChangedFn fn) override
403  {
404  return MakeSignalHandler(::uiInterface.NotifyAlertChanged_connect(fn));
405  }
406  std::unique_ptr<Handler> handleBannedListChanged(BannedListChangedFn fn) override
407  {
408  return MakeSignalHandler(::uiInterface.BannedListChanged_connect(fn));
409  }
410  std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
411  {
412  return MakeSignalHandler(::uiInterface.NotifyBlockTip_connect([fn](SynchronizationState sync_state, const CBlockIndex& block, double verification_progress) {
413  fn(sync_state, BlockTip{block.nHeight, block.GetBlockTime(), block.GetBlockHash()}, verification_progress);
414  }));
415  }
416  std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
417  {
418  return MakeSignalHandler(
419  ::uiInterface.NotifyHeaderTip_connect([fn](SynchronizationState sync_state, int64_t height, int64_t timestamp, bool presync) {
420  fn(sync_state, BlockTip{(int)height, timestamp, uint256{}}, presync);
421  }));
422  }
423  NodeContext* context() override { return m_context; }
424  void setContext(NodeContext* context) override
425  {
426  m_context = context;
427  }
428  ArgsManager& args() { return *Assert(Assert(m_context)->args); }
429  ChainstateManager& chainman() { return *Assert(m_context->chainman); }
430  NodeContext* m_context{nullptr};
431 };
432 
433 // NOLINTNEXTLINE(misc-no-recursion)
434 bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<RecursiveMutex>& lock, const CChain& active, const BlockManager& blockman) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
435 {
436  if (!index) return false;
437  if (block.m_hash) *block.m_hash = index->GetBlockHash();
438  if (block.m_height) *block.m_height = index->nHeight;
439  if (block.m_time) *block.m_time = index->GetBlockTime();
440  if (block.m_max_time) *block.m_max_time = index->GetBlockTimeMax();
441  if (block.m_mtp_time) *block.m_mtp_time = index->GetMedianTimePast();
442  if (block.m_in_active_chain) *block.m_in_active_chain = active[index->nHeight] == index;
443  if (block.m_locator) { *block.m_locator = GetLocator(index); }
444  if (block.m_next_block) FillBlock(active[index->nHeight] == index ? active[index->nHeight + 1] : nullptr, *block.m_next_block, lock, active, blockman);
445  if (block.m_data) {
446  REVERSE_LOCK(lock, cs_main);
447  if (!blockman.ReadBlock(*block.m_data, *index)) block.m_data->SetNull();
448  }
449  block.found = true;
450  return true;
451 }
452 
453 class NotificationsProxy : public CValidationInterface
454 {
455 public:
456  explicit NotificationsProxy(std::shared_ptr<Chain::Notifications> notifications)
457  : m_notifications(std::move(notifications)) {}
458  virtual ~NotificationsProxy() = default;
459  void TransactionAddedToMempool(const NewMempoolTransactionInfo& tx, uint64_t mempool_sequence) override
460  {
461  m_notifications->transactionAddedToMempool(tx.info.m_tx);
462  }
463  void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) override
464  {
465  m_notifications->transactionRemovedFromMempool(tx, reason);
466  }
467  void BlockConnected(const ChainstateRole& role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
468  {
469  m_notifications->blockConnected(role, kernel::MakeBlockInfo(index, block.get()));
470  }
471  void BlockDisconnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
472  {
473  m_notifications->blockDisconnected(kernel::MakeBlockInfo(index, block.get()));
474  }
475  void UpdatedBlockTip(const CBlockIndex* index, const CBlockIndex* fork_index, bool is_ibd) override
476  {
477  m_notifications->updatedBlockTip();
478  }
479  void ChainStateFlushed(const ChainstateRole& role, const CBlockLocator& locator) override
480  {
481  m_notifications->chainStateFlushed(role, locator);
482  }
483  std::shared_ptr<Chain::Notifications> m_notifications;
484 };
485 
486 class NotificationsHandlerImpl : public Handler
487 {
488 public:
489  explicit NotificationsHandlerImpl(ValidationSignals& signals, std::shared_ptr<Chain::Notifications> notifications)
490  : m_signals{signals}, m_proxy{std::make_shared<NotificationsProxy>(std::move(notifications))}
491  {
493  }
494  ~NotificationsHandlerImpl() override { disconnect(); }
495  void disconnect() override
496  {
497  if (m_proxy) {
499  m_proxy.reset();
500  }
501  }
503  std::shared_ptr<NotificationsProxy> m_proxy;
504 };
505 
506 class RpcHandlerImpl : public Handler
507 {
508 public:
509  explicit RpcHandlerImpl(const CRPCCommand& command) : m_command(command), m_wrapped_command(&command)
510  {
511  m_command.actor = [this](const JSONRPCRequest& request, UniValue& result, bool last_handler) {
512  if (!m_wrapped_command) return false;
513  try {
514  return m_wrapped_command->actor(request, result, last_handler);
515  } catch (const UniValue& e) {
516  // If this is not the last handler and a wallet not found
517  // exception was thrown, return false so the next handler can
518  // try to handle the request. Otherwise, reraise the exception.
519  if (!last_handler) {
520  const UniValue& code = e["code"];
521  if (code.isNum() && code.getInt<int>() == RPC_WALLET_NOT_FOUND) {
522  return false;
523  }
524  }
525  throw;
526  }
527  };
529  }
530 
531  void disconnect() final
532  {
533  if (m_wrapped_command) {
534  m_wrapped_command = nullptr;
536  }
537  }
538 
539  ~RpcHandlerImpl() override { disconnect(); }
540 
543 };
544 
545 class ChainImpl : public Chain
546 {
547 public:
548  explicit ChainImpl(NodeContext& node) : m_node(node) {}
549  std::optional<int> getHeight() override
550  {
551  const int height{WITH_LOCK(::cs_main, return chainman().ActiveChain().Height())};
552  return height >= 0 ? std::optional{height} : std::nullopt;
553  }
554  uint256 getBlockHash(int height) override
555  {
556  LOCK(::cs_main);
557  return Assert(chainman().ActiveChain()[height])->GetBlockHash();
558  }
559  bool haveBlockOnDisk(int height) override
560  {
561  LOCK(::cs_main);
562  const CBlockIndex* block{chainman().ActiveChain()[height]};
563  return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && block->nTx > 0;
564  }
565  std::optional<int> findLocatorFork(const CBlockLocator& locator) override
566  {
567  LOCK(::cs_main);
568  if (const CBlockIndex* fork = chainman().ActiveChainstate().FindForkInGlobalIndex(locator)) {
569  return fork->nHeight;
570  }
571  return std::nullopt;
572  }
573  bool hasBlockFilterIndex(BlockFilterType filter_type) override
574  {
575  return GetBlockFilterIndex(filter_type) != nullptr;
576  }
577  std::optional<bool> blockFilterMatchesAny(BlockFilterType filter_type, const uint256& block_hash, const GCSFilter::ElementSet& filter_set) override
578  {
579  const BlockFilterIndex* block_filter_index{GetBlockFilterIndex(filter_type)};
580  if (!block_filter_index) return std::nullopt;
581 
582  BlockFilter filter;
583  const CBlockIndex* index{WITH_LOCK(::cs_main, return chainman().m_blockman.LookupBlockIndex(block_hash))};
584  if (index == nullptr || !block_filter_index->LookupFilter(index, filter)) return std::nullopt;
585  return filter.GetFilter().MatchAny(filter_set);
586  }
587  bool findBlock(const uint256& hash, const FoundBlock& block) override
588  {
589  WAIT_LOCK(cs_main, lock);
590  return FillBlock(chainman().m_blockman.LookupBlockIndex(hash), block, lock, chainman().ActiveChain(), chainman().m_blockman);
591  }
592  bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override
593  {
594  WAIT_LOCK(cs_main, lock);
595  const CChain& active = chainman().ActiveChain();
596  return FillBlock(active.FindEarliestAtLeast(min_time, min_height), block, lock, active, chainman().m_blockman);
597  }
598  bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out) override
599  {
600  WAIT_LOCK(cs_main, lock);
601  const CChain& active = chainman().ActiveChain();
602  if (const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
603  if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) {
604  return FillBlock(ancestor, ancestor_out, lock, active, chainman().m_blockman);
605  }
606  }
607  return FillBlock(nullptr, ancestor_out, lock, active, chainman().m_blockman);
608  }
609  bool findAncestorByHash(const uint256& block_hash, const uint256& ancestor_hash, const FoundBlock& ancestor_out) override
610  {
611  WAIT_LOCK(cs_main, lock);
612  const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash);
613  const CBlockIndex* ancestor = chainman().m_blockman.LookupBlockIndex(ancestor_hash);
614  if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr;
615  return FillBlock(ancestor, ancestor_out, lock, chainman().ActiveChain(), chainman().m_blockman);
616  }
617  bool findCommonAncestor(const uint256& block_hash1, const uint256& block_hash2, const FoundBlock& ancestor_out, const FoundBlock& block1_out, const FoundBlock& block2_out) override
618  {
619  WAIT_LOCK(cs_main, lock);
620  const CChain& active = chainman().ActiveChain();
621  const CBlockIndex* block1 = chainman().m_blockman.LookupBlockIndex(block_hash1);
622  const CBlockIndex* block2 = chainman().m_blockman.LookupBlockIndex(block_hash2);
623  const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
624  // Using & instead of && below to avoid short circuiting and leaving
625  // output uninitialized. Cast bool to int to avoid -Wbitwise-instead-of-logical
626  // compiler warnings.
627  return int{FillBlock(ancestor, ancestor_out, lock, active, chainman().m_blockman)} &
628  int{FillBlock(block1, block1_out, lock, active, chainman().m_blockman)} &
629  int{FillBlock(block2, block2_out, lock, active, chainman().m_blockman)};
630  }
631  void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); }
632  double guessVerificationProgress(const uint256& block_hash) override
633  {
634  LOCK(chainman().GetMutex());
635  return chainman().GuessVerificationProgress(chainman().m_blockman.LookupBlockIndex(block_hash));
636  }
637  bool hasBlocks(const uint256& block_hash, int min_height, std::optional<int> max_height) override
638  {
639  // hasBlocks returns true if all ancestors of block_hash in specified
640  // range have block data (are not pruned), false if any ancestors in
641  // specified range are missing data.
642  //
643  // For simplicity and robustness, min_height and max_height are only
644  // used to limit the range, and passing min_height that's too low or
645  // max_height that's too high will not crash or change the result.
646  LOCK(::cs_main);
647  if (const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
648  if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height);
649  for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) {
650  // Check pprev to not segfault if min_height is too low
651  if (block->nHeight <= min_height || !block->pprev) return true;
652  }
653  }
654  return false;
655  }
656  RBFTransactionState isRBFOptIn(const CTransaction& tx) override
657  {
658  if (!m_node.mempool) return IsRBFOptInEmptyMempool(tx);
659  LOCK(m_node.mempool->cs);
660  return IsRBFOptIn(tx, *m_node.mempool);
661  }
662  bool isInMempool(const Txid& txid) override
663  {
664  if (!m_node.mempool) return false;
665  return m_node.mempool->exists(txid);
666  }
667  bool hasDescendantsInMempool(const Txid& txid) override
668  {
669  if (!m_node.mempool) return false;
670  return m_node.mempool->HasDescendants(txid);
671  }
672  bool broadcastTransaction(const CTransactionRef& tx,
673  const CAmount& max_tx_fee,
674  TxBroadcast broadcast_method,
675  std::string& err_string) override
676  {
677  const TransactionError err = BroadcastTransaction(m_node, tx, err_string, max_tx_fee, broadcast_method, /*wait_callback=*/false);
678  // Chain clients only care about failures to accept the tx to the mempool. Disregard non-mempool related failures.
679  // Note: this will need to be updated if BroadcastTransactions() is updated to return other non-mempool failures
680  // that Chain clients do not need to know about.
681  return TransactionError::OK == err;
682  }
683  void getTransactionAncestry(const Txid& txid, size_t& ancestors, size_t& cluster_count, size_t* ancestorsize, CAmount* ancestorfees) override
684  {
685  ancestors = cluster_count = 0;
686  if (!m_node.mempool) return;
687  m_node.mempool->GetTransactionAncestry(txid, ancestors, cluster_count, ancestorsize, ancestorfees);
688  }
689 
690  std::map<COutPoint, CAmount> calculateIndividualBumpFees(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) override
691  {
692  if (!m_node.mempool) {
693  std::map<COutPoint, CAmount> bump_fees;
694  for (const auto& outpoint : outpoints) {
695  bump_fees.emplace(outpoint, 0);
696  }
697  return bump_fees;
698  }
699  return MiniMiner(*m_node.mempool, outpoints).CalculateBumpFees(target_feerate);
700  }
701 
702  std::optional<CAmount> calculateCombinedBumpFee(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) override
703  {
704  if (!m_node.mempool) {
705  return 0;
706  }
707  return MiniMiner(*m_node.mempool, outpoints).CalculateTotalBumpFees(target_feerate);
708  }
709  void getPackageLimits(unsigned int& limit_ancestor_count, unsigned int& limit_descendant_count) override
710  {
711  const CTxMemPool::Limits default_limits{};
712 
713  const CTxMemPool::Limits& limits{m_node.mempool ? m_node.mempool->m_opts.limits : default_limits};
714 
715  limit_ancestor_count = limits.ancestor_count;
716  limit_descendant_count = limits.descendant_count;
717  }
719  {
720  if (!m_node.mempool) return {};
721  if (!m_node.mempool->CheckPolicyLimits(tx)) {
722  return util::Error{Untranslated("too many unconfirmed transactions in cluster")};
723  }
724  return {};
725  }
726  CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc) override
727  {
728  if (!m_node.fee_estimator) return {};
729  return m_node.fee_estimator->estimateSmartFee(num_blocks, calc, conservative);
730  }
731  unsigned int estimateMaxBlocks() override
732  {
733  if (!m_node.fee_estimator) return 0;
734  return m_node.fee_estimator->HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
735  }
736  CFeeRate mempoolMinFee() override
737  {
738  if (!m_node.mempool) return {};
739  return m_node.mempool->GetMinFee();
740  }
741  CFeeRate relayMinFee() override
742  {
743  if (!m_node.mempool) return CFeeRate{DEFAULT_MIN_RELAY_TX_FEE};
744  return m_node.mempool->m_opts.min_relay_feerate;
745  }
746  CFeeRate relayIncrementalFee() override
747  {
748  if (!m_node.mempool) return CFeeRate{DEFAULT_INCREMENTAL_RELAY_FEE};
749  return m_node.mempool->m_opts.incremental_relay_feerate;
750  }
751  CFeeRate relayDustFee() override
752  {
753  if (!m_node.mempool) return CFeeRate{DUST_RELAY_TX_FEE};
754  return m_node.mempool->m_opts.dust_relay_feerate;
755  }
756  bool havePruned() override
757  {
758  LOCK(::cs_main);
759  return chainman().m_blockman.m_have_pruned;
760  }
761  std::optional<int> getPruneHeight() override
762  {
763  LOCK(chainman().GetMutex());
764  return GetPruneHeight(chainman().m_blockman, chainman().ActiveChain());
765  }
766  bool isReadyToBroadcast() override { return !chainman().m_blockman.LoadingBlocks() && !isInitialBlockDownload(); }
767  bool isInitialBlockDownload() override
768  {
769  return chainman().IsInitialBlockDownload();
770  }
771  bool shutdownRequested() override { return ShutdownRequested(m_node); }
772  void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }
773  void initWarning(const bilingual_str& message) override { InitWarning(message); }
774  void initError(const bilingual_str& message) override { InitError(message); }
775  void showProgress(const std::string& title, int progress, bool resume_possible) override
776  {
777  ::uiInterface.ShowProgress(title, progress, resume_possible);
778  }
779  std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) override
780  {
781  return std::make_unique<NotificationsHandlerImpl>(validation_signals(), std::move(notifications));
782  }
783  void waitForNotificationsIfTipChanged(const uint256& old_tip) override
784  {
785  if (!old_tip.IsNull() && old_tip == WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()->GetBlockHash())) return;
786  validation_signals().SyncWithValidationInterfaceQueue();
787  }
788  void waitForNotifications() override
789  {
790  validation_signals().SyncWithValidationInterfaceQueue();
791  }
792  std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override
793  {
794  return std::make_unique<RpcHandlerImpl>(command);
795  }
796  bool rpcEnableDeprecated(const std::string& method) override { return IsDeprecatedRPCEnabled(method); }
797  common::SettingsValue getSetting(const std::string& name) override
798  {
799  return args().GetSetting(name);
800  }
801  std::vector<common::SettingsValue> getSettingsList(const std::string& name) override
802  {
803  return args().GetSettingsList(name);
804  }
805  common::SettingsValue getRwSetting(const std::string& name) override
806  {
808  args().LockSettings([&](const common::Settings& settings) {
809  if (const common::SettingsValue* value = common::FindKey(settings.rw_settings, name)) {
810  result = *value;
811  }
812  });
813  return result;
814  }
815  bool updateRwSetting(const std::string& name,
816  const interfaces::SettingsUpdate& update_settings_func) override
817  {
818  std::optional<interfaces::SettingsAction> action;
819  args().LockSettings([&](common::Settings& settings) {
820  if (auto* value = common::FindKey(settings.rw_settings, name)) {
821  action = update_settings_func(*value);
822  if (value->isNull()) settings.rw_settings.erase(name);
823  } else {
824  UniValue new_value;
825  action = update_settings_func(new_value);
826  if (!new_value.isNull()) settings.rw_settings[name] = std::move(new_value);
827  }
828  });
829  if (!action) return false;
830  // Now dump value to disk if requested
832  }
833  bool overwriteRwSetting(const std::string& name, common::SettingsValue value, interfaces::SettingsAction action) override
834  {
835  return updateRwSetting(name, [&](common::SettingsValue& settings) {
836  settings = std::move(value);
837  return action;
838  });
839  }
840  bool deleteRwSettings(const std::string& name, interfaces::SettingsAction action) override
841  {
842  return overwriteRwSetting(name, {}, action);
843  }
844  void requestMempoolTransactions(Notifications& notifications) override
845  {
846  if (!m_node.mempool) return;
847  LOCK2(::cs_main, m_node.mempool->cs);
848  for (const CTxMemPoolEntry& entry : m_node.mempool->entryAll()) {
849  notifications.transactionAddedToMempool(entry.GetSharedTx());
850  }
851  }
852  bool hasAssumedValidChain() override
853  {
854  LOCK(::cs_main);
855  return bool{chainman().CurrentChainstate().m_from_snapshot_blockhash};
856  }
857 
858  NodeContext* context() override { return &m_node; }
859  ArgsManager& args() { return *Assert(m_node.args); }
860  ChainstateManager& chainman() { return *Assert(m_node.chainman); }
861  ValidationSignals& validation_signals() { return *Assert(m_node.validation_signals); }
862  NodeContext& m_node;
863 };
864 
865 class BlockTemplateImpl : public BlockTemplate
866 {
867 public:
868  explicit BlockTemplateImpl(BlockAssembler::Options assemble_options,
869  std::unique_ptr<CBlockTemplate> block_template,
870  NodeContext& node) : m_assemble_options(std::move(assemble_options)),
871  m_block_template(std::move(block_template)),
872  m_node(node)
873  {
875  }
876 
877  CBlockHeader getBlockHeader() override
878  {
879  return m_block_template->block;
880  }
881 
882  CBlock getBlock() override
883  {
884  return m_block_template->block;
885  }
886 
887  std::vector<CAmount> getTxFees() override
888  {
889  return m_block_template->vTxFees;
890  }
891 
892  std::vector<int64_t> getTxSigops() override
893  {
894  return m_block_template->vTxSigOpsCost;
895  }
896 
897  CoinbaseTx getCoinbaseTx() override
898  {
899  return m_block_template->m_coinbase_tx;
900  }
901 
902  std::vector<uint256> getCoinbaseMerklePath() override
903  {
904  return TransactionMerklePath(m_block_template->block, 0);
905  }
906 
907  bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CTransactionRef coinbase) override
908  {
909  AddMerkleRootAndCoinbase(m_block_template->block, std::move(coinbase), version, timestamp, nonce);
910  return chainman().ProcessNewBlock(std::make_shared<const CBlock>(m_block_template->block), /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/nullptr);
911  }
912 
913  std::unique_ptr<BlockTemplate> waitNext(BlockWaitOptions options) override
914  {
915  auto new_template = WaitAndCreateNewBlock(chainman(), notifications(), m_node.mempool.get(), m_block_template, options, m_assemble_options, m_interrupt_wait);
916  if (new_template) return std::make_unique<BlockTemplateImpl>(m_assemble_options, std::move(new_template), m_node);
917  return nullptr;
918  }
919 
920  void interruptWait() override
921  {
922  InterruptWait(notifications(), m_interrupt_wait);
923  }
924 
925  const BlockAssembler::Options m_assemble_options;
926 
927  const std::unique_ptr<CBlockTemplate> m_block_template;
928 
929  bool m_interrupt_wait{false};
930  ChainstateManager& chainman() { return *Assert(m_node.chainman); }
931  KernelNotifications& notifications() { return *Assert(m_node.notifications); }
932  NodeContext& m_node;
933 };
934 
935 class MinerImpl : public Mining
936 {
937 public:
938  explicit MinerImpl(NodeContext& node) : m_node(node) {}
939 
940  bool isTestChain() override
941  {
942  return chainman().GetParams().IsTestChain();
943  }
944 
945  bool isInitialBlockDownload() override
946  {
947  return chainman().IsInitialBlockDownload();
948  }
949 
950  std::optional<BlockRef> getTip() override
951  {
952  return GetTip(chainman());
953  }
954 
955  std::optional<BlockRef> waitTipChanged(uint256 current_tip, MillisecondsDouble timeout) override
956  {
957  return WaitTipChanged(chainman(), notifications(), current_tip, timeout, m_interrupt_mining);
958  }
959 
960  std::unique_ptr<BlockTemplate> createNewBlock(const BlockCreateOptions& options, bool cooldown) override
961  {
962  // Reject too-small values instead of clamping so callers don't silently
963  // end up mining with different options than requested. This matches the
964  // behavior of the `-blockreservedweight` startup option, which rejects
965  // values below MINIMUM_BLOCK_RESERVED_WEIGHT.
966  if (options.block_reserved_weight && options.block_reserved_weight < MINIMUM_BLOCK_RESERVED_WEIGHT) {
967  throw std::runtime_error(strprintf("block_reserved_weight (%zu) must be at least %u weight units",
968  *options.block_reserved_weight,
970  }
971 
972  // Ensure m_tip_block is set so consumers of BlockTemplate can rely on that.
973  std::optional<BlockRef> maybe_tip{waitTipChanged(uint256::ZERO, MillisecondsDouble::max())};
974 
975  if (!maybe_tip) return {};
976 
977  if (cooldown) {
978  // Do not return a template during IBD, because it can have long
979  // pauses and sometimes takes a while to get started. Although this
980  // is useful in general, it's gated behind the cooldown argument,
981  // because on regtest and single miner signets this would wait
982  // forever if no block was mined in the past day.
983  while (chainman().IsInitialBlockDownload()) {
984  maybe_tip = waitTipChanged(maybe_tip->hash, MillisecondsDouble{1000});
985  if (!maybe_tip || chainman().m_interrupt || WITH_LOCK(notifications().m_tip_block_mutex, return m_interrupt_mining)) return {};
986  }
987 
988  // Also wait during the final catch-up moments after IBD.
989  if (!CooldownIfHeadersAhead(chainman(), notifications(), *maybe_tip, m_interrupt_mining)) return {};
990  }
991 
992  BlockAssembler::Options assemble_options{options};
993  ApplyArgsManOptions(*Assert(m_node.args), assemble_options);
994  return std::make_unique<BlockTemplateImpl>(assemble_options, BlockAssembler{chainman().ActiveChainstate(), context()->mempool.get(), assemble_options}.CreateNewBlock(), m_node);
995  }
996 
997  void interrupt() override
998  {
999  InterruptWait(notifications(), m_interrupt_mining);
1000  }
1001 
1002  bool checkBlock(const CBlock& block, const node::BlockCheckOptions& options, std::string& reason, std::string& debug) override
1003  {
1004  LOCK(chainman().GetMutex());
1005  BlockValidationState state{TestBlockValidity(chainman().ActiveChainstate(), block, /*check_pow=*/options.check_pow, /*check_merkle_root=*/options.check_merkle_root)};
1006  reason = state.GetRejectReason();
1007  debug = state.GetDebugMessage();
1008  return state.IsValid();
1009  }
1010 
1011  NodeContext* context() override { return &m_node; }
1012  ChainstateManager& chainman() { return *Assert(m_node.chainman); }
1013  KernelNotifications& notifications() { return *Assert(m_node.notifications); }
1014  // Treat as if guarded by notifications().m_tip_block_mutex
1015  bool m_interrupt_mining{false};
1016  NodeContext& m_node;
1017 };
1018 } // namespace
1019 } // namespace node
1020 
1021 namespace interfaces {
1022 std::unique_ptr<Node> MakeNode(node::NodeContext& context) { return std::make_unique<node::NodeImpl>(context); }
1023 std::unique_ptr<Chain> MakeChain(node::NodeContext& context) { return std::make_unique<node::ChainImpl>(context); }
1024 std::unique_ptr<Mining> MakeMining(node::NodeContext& context, bool wait_loaded)
1025 {
1026  if (wait_loaded) {
1027  node::KernelNotifications& kernel_notifications(*Assert(context.notifications));
1028  util::SignalInterrupt& interrupt(*Assert(context.shutdown_signal));
1029  WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock);
1030  kernel_notifications.m_tip_block_cv.wait(lock, [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) {
1031  return kernel_notifications.m_state.chainstate_loaded || interrupt;
1032  });
1033  if (interrupt) return nullptr;
1034  }
1035  return std::make_unique<node::MinerImpl>(context);
1036 }
1037 } // namespace interfaces
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:403
TransactionError
Definition: types.h:28
virtual bool haveBlockOnDisk(int height)=0
Check that the block is available on disk (i.e.
Helper for findBlock to selectively return pieces of block data.
Definition: chain.h:52
const GCSFilter & GetFilter() const LIFETIMEBOUND
Definition: blockfilter.h:137
virtual bool deleteRwSettings(const std::string &name, SettingsAction action=SettingsAction::WRITE)=0
Delete a given setting in <datadir>/settings.json.
Interval between compact filter checkpoints.
virtual bool findCommonAncestor(const uint256 &block_hash1, const uint256 &block_hash2, const FoundBlock &ancestor_out={}, const FoundBlock &block1_out={}, const FoundBlock &block2_out={})=0
Find most recent common ancestor between two blocks and optionally return block information.
virtual void findCoins(std::map< COutPoint, Coin > &coins)=0
Look up unspent output information.
virtual void getPackageLimits(unsigned int &limit_ancestor_count, unsigned int &limit_descendant_count)=0
Get the node&#39;s package limits.
Block template interface.
Definition: mining.h:31
TxBroadcast
How to broadcast a local transaction.
Definition: types.h:165
Block tip (could be a header or not, depends on the subscribed signal).
Definition: node.h:275
std::any context
Definition: request.h:62
Enables interaction with an external signing device or service, such as a hardware wallet...
virtual void TransactionRemovedFromMempool(const CTransactionRef &tx, MemPoolRemovalReason reason, uint64_t mempool_sequence)
Notifies listeners of a transaction leaving mempool.
static constexpr unsigned int DEFAULT_INCREMENTAL_RELAY_FEE
Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or rep...
Definition: policy.h:47
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:853
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition: validation.h:93
BCLog::Logger & LogInstance()
Definition: logging.cpp:26
virtual std::optional< int > getHeight()=0
Get current chain height, not including genesis block (returns 0 if chain only contains genesis block...
virtual CBlockHeader getBlockHeader()=0
virtual bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock &block={})=0
Find first block in the chain with timestamp >= the given time and height >= than the given height...
CClientUIInterface uiInterface
virtual void getTransactionAncestry(const Txid &txid, size_t &ancestors, size_t &cluster_count, size_t *ancestorsize=nullptr, CAmount *ancestorfees=nullptr)=0
Calculate mempool ancestor and cluster counts for the given transaction.
assert(!tx.IsCoinBase())
Generate a new block, without valid proof-of-work.
Definition: miner.h:60
Describes a place in the block chain to another node such that if the other node doesn&#39;t have the sam...
Definition: block.h:116
NodeContext & m_node
Definition: interfaces.cpp:862
virtual std::unique_ptr< Handler > handleNotifications(std::shared_ptr< Notifications > notifications)=0
Register handler for notifications.
virtual void BlockDisconnected(const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex)
Notifies listeners of a block being disconnected Provides the block that was disconnected.
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:100
#define TRY_LOCK(cs, name)
Definition: sync.h:263
RBFTransactionState IsRBFOptIn(const CTransaction &tx, const CTxMemPool &pool)
Determine whether an unconfirmed transaction is signaling opt-in to RBF according to BIP 125 This inv...
Definition: rbf.cpp:24
std::map< std::string, SettingsValue > forced_settings
Map of setting name to forced setting value.
Definition: settings.h:34
unsigned int nonce
Definition: miner_tests.cpp:82
Stored settings.
Definition: settings.h:32
util::SignalInterrupt * shutdown_signal
Interrupt object used to track whether node shutdown was requested.
Definition: context.h:65
common::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
Definition: args.cpp:859
Bilingual messages:
Definition: translation.h:24
Definition: block.h:73
Actor actor
Definition: server.h:69
std::vector< uint256 > TransactionMerklePath(const CBlock &block, uint32_t position)
Compute merkle path to the specified transaction.
Definition: merkle.cpp:172
virtual uint256 getBlockHash(int height)=0
Get block hash. Height must be valid or this function will abort.
virtual CFeeRate mempoolMinFee()=0
Mempool minimum fee.
virtual common::SettingsValue getSetting(const std::string &arg)=0
Get settings value.
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
Definition: validation.h:939
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1172
Options struct containing limit options for a CTxMemPool.
bool m_interrupt_mining
An in-memory indexed chain of blocks.
Definition: chain.h:379
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:253
virtual CFeeRate relayDustFee()=0
Relay dust fee setting (-dustrelayfee), reflecting lowest rate it&#39;s economical to spend...
virtual bool hasBlockFilterIndex(BlockFilterType filter_type)=0
Returns whether a block filter index is available.
virtual std::vector< common::SettingsValue > getSettingsList(const std::string &arg)=0
Get list of settings values.
BlockFilterIndex * GetBlockFilterIndex(BlockFilterType filter_type)
Get a block filter index by type.
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:82
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
Information about chainstate that notifications are sent from.
Definition: types.h:18
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
Definition: chain.cpp:155
bool GetProxy(enum Network net, Proxy &proxyInfoOut)
Definition: netbase.cpp:709
virtual bool isInitialBlockDownload()=0
Check if in IBD.
std::optional< BlockRef > GetTip(ChainstateManager &chainman)
Definition: miner.cpp:450
#define REVERSE_LOCK(g, cs)
Definition: sync.h:244
static constexpr unsigned int DEFAULT_MIN_RELAY_TX_FEE
Default for -minrelaytxfee, minimum relay fee for transactions.
Definition: policy.h:69
Hash/height pair to help track and identify blocks.
Definition: types.h:13
virtual std::optional< int > getPruneHeight()=0
Get the current prune height.
Interrupt(node)
bool MatchAny(const ElementSet &elements) const
Checks if any of the given elements may be in the set.
bool removeCommand(const std::string &name, const CRPCCommand *pcmd)
Definition: server.cpp:260
::ExternalSigner m_signer
Definition: interfaces.cpp:101
std::optional< BlockRef > WaitTipChanged(ChainstateManager &chainman, KernelNotifications &kernel_notifications, const uint256 &current_tip, MillisecondsDouble &timeout, bool &interrupt)
Definition: miner.cpp:492
common::SettingsValue GetPersistentSetting(const std::string &name) const
Get current setting from config file or read/write settings file, ignoring nonpersistent command line...
Definition: args.cpp:449
Definition: common.h:29
bool isNum() const
Definition: univalue.h:86
virtual std::unique_ptr< BlockTemplate > waitNext(node::BlockWaitOptions options={})=0
Waits for fees in the next block to rise, a new tip or the timeout.
Add the transaction to the mempool and broadcast to all peers for which tx relay is enabled...
bool AppInitLockDirectories()
Lock bitcoin core critical directories.
Definition: init.cpp:1195
util::Result< void > ApplyArgsManOptions(const ArgsManager &args, BlockManager::Options &opts)
const CRPCCommand * m_wrapped_command
Definition: interfaces.cpp:542
std::unique_ptr< Node > MakeNode(node::NodeContext &context)
Return implementation of Node interface.
Int getInt() const
Definition: univalue.h:140
void InitWarning(const bilingual_str &str)
Show warning message.
virtual void TransactionAddedToMempool(const NewMempoolTransactionInfo &tx, uint64_t mempool_sequence)
Notifies listeners of a transaction having been added to mempool.
std::string m_name
Name of signer.
virtual double guessVerificationProgress(const uint256 &block_hash)=0
Estimate fraction of total transactions verified if blocks up to the specified block hash are verifie...
Implement this to subscribe to events generated in validation and mempool.
virtual bool hasDescendantsInMempool(const Txid &txid)=0
Check if transaction has descendants in mempool.
RBFTransactionState
The rbf state of unconfirmed transactions.
Definition: rbf.h:29
std::unique_ptr< CTxMemPool > mempool
Definition: context.h:68
bool AppInitBasicSetup(const ArgsManager &args, std::atomic< int > &exit_status)
Initialize bitcoin core: Basic context setup.
Definition: init.cpp:882
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
Definition: mempool_entry.h:65
virtual node::CoinbaseTx getCoinbaseTx()=0
Return fields needed to construct a coinbase transaction.
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
UniValue execute(const JSONRPCRequest &request) const
Execute a method.
Definition: server.cpp:482
virtual std::optional< int > findLocatorFork(const CBlockLocator &locator)=0
Return height of the highest block on chain in common with the locator, which will either be the orig...
CRPCCommand m_command
Definition: interfaces.cpp:541
std::string strMethod
Definition: request.h:56
uint256 GetBlockHash() const
Definition: chain.h:198
CBlockIndex * FindEarliestAtLeast(int64_t nTime, int height) const
Find the earliest block with timestamp equal or greater than the given time and height equal or great...
Definition: chain.cpp:61
BlockFilterType
Definition: blockfilter.h:93
NodeContext struct containing references to chain state and connection state.
Definition: context.h:56
#define LOCK2(cs1, cs2)
Definition: sync.h:259
std::string name
Definition: server.h:68
CRPCTable tableRPC
Definition: server.cpp:544
Interface giving clients (RPC, Stratum v2 Template Provider in the future) ability to create block te...
Definition: mining.h:96
virtual bool hasAssumedValidChain()=0
Return true if an assumed-valid snapshot is in use.
std::unique_ptr< Mining > MakeMining(node::NodeContext &node, bool wait_loaded=true)
Return implementation of Mining interface.
const BlockAssembler::Options m_assemble_options
Definition: interfaces.cpp:925
RBFTransactionState IsRBFOptInEmptyMempool(const CTransaction &tx)
Definition: rbf.cpp:52
ArgsManager & args
Definition: bitcoind.cpp:277
std::vector< common::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: args.cpp:867
std::function< std::optional< interfaces::SettingsAction >(common::SettingsValue &)> SettingsUpdate
Definition: chain.h:91
std::map< std::string, std::vector< SettingsValue > > command_line_options
Map of setting name to list of command line values.
Definition: settings.h:36
SettingsAction
The action to be taken after updating a settings value.
Definition: chain.h:86
virtual bool findAncestorByHeight(const uint256 &block_hash, int ancestor_height, const FoundBlock &ancestor_out={})=0
Find ancestor of block at specified height and optionally return ancestor information.
virtual bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CTransactionRef coinbase)=0
Construct and broadcast the block.
UniValue params
Definition: request.h:57
virtual CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation *calc=nullptr)=0
Estimate smart fee.
#define LOCK(cs)
Definition: sync.h:258
const char * name
Definition: rest.cpp:48
bool InitError(const bilingual_str &str)
Show error message.
void AddMerkleRootAndCoinbase(CBlock &block, CTransactionRef coinbase, uint32_t version, uint32_t timestamp, uint32_t nonce)
Definition: miner.cpp:336
void StartMapPort(bool enable)
Definition: mapport.cpp:137
virtual bool updateRwSetting(const std::string &name, const SettingsUpdate &update_function)=0
Updates a setting in <datadir>/settings.json.
Complete block filter struct as defined in BIP 157.
Definition: blockfilter.h:115
virtual bool overwriteRwSetting(const std::string &name, common::SettingsValue value, SettingsAction action=SettingsAction::WRITE)=0
Replace a setting in <datadir>/settings.json with a new value.
Template containing all coinbase transaction fields that are set by our miner code.
Definition: types.h:119
static const uint256 ZERO
Definition: uint256.h:203
virtual std::unique_ptr< Handler > handleRpc(const CRPCCommand &command)=0
Register handler for RPC.
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
Notifies listeners when the block chain tip advances.
virtual std::vector< CAmount > getTxFees()=0
bool AppInitMain(NodeContext &node, interfaces::BlockAndHeaderTipInfo *tip_info)
Bitcoin core main initialization.
Definition: init.cpp:1421
virtual bool findBlock(const uint256 &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
virtual bool broadcastTransaction(const CTransactionRef &tx, const CAmount &max_tx_fee, node::TxBroadcast broadcast_method, std::string &err_string)=0
Process a local transaction, optionally adding it to the mempool and optionally broadcasting it to th...
virtual void waitForNotificationsIfTipChanged(const uint256 &old_tip)=0
Wait for pending notifications to be processed unless block hash points to the current chain tip...
void InterruptWait(KernelNotifications &kernel_notifications, bool &interrupt_wait)
Definition: miner.cpp:354
NodeContext * m_context
Definition: interfaces.cpp:430
virtual void requestMempoolTransactions(Notifications &notifications)=0
Synchronously send transactionAddedToMempool notifications about all current mempool transactions to ...
Network
A network type.
Definition: netaddress.h:33
std::optional< int > GetPruneHeight(const BlockManager &blockman, const CChain &chain)
Return height of highest block that has been pruned, or std::nullopt if no blocks have been pruned...
Definition: blockchain.cpp:883
static CService ip(uint32_t i)
Block and header tip information.
Definition: node.h:49
int64_t NodeId
Definition: net.h:103
virtual std::optional< CAmount > calculateCombinedBumpFee(const std::vector< COutPoint > &outpoints, const CFeeRate &target_feerate)=0
Calculate the combined bump fee for an input set per the same strategy.
virtual void BlockConnected(const kernel::ChainstateRole &role, const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex)
Notifies listeners of a block being connected.
virtual void interrupt()=0
Interrupts createNewBlock and waitTipChanged.
#define WAIT_LOCK(cs, name)
Definition: sync.h:264
virtual std::vector< uint256 > getCoinbaseMerklePath()=0
Compute merkle path to the coinbase transaction.
virtual bool checkBlock(const CBlock &block, const node::BlockCheckOptions &options, std::string &reason, std::string &debug)=0
Checks if a given block is valid.
std::shared_ptr< NotificationsProxy > m_proxy
Definition: interfaces.cpp:503
Invalid wallet specified.
Definition: protocol.h:80
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:28
constexpr bool IsNull() const
Definition: uint256.h:48
Wallet chain client that in addition to having chain client methods for starting up, shutting down, and registering RPCs, also has additional methods (called by the GUI) to load and create wallets.
Definition: wallet.h:315
bool IsDeprecatedRPCEnabled(const std::string &method)
Definition: server.cpp:339
virtual bool isInitialBlockDownload()=0
Returns whether IBD is still in progress.
bool isNull() const
Definition: univalue.h:81
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:289
void FindCoins(const NodeContext &node, std::map< COutPoint, Coin > &coins)
Look up unspent output information.
Definition: coin.cpp:12
External signer interface used by the GUI.
Definition: node.h:59
std::unordered_set< Element, ByteVectorHash > ElementSet
Definition: blockfilter.h:33
virtual void initWarning(const bilingual_str &message)=0
Send init warning.
Definition: messages.h:21
Definition: netbase.h:58
virtual bool isInMempool(const Txid &txid)=0
Check if transaction is in mempool.
Generic interface for managing an event handler or callback function registered with another interfac...
Definition: handler.h:22
Helper class that manages an interrupt flag, and allows a thread or signal to interrupt another threa...
int flags
Definition: bitcoin-tx.cpp:529
virtual node::NodeContext * context()
Get internal node context.
Definition: chain.h:392
static constexpr unsigned int DUST_RELAY_TX_FEE
Min feerate for defining dust.
Definition: policy.h:67
Network address.
Definition: netaddress.h:112
256-bit opaque blob.
Definition: uint256.h:195
virtual bool isReadyToBroadcast()=0
Check if the node is ready to broadcast transactions.
virtual node::NodeContext * context()
Get internal node context.
Definition: mining.h:159
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:51
std::unique_ptr< Chain > MakeChain(node::NodeContext &node)
Return implementation of Chain interface.
Shutdown(node)
CategoryMask GetCategoryMask() const
Definition: logging.h:262
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr, bool backup=false) const
Write settings file or backup settings file.
Definition: args.cpp:429
const auto command
auto result
Definition: common-types.h:74
bool AppInitParameterInteraction(const ArgsManager &args)
Initialization: parameter interaction.
Definition: init.cpp:919
void RegisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Register subscriber.
virtual bool findAncestorByHash(const uint256 &block_hash, const uint256 &ancestor_hash, const FoundBlock &ancestor_out={})=0
Return whether block descends from a specified ancestor, and optionally return ancestor information...
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:117
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:93
const CChainParams & Params()
Return the currently selected parameters.
bool ShutdownRequested(node::NodeContext &node)
Return whether node shutdown was requested.
Definition: init.cpp:250
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: args.cpp:461
virtual std::optional< BlockRef > getTip()=0
Returns the hash and height for the tip of this chain.
virtual std::vector< int64_t > getTxSigops()=0
std::unique_ptr< KernelNotifications > notifications
Issues blocking calls about sync status, errors and warnings.
Definition: context.h:86
std::string URI
Definition: request.h:59
uint64_t CategoryMask
Definition: categories.h:12
bool check_pow
Set false to omit the proof-of-work check.
Definition: types.h:111
virtual void initMessage(const std::string &message)=0
Send init message.
virtual std::map< COutPoint, CAmount > calculateIndividualBumpFees(const std::vector< COutPoint > &outpoints, const CFeeRate &target_feerate)=0
For each outpoint, calculate the fee-bumping cost to spend this outpoint at the specified.
bool AppInitSanityChecks(const kernel::Context &kernel)
Initialization sanity checks.
Definition: init.cpp:1176
int exit_status
const CTransactionRef m_tx
Fee rate in satoshis per virtualbyte: CAmount / vB the feerate is represented internally as FeeFrac...
Definition: feerate.h:31
virtual RBFTransactionState isRBFOptIn(const CTransaction &tx)=0
Check if transaction is RBF opt in.
virtual bool hasBlocks(const uint256 &block_hash, int min_height=0, std::optional< int > max_height={})=0
Return true if data is available for all blocks in the specified range of blocks. ...
bool CooldownIfHeadersAhead(ChainstateManager &chainman, KernelNotifications &kernel_notifications, const BlockRef &last_tip, bool &interrupt_mining)
Wait while the best known header extends the current chain tip AND at least one block is being added ...
Definition: miner.cpp:458
bool m_interrupt_wait
Definition: interfaces.cpp:929
virtual void showProgress(const std::string &title, int progress, bool resume_possible)=0
Send progress indicator.
std::unique_ptr< Handler > MakeSignalHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
Definition: interfaces.cpp:47
bool check_merkle_root
Set false to omit the merkle root check.
Definition: types.h:106
TransactionError BroadcastTransaction(NodeContext &node, const CTransactionRef tx, std::string &err_string, const CAmount &max_tx_fee, TxBroadcast broadcast_method, bool wait_callback)
Submit a transaction to the mempool and (optionally) relay it to all P2P peers.
Definition: transaction.cpp:32
std::map< CSubNet, CBanEntry > banmap_t
Definition: net_types.h:41
Wrapper around std::unique_lock style lock for MutexType.
Definition: sync.h:145
virtual unsigned int estimateMaxBlocks()=0
Fee estimator max target.
CBlockLocator GetLocator(const CBlockIndex *index)
Get a locator for a block index entry.
Definition: chain.cpp:45
std::map< std::string, SettingsValue > rw_settings
Map of setting name to read-write file setting value.
Definition: settings.h:38
virtual bool shutdownRequested()=0
Check if shutdown requested.
bool AppInitInterfaces(NodeContext &node)
Initialize node and wallet interface pointers.
Definition: init.cpp:1207
interfaces::BlockInfo MakeBlockInfo(const CBlockIndex *index, const CBlock *data)
Return data from block index.
Definition: chain.cpp:18
virtual void disconnect()=0
Disconnect the handler.
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:280
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:106
BlockValidationState TestBlockValidity(Chainstate &chainstate, const CBlock &block, const bool check_pow, const bool check_merkle_root)
Verify a block, including transactions.
virtual util::Result< void > checkChainLimits(const CTransactionRef &tx)=0
Check if transaction will pass the mempool&#39;s chain limits.
virtual void ChainStateFlushed(const kernel::ChainstateRole &role, const CBlockLocator &locator)
Notifies listeners of the new active block chain on-disk.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:110
std::string GetRejectReason() const
Definition: validation.h:109
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: args.h:425
full block available in blk*.dat
Definition: chain.h:75
virtual std::optional< BlockRef > waitTipChanged(uint256 current_tip, MillisecondsDouble timeout=MillisecondsDouble::max())=0
Waits for the connected tip to change.
virtual CBlock getBlock()=0
is a home for public enum and struct type definitions that are used internally by node code...
virtual bool isTestChain()=0
If this chain is exclusively used for testing.
ValidationSignals & m_signals
Definition: interfaces.cpp:502
virtual bool rpcEnableDeprecated(const std::string &method)=0
Check if deprecated RPC is enabled.
std::unique_ptr< CBlockTemplate > WaitAndCreateNewBlock(ChainstateManager &chainman, KernelNotifications &kernel_notifications, CTxMemPool *mempool, const std::unique_ptr< CBlockTemplate > &block_template, const BlockWaitOptions &options, const BlockAssembler::Options &assemble_options, bool &interrupt_wait)
Return a new block template when fees rise to a certain threshold or after a new tip; return nullopt ...
Definition: miner.cpp:361
std::vector< std::string > listCommands() const
Returns a list of registered commands.
Definition: server.cpp:519
static bool Enumerate(const std::string &command, std::vector< ExternalSigner > &signers, const std::string &chain)
Obtain a list of signers.
virtual common::SettingsValue getRwSetting(const std::string &name)=0
Return <datadir>/settings.json setting value.
const std::unique_ptr< CBlockTemplate > m_block_template
Definition: interfaces.cpp:927
ConnectionDirection
Definition: netbase.h:33
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
Definition: string.h:205
Definition: musig.c:31
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: cs_main.cpp:8
virtual void initError(const bilingual_str &message)=0
Send init error.
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:69
virtual CFeeRate relayIncrementalFee()=0
Relay incremental fee setting (-incrementalrelayfee), reflecting cost of relay.
virtual CFeeRate relayMinFee()=0
Relay current minimum fee (from -minrelaytxfee and -incrementalrelayfee settings).
virtual void waitForNotifications()=0
Wait for all pending notifications up to this point to be processed.
static constexpr unsigned int MINIMUM_BLOCK_RESERVED_WEIGHT
This accounts for the block header, var_int encoding of the transaction count and a minimally viable ...
Definition: policy.h:33
void UnregisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Unregister subscriber.
std::chrono::duration< double, std::chrono::milliseconds::period > MillisecondsDouble
Definition: time.h:94
unsigned int nTx
Number of transactions in this block.
Definition: chain.h:123
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:26
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:72
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:764
virtual void interruptWait()=0
Interrupts the current wait for the next block template.
virtual bool havePruned()=0
Check if any block has been pruned.
#define Assert(val)
Identity function.
Definition: check.h:113
std::shared_ptr< Chain::Notifications > m_notifications
Definition: interfaces.cpp:483
#define LogError(...)
Definition: log.h:97
virtual std::unique_ptr< BlockTemplate > createNewBlock(const node::BlockCreateOptions &options={}, bool cooldown=true)=0
Construct a new block template.
auto FindKey(Map &&map, Key &&key) -> decltype(&map.at(key))
Map lookup helper.
Definition: settings.h:107
virtual std::optional< bool > blockFilterMatchesAny(BlockFilterType filter_type, const uint256 &block_hash, const GCSFilter::ElementSet &filter_set)=0
Returns whether any of the elements match the block via a BIP 157 block filter or std::nullopt if the...