Bitcoin ABC  0.26.3
P2P Digital Currency
interfaces.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018 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 <chain.h>
8 #include <chainparams.h>
9 #include <common/args.h>
10 #include <config.h>
11 #include <init.h>
12 #include <interfaces/chain.h>
13 #include <interfaces/handler.h>
14 #include <interfaces/node.h>
15 #include <interfaces/wallet.h>
16 #include <kernel/mempool_entry.h>
17 #include <mapport.h>
18 #include <net.h>
19 #include <net_processing.h>
20 #include <netaddress.h>
21 #include <netbase.h>
22 #include <node/blockstorage.h>
23 #include <node/coin.h>
24 #include <node/context.h>
25 #include <node/transaction.h>
26 #include <node/ui_interface.h>
27 #include <policy/settings.h>
28 #include <primitives/block.h>
29 #include <primitives/transaction.h>
30 #include <rpc/protocol.h>
31 #include <rpc/server.h>
32 #include <shutdown.h>
33 #include <sync.h>
34 #include <txmempool.h>
35 #include <uint256.h>
36 #include <util/check.h>
37 #include <util/translation.h>
38 #include <validation.h>
39 #include <validationinterface.h>
40 #include <warnings.h>
41 
42 #if defined(HAVE_CONFIG_H)
43 #include <config/bitcoin-config.h>
44 #endif
45 
46 #include <univalue.h>
47 
48 #include <boost/signals2/signal.hpp>
49 
50 #include <memory>
51 #include <utility>
52 
54 
56 using interfaces::Chain;
60 using interfaces::Node;
62 
63 namespace node {
64 namespace {
65 
66  class NodeImpl : public Node {
67  private:
68  ChainstateManager &chainman() { return *Assert(m_context->chainman); }
69 
70  public:
71  explicit NodeImpl(NodeContext *context) { setContext(context); }
72  void initLogging() override { InitLogging(*Assert(m_context->args)); }
73  void initParameterInteraction() override {
75  }
76  bilingual_str getWarnings() override { return GetWarnings(true); }
77  bool baseInitialize(Config &config) override {
78  return AppInitBasicSetup(gArgs) &&
82  }
83  bool appInitMain(Config &config, RPCServer &rpcServer,
84  HTTPRPCRequestProcessor &httpRPCRequestProcessor,
85  interfaces::BlockAndHeaderTipInfo *tip_info) override {
86  return AppInitMain(config, rpcServer, httpRPCRequestProcessor,
87  *m_context, tip_info);
88  }
89  void appShutdown() override {
92  }
93  void startShutdown() override {
94  StartShutdown();
95  // Stop RPC for clean shutdown if any of waitfor* commands is
96  // executed.
97  if (gArgs.GetBoolArg("-server", false)) {
98  InterruptRPC();
99  StopRPC();
100  }
101  }
102  bool shutdownRequested() override { return ShutdownRequested(); }
103  bool isPersistentSettingIgnored(const std::string &name) override {
104  bool ignored = false;
105  gArgs.LockSettings([&](util::Settings &settings) {
106  if (auto *options =
108  ignored = !options->empty();
109  }
110  });
111  return ignored;
112  }
114  getPersistentSetting(const std::string &name) override {
116  }
117  void updateRwSetting(const std::string &name,
118  const util::SettingsValue &value) override {
119  gArgs.LockSettings([&](util::Settings &settings) {
120  if (value.isNull()) {
121  settings.rw_settings.erase(name);
122  } else {
123  settings.rw_settings[name] = value;
124  }
125  });
127  }
128  void forceSetting(const std::string &name,
129  const util::SettingsValue &value) override {
130  gArgs.LockSettings([&](util::Settings &settings) {
131  if (value.isNull()) {
132  settings.forced_settings.erase(name);
133  } else {
134  settings.forced_settings[name] = value;
135  }
136  });
137  }
138  void resetSettings() override {
139  gArgs.WriteSettingsFile(/*errors=*/nullptr, /*backup=*/true);
140  gArgs.LockSettings([&](util::Settings &settings) {
141  settings.rw_settings.clear();
142  });
144  }
145  void mapPort(bool use_upnp, bool use_natpmp) override {
146  StartMapPort(use_upnp, use_natpmp);
147  }
148  bool getProxy(Network net, proxyType &proxy_info) override {
149  return GetProxy(net, proxy_info);
150  }
151  size_t getNodeCount(CConnman::NumConnections flags) override {
152  return m_context->connman ? m_context->connman->GetNodeCount(flags)
153  : 0;
154  }
155  bool getNodesStats(NodesStats &stats) override {
156  stats.clear();
157 
158  if (m_context->connman) {
159  std::vector<CNodeStats> stats_temp;
160  m_context->connman->GetNodeStats(stats_temp);
161 
162  stats.reserve(stats_temp.size());
163  for (auto &node_stats_temp : stats_temp) {
164  stats.emplace_back(std::move(node_stats_temp), false,
165  CNodeStateStats());
166  }
167 
168  // Try to retrieve the CNodeStateStats for each node.
169  if (m_context->peerman) {
170  TRY_LOCK(::cs_main, lockMain);
171  if (lockMain) {
172  for (auto &node_stats : stats) {
173  std::get<1>(node_stats) =
174  m_context->peerman->GetNodeStateStats(
175  std::get<0>(node_stats).nodeid,
176  std::get<2>(node_stats));
177  }
178  }
179  }
180  return true;
181  }
182  return false;
183  }
184  bool getBanned(banmap_t &banmap) override {
185  if (m_context->banman) {
186  m_context->banman->GetBanned(banmap);
187  return true;
188  }
189  return false;
190  }
191  bool ban(const CNetAddr &net_addr, int64_t ban_time_offset) override {
192  if (m_context->banman) {
193  m_context->banman->Ban(net_addr, ban_time_offset);
194  return true;
195  }
196  return false;
197  }
198  bool unban(const CSubNet &ip) override {
199  if (m_context->banman) {
200  m_context->banman->Unban(ip);
201  return true;
202  }
203  return false;
204  }
205  bool disconnectByAddress(const CNetAddr &net_addr) override {
206  if (m_context->connman) {
207  return m_context->connman->DisconnectNode(net_addr);
208  }
209  return false;
210  }
211  bool disconnectById(NodeId id) override {
212  if (m_context->connman) {
213  return m_context->connman->DisconnectNode(id);
214  }
215  return false;
216  }
217  int64_t getTotalBytesRecv() override {
218  return m_context->connman ? m_context->connman->GetTotalBytesRecv()
219  : 0;
220  }
221  int64_t getTotalBytesSent() override {
222  return m_context->connman ? m_context->connman->GetTotalBytesSent()
223  : 0;
224  }
225  size_t getMempoolSize() override {
226  return m_context->mempool ? m_context->mempool->size() : 0;
227  }
228  size_t getMempoolDynamicUsage() override {
229  return m_context->mempool ? m_context->mempool->DynamicMemoryUsage()
230  : 0;
231  }
232  bool getHeaderTip(int &height, int64_t &block_time) override {
233  LOCK(::cs_main);
234  auto best_header = chainman().m_best_header;
235  if (best_header) {
236  height = best_header->nHeight;
237  block_time = best_header->GetBlockTime();
238  return true;
239  }
240  return false;
241  }
242  int getNumBlocks() override {
243  LOCK(::cs_main);
244  return chainman().ActiveChain().Height();
245  }
246  BlockHash getBestBlockHash() override {
247  const CBlockIndex *tip =
248  WITH_LOCK(::cs_main, return chainman().ActiveTip());
249  return tip ? tip->GetBlockHash()
250  : chainman().GetParams().GenesisBlock().GetHash();
251  }
252  int64_t getLastBlockTime() override {
253  LOCK(::cs_main);
254  if (chainman().ActiveChain().Tip()) {
255  return chainman().ActiveChain().Tip()->GetBlockTime();
256  }
257  // Genesis block's time of current network
258  return chainman().GetParams().GenesisBlock().GetBlockTime();
259  }
260  double getVerificationProgress() override {
261  const CBlockIndex *tip;
262  {
263  LOCK(::cs_main);
264  tip = chainman().ActiveChain().Tip();
265  }
266  return GuessVerificationProgress(chainman().GetParams().TxData(),
267  tip);
268  }
269  bool isInitialBlockDownload() override {
270  return chainman().ActiveChainstate().IsInitialBlockDownload();
271  }
272  bool isLoadingBlocks() override {
273  return chainman().m_blockman.LoadingBlocks();
274  }
275  void setNetworkActive(bool active) override {
276  if (m_context->connman) {
277  m_context->connman->SetNetworkActive(active);
278  }
279  }
280  bool getNetworkActive() override {
281  return m_context->connman && m_context->connman->GetNetworkActive();
282  }
283  CFeeRate getDustRelayFee() override {
284  if (!m_context->mempool) {
285  return CFeeRate{DUST_RELAY_TX_FEE};
286  }
287  return m_context->mempool->m_dust_relay_feerate;
288  }
289  UniValue executeRpc(const Config &config, const std::string &command,
290  const UniValue &params,
291  const std::string &uri) override {
292  JSONRPCRequest req;
293  req.context = m_context;
294  req.params = params;
295  req.strMethod = command;
296  req.URI = uri;
297  return ::tableRPC.execute(config, req);
298  }
299  std::vector<std::string> listRpcCommands() override {
301  }
302  void rpcSetTimerInterfaceIfUnset(RPCTimerInterface *iface) override {
304  }
305  void rpcUnsetTimerInterface(RPCTimerInterface *iface) override {
306  RPCUnsetTimerInterface(iface);
307  }
308  bool getUnspentOutput(const COutPoint &output, Coin &coin) override {
309  LOCK(::cs_main);
310  return chainman().ActiveChainstate().CoinsTip().GetCoin(output,
311  coin);
312  }
313  WalletClient &walletClient() override {
314  return *Assert(m_context->wallet_client);
315  }
316  std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override {
317  return MakeHandler(::uiInterface.InitMessage_connect(fn));
318  }
319  std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) override {
320  return MakeHandler(::uiInterface.ThreadSafeMessageBox_connect(fn));
321  }
322  std::unique_ptr<Handler> handleQuestion(QuestionFn fn) override {
323  return MakeHandler(::uiInterface.ThreadSafeQuestion_connect(fn));
324  }
325  std::unique_ptr<Handler>
326  handleShowProgress(ShowProgressFn fn) override {
327  return MakeHandler(::uiInterface.ShowProgress_connect(fn));
328  }
329  std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(
330  NotifyNumConnectionsChangedFn fn) override {
331  return MakeHandler(
332  ::uiInterface.NotifyNumConnectionsChanged_connect(fn));
333  }
334  std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(
335  NotifyNetworkActiveChangedFn fn) override {
336  return MakeHandler(
337  ::uiInterface.NotifyNetworkActiveChanged_connect(fn));
338  }
339  std::unique_ptr<Handler>
340  handleNotifyAlertChanged(NotifyAlertChangedFn fn) override {
341  return MakeHandler(::uiInterface.NotifyAlertChanged_connect(fn));
342  }
343  std::unique_ptr<Handler>
344  handleBannedListChanged(BannedListChangedFn fn) override {
345  return MakeHandler(::uiInterface.BannedListChanged_connect(fn));
346  }
347  std::unique_ptr<Handler>
348  handleNotifyBlockTip(NotifyBlockTipFn fn) override {
349  return MakeHandler(::uiInterface.NotifyBlockTip_connect(
350  [fn](SynchronizationState sync_state,
351  const CBlockIndex *block) {
352  fn(sync_state,
353  BlockTip{block->nHeight, block->GetBlockTime(),
354  block->GetBlockHash()},
355  GuessVerificationProgress(Params().TxData(), block));
356  }));
357  }
358  std::unique_ptr<Handler>
359  handleNotifyHeaderTip(NotifyHeaderTipFn fn) override {
360  /* verification progress is unused when a header was received */
361  return MakeHandler(::uiInterface.NotifyHeaderTip_connect(
362  [fn](SynchronizationState sync_state, int64_t height,
363  int64_t timestamp, bool presync) {
364  fn(sync_state,
365  BlockTip{int(height), timestamp, BlockHash{}}, presync);
366  }));
367  }
368  NodeContext *context() override { return m_context; }
369  void setContext(NodeContext *context) override { m_context = context; }
370  NodeContext *m_context{nullptr};
371  };
372 
373  bool FillBlock(const CBlockIndex *index, const FoundBlock &block,
374  UniqueLock<RecursiveMutex> &lock, const CChain &active,
375  const BlockManager &blockman) {
376  if (!index) {
377  return false;
378  }
379  if (block.m_hash) {
380  *block.m_hash = index->GetBlockHash();
381  }
382  if (block.m_height) {
383  *block.m_height = index->nHeight;
384  }
385  if (block.m_time) {
386  *block.m_time = index->GetBlockTime();
387  }
388  if (block.m_max_time) {
389  *block.m_max_time = index->GetBlockTimeMax();
390  }
391  if (block.m_mtp_time) {
392  *block.m_mtp_time = index->GetMedianTimePast();
393  }
394  if (block.m_in_active_chain) {
395  *block.m_in_active_chain = active[index->nHeight] == index;
396  }
397  // TODO backport core#25494 with change from core#25717
398  if (block.m_next_block) {
399  FillBlock(active[index->nHeight] == index
400  ? active[index->nHeight + 1]
401  : nullptr,
402  *block.m_next_block, lock, active, blockman);
403  }
404  if (block.m_data) {
405  REVERSE_LOCK(lock);
406  if (!blockman.ReadBlockFromDisk(*block.m_data, *index)) {
407  block.m_data->SetNull();
408  }
409  }
410  return true;
411  }
412 
413  class NotificationsProxy : public CValidationInterface {
414  public:
415  explicit NotificationsProxy(
416  std::shared_ptr<Chain::Notifications> notifications)
417  : m_notifications(std::move(notifications)) {}
418  virtual ~NotificationsProxy() = default;
420  std::shared_ptr<const std::vector<Coin>>,
421  uint64_t mempool_sequence) override {
422  m_notifications->transactionAddedToMempool(tx, mempool_sequence);
423  }
425  MemPoolRemovalReason reason,
426  uint64_t mempool_sequence) override {
427  m_notifications->transactionRemovedFromMempool(tx, reason,
428  mempool_sequence);
429  }
430  void BlockConnected(const std::shared_ptr<const CBlock> &block,
431  const CBlockIndex *index) override {
432  m_notifications->blockConnected(*block, index->nHeight);
433  }
434  void BlockDisconnected(const std::shared_ptr<const CBlock> &block,
435  const CBlockIndex *index) override {
436  m_notifications->blockDisconnected(*block, index->nHeight);
437  }
438  void UpdatedBlockTip(const CBlockIndex *index,
439  const CBlockIndex *fork_index,
440  bool is_ibd) override {
441  m_notifications->updatedBlockTip();
442  }
443  void ChainStateFlushed(const CBlockLocator &locator) override {
444  m_notifications->chainStateFlushed(locator);
445  }
446  std::shared_ptr<Chain::Notifications> m_notifications;
447  };
448 
449  class NotificationsHandlerImpl : public Handler {
450  public:
451  explicit NotificationsHandlerImpl(
452  std::shared_ptr<Chain::Notifications> notifications)
453  : m_proxy(std::make_shared<NotificationsProxy>(
454  std::move(notifications))) {
456  }
457  ~NotificationsHandlerImpl() override { disconnect(); }
458  void disconnect() override {
459  if (m_proxy) {
461  m_proxy.reset();
462  }
463  }
464  std::shared_ptr<NotificationsProxy> m_proxy;
465  };
466 
467  class RpcHandlerImpl : public Handler {
468  public:
469  explicit RpcHandlerImpl(const CRPCCommand &command)
470  : m_command(command), m_wrapped_command(&command) {
471  m_command.actor = [this](const Config &config,
472  const JSONRPCRequest &request,
473  UniValue &result, bool last_handler) {
474  if (!m_wrapped_command) {
475  return false;
476  }
477  try {
478  return m_wrapped_command->actor(config, request, result,
479  last_handler);
480  } catch (const UniValue &e) {
481  // If this is not the last handler and a wallet not found
482  // exception was thrown, return false so the next handler
483  // can try to handle the request. Otherwise, reraise the
484  // exception.
485  if (!last_handler) {
486  const UniValue &code = e["code"];
487  if (code.isNum() &&
488  code.getInt<int>() == RPC_WALLET_NOT_FOUND) {
489  return false;
490  }
491  }
492  throw;
493  }
494  };
496  }
497 
498  void disconnect() final {
499  if (m_wrapped_command) {
500  m_wrapped_command = nullptr;
502  }
503  }
504 
505  ~RpcHandlerImpl() override { disconnect(); }
506 
509  };
510 
511  class ChainImpl : public Chain {
512  private:
513  ChainstateManager &chainman() { return *Assert(m_node.chainman); }
514 
515  public:
516  explicit ChainImpl(NodeContext &node, const CChainParams &params)
517  : m_node(node), m_params(params) {}
518  std::optional<int> getHeight() override {
519  LOCK(::cs_main);
520  const CChain &active = Assert(m_node.chainman)->ActiveChain();
521  int height = active.Height();
522  if (height >= 0) {
523  return height;
524  }
525  return std::nullopt;
526  }
527  BlockHash getBlockHash(int height) override {
528  LOCK(::cs_main);
529  const CChain &active = Assert(m_node.chainman)->ActiveChain();
530  CBlockIndex *block = active[height];
531  assert(block);
532  return block->GetBlockHash();
533  }
534  bool haveBlockOnDisk(int height) override {
535  LOCK(cs_main);
536  const CChain &active = Assert(m_node.chainman)->ActiveChain();
537  CBlockIndex *block = active[height];
538  return block && (block->nStatus.hasData() != 0) && block->nTx > 0;
539  }
540  CBlockLocator getTipLocator() override {
541  LOCK(cs_main);
542  const CChain &active = Assert(m_node.chainman)->ActiveChain();
543  return active.GetLocator();
544  }
545  // TODO: backport core#25036 with changes from core#25717
546  std::optional<int>
547  findLocatorFork(const CBlockLocator &locator) override {
548  LOCK(cs_main);
549  const Chainstate &active =
550  Assert(m_node.chainman)->ActiveChainstate();
551  if (const CBlockIndex *fork =
552  active.FindForkInGlobalIndex(locator)) {
553  return fork->nHeight;
554  }
555  return std::nullopt;
556  }
557  bool findBlock(const BlockHash &hash,
558  const FoundBlock &block) override {
559  WAIT_LOCK(cs_main, lock);
560  const CChain &active = Assert(m_node.chainman)->ActiveChain();
561  return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash),
562  block, lock, active, chainman().m_blockman);
563  }
564  bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height,
565  const FoundBlock &block) override {
566  WAIT_LOCK(cs_main, lock);
567  const CChain &active = Assert(m_node.chainman)->ActiveChain();
568  return FillBlock(active.FindEarliestAtLeast(min_time, min_height),
569  block, lock, active, chainman().m_blockman);
570  }
571  bool findAncestorByHeight(const BlockHash &block_hash,
572  int ancestor_height,
573  const FoundBlock &ancestor_out) override {
574  WAIT_LOCK(cs_main, lock);
575  const CChain &active = Assert(m_node.chainman)->ActiveChain();
576  if (const CBlockIndex *block =
577  m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
578  if (const CBlockIndex *ancestor =
579  block->GetAncestor(ancestor_height)) {
580  return FillBlock(ancestor, ancestor_out, lock, active,
581  chainman().m_blockman);
582  }
583  }
584  return FillBlock(nullptr, ancestor_out, lock, active,
585  chainman().m_blockman);
586  }
587  bool findAncestorByHash(const BlockHash &block_hash,
588  const BlockHash &ancestor_hash,
589  const FoundBlock &ancestor_out) override {
590  WAIT_LOCK(cs_main, lock);
591  const CChain &active = Assert(m_node.chainman)->ActiveChain();
592  const CBlockIndex *block =
593  m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
594  const CBlockIndex *ancestor =
595  m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
596  if (block && ancestor &&
597  block->GetAncestor(ancestor->nHeight) != ancestor) {
598  ancestor = nullptr;
599  }
600  return FillBlock(ancestor, ancestor_out, lock, active,
601  chainman().m_blockman);
602  }
603  bool findCommonAncestor(const BlockHash &block_hash1,
604  const BlockHash &block_hash2,
605  const FoundBlock &ancestor_out,
606  const FoundBlock &block1_out,
607  const FoundBlock &block2_out) override {
608  WAIT_LOCK(cs_main, lock);
609  const CChain &active = Assert(m_node.chainman)->ActiveChain();
610  const CBlockIndex *block1 =
611  m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
612  const CBlockIndex *block2 =
613  m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
614  const CBlockIndex *ancestor =
615  block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
616  // Using & instead of && below to avoid short circuiting and leaving
617  // output uninitialized. Cast bool to int to avoid
618  // -Wbitwise-instead-of-logical compiler warnings.
619  return int{FillBlock(ancestor, ancestor_out, lock, active,
620  chainman().m_blockman)} &
621  int{FillBlock(block1, block1_out, lock, active,
622  chainman().m_blockman)} &
623  int{FillBlock(block2, block2_out, lock, active,
624  chainman().m_blockman)};
625  }
626  void findCoins(std::map<COutPoint, Coin> &coins) override {
627  return FindCoins(m_node, coins);
628  }
629  double guessVerificationProgress(const BlockHash &block_hash) override {
630  LOCK(cs_main);
632  chainman().GetParams().TxData(),
633  chainman().m_blockman.LookupBlockIndex(block_hash));
634  }
635  bool hasBlocks(const BlockHash &block_hash, int min_height,
636  std::optional<int> max_height) override {
637  // hasBlocks returns true if all ancestors of block_hash in
638  // specified range have block data (are not pruned), false if any
639  // ancestors in specified range are missing data.
640  //
641  // For simplicity and robustness, min_height and max_height are only
642  // used to limit the range, and passing min_height that's too low or
643  // max_height that's too high will not crash or change the result.
644  LOCK(::cs_main);
645  if (const CBlockIndex *block =
646  chainman().m_blockman.LookupBlockIndex(block_hash)) {
647  if (max_height && block->nHeight >= *max_height) {
648  block = block->GetAncestor(*max_height);
649  }
650  for (; block->nStatus.hasData(); block = block->pprev) {
651  // Check pprev to not segfault if min_height is too low
652  if (block->nHeight <= min_height || !block->pprev) {
653  return true;
654  }
655  }
656  }
657  return false;
658  }
659  bool broadcastTransaction(const Config &config,
660  const CTransactionRef &tx,
661  const Amount &max_tx_fee, bool relay,
662  std::string &err_string) override {
663  const TransactionError err =
664  BroadcastTransaction(m_node, tx, err_string, max_tx_fee, relay,
665  /*wait_callback=*/false);
666  // Chain clients only care about failures to accept the tx to the
667  // mempool. Disregard non-mempool related failures. Note: this will
668  // need to be updated if BroadcastTransactions() is updated to
669  // return other non-mempool failures that Chain clients do not need
670  // to know about.
671  return err == TransactionError::OK;
672  }
673  CFeeRate estimateFee() const override {
674  if (!m_node.mempool) {
675  return {};
676  }
677  return m_node.mempool->estimateFee();
678  }
679  CFeeRate relayMinFee() override {
680  if (!m_node.mempool) {
682  }
683  return m_node.mempool->m_min_relay_feerate;
684  }
685  CFeeRate relayDustFee() override {
686  if (!m_node.mempool) {
687  return CFeeRate{DUST_RELAY_TX_FEE};
688  }
689  return m_node.mempool->m_dust_relay_feerate;
690  }
691  bool havePruned() override {
692  LOCK(cs_main);
693  return m_node.chainman->m_blockman.m_have_pruned;
694  }
695  bool isReadyToBroadcast() override {
696  return !chainman().m_blockman.LoadingBlocks() &&
698  }
699  bool isInitialBlockDownload() override {
700  return chainman().ActiveChainstate().IsInitialBlockDownload();
701  }
702  bool shutdownRequested() override { return ShutdownRequested(); }
703  void initMessage(const std::string &message) override {
704  ::uiInterface.InitMessage(message);
705  }
706  void initWarning(const bilingual_str &message) override {
707  InitWarning(message);
708  }
709  void initError(const bilingual_str &message) override {
710  InitError(message);
711  }
712  void showProgress(const std::string &title, int progress,
713  bool resume_possible) override {
714  ::uiInterface.ShowProgress(title, progress, resume_possible);
715  }
716  std::unique_ptr<Handler> handleNotifications(
717  std::shared_ptr<Notifications> notifications) override {
718  return std::make_unique<NotificationsHandlerImpl>(
719  std::move(notifications));
720  }
721  void
722  waitForNotificationsIfTipChanged(const BlockHash &old_tip) override {
723  if (!old_tip.IsNull()) {
724  LOCK(::cs_main);
725  const CChain &active = Assert(m_node.chainman)->ActiveChain();
726  if (old_tip == active.Tip()->GetBlockHash()) {
727  return;
728  }
729  }
731  }
732 
733  std::unique_ptr<Handler>
734  handleRpc(const CRPCCommand &command) override {
735  return std::make_unique<RpcHandlerImpl>(command);
736  }
737  bool rpcEnableDeprecated(const std::string &method) override {
738  return IsDeprecatedRPCEnabled(gArgs, method);
739  }
740  void rpcRunLater(const std::string &name, std::function<void()> fn,
741  int64_t seconds) override {
742  RPCRunLater(name, std::move(fn), seconds);
743  }
744  int rpcSerializationFlags() override { return RPCSerializationFlags(); }
745  util::SettingsValue getSetting(const std::string &name) override {
746  return gArgs.GetSetting(name);
747  }
748  std::vector<util::SettingsValue>
749  getSettingsList(const std::string &name) override {
750  return gArgs.GetSettingsList(name);
751  }
752  util::SettingsValue getRwSetting(const std::string &name) override {
753  util::SettingsValue result;
754  gArgs.LockSettings([&](const util::Settings &settings) {
755  if (const util::SettingsValue *value =
756  util::FindKey(settings.rw_settings, name)) {
757  result = *value;
758  }
759  });
760  return result;
761  }
762  bool updateRwSetting(const std::string &name,
763  const util::SettingsValue &value,
764  bool write) override {
765  gArgs.LockSettings([&](util::Settings &settings) {
766  if (value.isNull()) {
767  settings.rw_settings.erase(name);
768  } else {
769  settings.rw_settings[name] = value;
770  }
771  });
772  return !write || gArgs.WriteSettingsFile();
773  }
774  void requestMempoolTransactions(Notifications &notifications) override {
775  if (!m_node.mempool) {
776  return;
777  }
778  LOCK2(::cs_main, m_node.mempool->cs);
779  for (const CTxMemPoolEntryRef &entry : m_node.mempool->mapTx) {
780  notifications.transactionAddedToMempool(entry->GetSharedTx(),
781  /*mempool_sequence=*/0);
782  }
783  }
784  const CChainParams &params() const override { return m_params; }
785  NodeContext &m_node;
787  };
788 } // namespace
789 } // namespace node
790 
791 namespace interfaces {
792 std::unique_ptr<Node> MakeNode(node::NodeContext *context) {
793  return std::make_unique<node::NodeImpl>(context);
794 }
795 std::unique_ptr<Chain> MakeChain(node::NodeContext &node,
796  const CChainParams &params) {
797  return std::make_unique<node::ChainImpl>(node, params);
798 }
799 } // namespace interfaces
ArgsManager gArgs
Definition: args.cpp:38
int flags
Definition: bitcoin-tx.cpp:543
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
Definition: chain.cpp:112
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:19
#define Assert(val)
Identity function.
Definition: check.h:84
util::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:483
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: args.h:398
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr, bool backup=false) const
Write settings file or backup settings file.
Definition: args.cpp:457
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: args.cpp:837
util::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
Definition: args.cpp:828
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: args.cpp:556
void SetNull()
Definition: block.h:80
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:25
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:32
int64_t GetBlockTime() const
Definition: blockindex.h:180
int64_t GetMedianTimePast() const
Definition: blockindex.h:192
int64_t GetBlockTimeMax() const
Definition: blockindex.h:182
unsigned int nTx
Number of transactions in this block.
Definition: blockindex.h:60
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: blockindex.cpp:78
BlockHash GetBlockHash() const
Definition: blockindex.h:146
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:38
An in-memory indexed chain of blocks.
Definition: chain.h:134
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:150
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:62
int Height() const
Return the maximal height in the chain.
Definition: chain.h:186
CBlockLocator GetLocator() const
Return a CBlockLocator that refers to the tip of this chain.
Definition: chain.cpp:45
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:80
NumConnections
Definition: net.h:847
Fee rate in satoshis per kilobyte: Amount / kB.
Definition: feerate.h:21
Network address.
Definition: netaddress.h:121
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:20
std::string name
Definition: server.h:176
Actor actor
Definition: server.h:177
bool removeCommand(const std::string &name, const CRPCCommand *pcmd)
Definition: server.cpp:335
std::vector< std::string > listCommands() const
Returns a list of registered commands.
Definition: server.cpp:623
UniValue execute(const Config &config, const JSONRPCRequest &request) const
Execute a method.
Definition: server.cpp:582
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:327
Implement this to subscribe to events generated in validation.
virtual void ChainStateFlushed(const CBlockLocator &locator)
Notifies listeners of the new active block chain on-disk.
virtual void TransactionAddedToMempool(const CTransactionRef &tx, std::shared_ptr< const std::vector< Coin >> spent_coins, uint64_t mempool_sequence)
Notifies listeners of a transaction having been added to mempool.
virtual void TransactionRemovedFromMempool(const CTransactionRef &tx, MemPoolRemovalReason reason, uint64_t mempool_sequence)
Notifies listeners of a transaction leaving mempool.
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload)
Notifies listeners when the block chain tip advances.
virtual void BlockConnected(const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex)
Notifies listeners of a block being connected.
virtual void BlockDisconnected(const std::shared_ptr< const CBlock > &block, const CBlockIndex *pindex)
Notifies listeners of a block being disconnected.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:630
const CBlockIndex * FindForkInGlobalIndex(const CBlockLocator &locator) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Find the last common block of this chain and a locator.
Definition: validation.cpp:122
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:1153
A UTXO entry.
Definition: coins.h:28
Definition: config.h:19
UniValue params
Definition: request.h:34
std::string strMethod
Definition: request.h:33
std::string URI
Definition: request.h:36
std::any context
Definition: request.h:39
Definition: rcu.h:85
Class for registering and managing all RPC calls.
Definition: server.h:40
RPC timer "driver".
Definition: server.h:100
bool isNull() const
Definition: univalue.h:104
Int getInt() const
Definition: univalue.h:157
bool isNum() const
Definition: univalue.h:109
Wrapper around std::unique_lock style lock for Mutex.
Definition: sync.h:168
bool IsNull() const
Definition: uint256.h:32
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:123
virtual void rpcRunLater(const std::string &name, std::function< void()> fn, int64_t seconds)=0
Run function after given number of seconds.
virtual CBlockLocator getTipLocator()=0
Get locator for the current chain tip.
virtual bool findAncestorByHash(const BlockHash &block_hash, const BlockHash &ancestor_hash, const FoundBlock &ancestor_out={})=0
Return whether block descends from a specified ancestor, and optionally return ancestor information.
virtual bool isInitialBlockDownload()=0
Check if in IBD.
virtual BlockHash getBlockHash(int height)=0
Get block hash. Height must be valid or this function will abort.
virtual bool rpcEnableDeprecated(const std::string &method)=0
Check if deprecated RPC is enabled.
virtual int rpcSerializationFlags()=0
Current RPC serialization flags.
virtual bool findBlock(const BlockHash &hash, const FoundBlock &block={})=0
Return whether node has the block and optionally return block metadata or contents.
virtual bool findCommonAncestor(const BlockHash &block_hash1, const BlockHash &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 bool updateRwSetting(const std::string &name, const util::SettingsValue &value, bool write=true)=0
Write a setting to <datadir>/settings.json.
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,...
virtual bool broadcastTransaction(const Config &config, const CTransactionRef &tx, const Amount &max_tx_fee, bool relay, std::string &err_string)=0
Transaction is added to memory pool, if the transaction fee is below the amount specified by max_tx_f...
virtual util::SettingsValue getRwSetting(const std::string &name)=0
Return <datadir>/settings.json setting value.
virtual double guessVerificationProgress(const BlockHash &block_hash)=0
Estimate fraction of total transactions verified if blocks up to the specified block hash are verifie...
virtual void showProgress(const std::string &title, int progress, bool resume_possible)=0
Send progress indicator.
virtual bool havePruned()=0
Check if any block has been pruned.
virtual void findCoins(std::map< COutPoint, Coin > &coins)=0
Look up unspent output information.
virtual bool shutdownRequested()=0
Check if shutdown requested.
virtual std::optional< int > getHeight()=0
Get current chain height, not including genesis block (returns 0 if chain only contains genesis block...
virtual bool isReadyToBroadcast()=0
Check if the node is ready to broadcast transactions.
virtual bool hasBlocks(const BlockHash &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.
virtual util::SettingsValue getSetting(const std::string &arg)=0
Get settings value.
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...
virtual bool findAncestorByHeight(const BlockHash &block_hash, int ancestor_height, const FoundBlock &ancestor_out={})=0
Find ancestor of block at specified height and optionally return ancestor information.
virtual void initMessage(const std::string &message)=0
Send init message.
virtual std::unique_ptr< Handler > handleNotifications(std::shared_ptr< Notifications > notifications)=0
Register handler for notifications.
virtual bool haveBlockOnDisk(int height)=0
Check that the block is available on disk (i.e.
virtual std::unique_ptr< Handler > handleRpc(const CRPCCommand &command)=0
Register handler for RPC.
virtual CFeeRate relayDustFee()=0
Relay dust fee setting (-dustrelayfee), reflecting lowest rate it's economical to spend.
virtual CFeeRate estimateFee() const =0
Estimate fee.
virtual void requestMempoolTransactions(Notifications &notifications)=0
Synchronously send transactionAddedToMempool notifications about all current mempool transactions to ...
virtual void initError(const bilingual_str &message)=0
Send init error.
virtual void waitForNotificationsIfTipChanged(const BlockHash &old_tip)=0
Wait for pending notifications to be processed unless block hash points to the current chain tip.
virtual void initWarning(const bilingual_str &message)=0
Send init warning.
virtual CFeeRate relayMinFee()=0
Relay current minimum fee (from -minrelaytxfee settings).
virtual const CChainParams & params() const =0
This Chain's parameters.
virtual std::vector< util::SettingsValue > getSettingsList(const std::string &arg)=0
Get list of settings values.
Helper for findBlock to selectively return pieces of block data.
Definition: chain.h:48
CBlock * m_data
Definition: chain.h:95
const FoundBlock * m_next_block
Definition: chain.h:94
BlockHash * m_hash
Definition: chain.h:88
int64_t * m_max_time
Definition: chain.h:91
int64_t * m_time
Definition: chain.h:90
bool * m_in_active_chain
Definition: chain.h:93
int64_t * m_mtp_time
Definition: chain.h:92
Generic interface for managing an event handler or callback function registered with another interfac...
Definition: handler.h:22
virtual void disconnect()=0
Disconnect the handler.
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:58
Wallet chain client that in addition to having chain client methods for starting up,...
Definition: wallet.h:304
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:7
TransactionError
Definition: error.h:22
void Interrupt(NodeContext &node)
Interrupt threads.
Definition: init.cpp:197
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:1625
bool AppInitLockDataDirectory()
Lock bitcoin data directory.
Definition: init.cpp:2022
void Shutdown(NodeContext &node)
Definition: init.cpp:221
bool AppInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, NodeContext &node, interfaces::BlockAndHeaderTipInfo *tip_info)
Bitcoin main initialization.
Definition: init.cpp:2044
bool AppInitBasicSetup(const ArgsManager &args)
Initialize bitcoin: Basic context setup.
Definition: init.cpp:1652
bool AppInitSanityChecks()
Initialization sanity checks: ecc init, sanity checks, dir lock.
Definition: init.cpp:2004
bool AppInitInterfaces(NodeContext &node)
Initialize node and wallet interface pointers.
Definition: init.cpp:2034
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:1491
bool AppInitParameterInteraction(Config &config, const ArgsManager &args)
Initialization: parameter interaction.
Definition: init.cpp:1699
void StartMapPort(bool use_upnp, bool use_natpmp)
Definition: mapport.cpp:358
std::unique_ptr< Handler > MakeHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
Definition: handler.cpp:48
std::unique_ptr< Node > MakeNode(node::NodeContext *context)
Return implementation of Node interface.
Definition: interfaces.cpp:792
std::unique_ptr< Chain > MakeChain(node::NodeContext &node, const CChainParams &params)
Return implementation of Chain interface.
Definition: interfaces.cpp:795
Definition: init.h:28
TransactionError BroadcastTransaction(const NodeContext &node, const CTransactionRef tx, std::string &err_string, const Amount max_tx_fee, bool relay, bool wait_callback)
Submit a transaction to the mempool and (optionally) relay it to all P2P peers.
Definition: transaction.cpp:37
void FindCoins(const NodeContext &node, std::map< COutPoint, Coin > &coins)
Look up unspent output information.
Definition: coin.cpp:12
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:257
auto FindKey(Map &&map, Key &&key) -> decltype(&map.at(key))
Map lookup helper.
Definition: settings.h:115
std::map< CSubNet, CBanEntry > banmap_t
Definition: net_types.h:13
Network
A network type.
Definition: netaddress.h:44
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:720
NodeContext & m_node
Definition: interfaces.cpp:785
NodeContext * m_context
Definition: interfaces.cpp:370
std::shared_ptr< Chain::Notifications > m_notifications
Definition: interfaces.cpp:446
CRPCCommand m_command
Definition: interfaces.cpp:507
const CChainParams & m_params
Definition: interfaces.cpp:786
const CRPCCommand * m_wrapped_command
Definition: interfaces.cpp:508
std::shared_ptr< NotificationsProxy > m_proxy
Definition: interfaces.cpp:464
int64_t NodeId
Definition: nodeid.h:10
static constexpr Amount DUST_RELAY_TX_FEE(1000 *SATOSHI)
Min feerate for defining dust.
static constexpr Amount DEFAULT_MIN_RELAY_TX_FEE_PER_KB(1000 *SATOSHI)
Default for -minrelaytxfee, minimum relay fee for transactions.
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:315
const char * name
Definition: rest.cpp:47
@ RPC_WALLET_NOT_FOUND
Invalid wallet specified.
Definition: protocol.h:109
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
Set the factory function for timer, but only, if unset.
Definition: server.cpp:648
bool IsDeprecatedRPCEnabled(const ArgsManager &args, const std::string &method)
Definition: server.cpp:407
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
Unset factory function for timers.
Definition: server.cpp:658
void RPCRunLater(const std::string &name, std::function< void()> func, int64_t nSeconds)
Run func nSeconds from now.
Definition: server.cpp:664
void StopRPC()
Definition: server.cpp:365
int RPCSerializationFlags()
Retrieves any serialization flags requested in command line argument.
Definition: server.cpp:679
void InterruptRPC()
Definition: server.cpp:354
CRPCTable tableRPC
Definition: server.cpp:683
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
Definition: shutdown.cpp:85
void StartShutdown()
Request shutdown of the application.
Definition: shutdown.cpp:55
Definition: amount.h:19
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition: block.h:105
Bilingual messages:
Definition: translation.h:17
Block and header tip information.
Definition: node.h:49
Block tip (could be a header or not, depends on the subscribed signal).
Definition: node.h:269
NodeContext struct containing references to chain state and connection state.
Definition: context.h:43
Stored settings.
Definition: settings.h:31
std::map< std::string, SettingsValue > rw_settings
Map of setting name to read-write file setting value.
Definition: settings.h:37
std::map< std::string, std::vector< SettingsValue > > command_line_options
Map of setting name to list of command line values.
Definition: settings.h:35
#define WAIT_LOCK(cs, name)
Definition: sync.h:317
#define LOCK2(cs1, cs2)
Definition: sync.h:309
#define LOCK(cs)
Definition: sync.h:306
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:357
#define TRY_LOCK(cs, name)
Definition: sync.h:314
#define REVERSE_LOCK(g)
Definition: sync.h:265
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
Definition: txmempool.h:148
CClientUIInterface uiInterface
void InitWarning(const bilingual_str &str)
Show warning message.
bool InitError(const bilingual_str &str)
Show error message.
double GuessVerificationProgress(const ChainTxData &data, const CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index require cs_main if pindex h...
assert(!tx.IsCoinBase())
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition: validation.h:113
void UnregisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Unregister subscriber.
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
void RegisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Register subscriber.
bilingual_str GetWarnings(bool verbose)
Format a string that describes several potential problems detected by the core.
Definition: warnings.cpp:41