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 <config.h>
10 #include <init.h>
11 #include <interfaces/chain.h>
12 #include <interfaces/handler.h>
13 #include <interfaces/node.h>
14 #include <interfaces/wallet.h>
15 #include <mapport.h>
16 #include <net.h>
17 #include <net_processing.h>
18 #include <netaddress.h>
19 #include <netbase.h>
20 #include <node/blockstorage.h>
21 #include <node/coin.h>
22 #include <node/context.h>
23 #include <node/transaction.h>
24 #include <node/ui_interface.h>
25 #include <policy/settings.h>
26 #include <primitives/block.h>
27 #include <primitives/transaction.h>
28 #include <rpc/protocol.h>
29 #include <rpc/server.h>
30 #include <shutdown.h>
31 #include <sync.h>
32 #include <timedata.h>
33 #include <txmempool.h>
34 #include <uint256.h>
35 #include <util/check.h>
36 #include <util/system.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  void mapPort(bool use_upnp, bool use_natpmp) override {
104  StartMapPort(use_upnp, use_natpmp);
105  }
106  bool getProxy(Network net, proxyType &proxy_info) override {
107  return GetProxy(net, proxy_info);
108  }
109  size_t getNodeCount(CConnman::NumConnections flags) override {
110  return m_context->connman ? m_context->connman->GetNodeCount(flags)
111  : 0;
112  }
113  bool getNodesStats(NodesStats &stats) override {
114  stats.clear();
115 
116  if (m_context->connman) {
117  std::vector<CNodeStats> stats_temp;
118  m_context->connman->GetNodeStats(stats_temp);
119 
120  stats.reserve(stats_temp.size());
121  for (auto &node_stats_temp : stats_temp) {
122  stats.emplace_back(std::move(node_stats_temp), false,
123  CNodeStateStats());
124  }
125 
126  // Try to retrieve the CNodeStateStats for each node.
127  if (m_context->peerman) {
128  TRY_LOCK(::cs_main, lockMain);
129  if (lockMain) {
130  for (auto &node_stats : stats) {
131  std::get<1>(node_stats) =
132  m_context->peerman->GetNodeStateStats(
133  std::get<0>(node_stats).nodeid,
134  std::get<2>(node_stats));
135  }
136  }
137  }
138  return true;
139  }
140  return false;
141  }
142  bool getBanned(banmap_t &banmap) override {
143  if (m_context->banman) {
144  m_context->banman->GetBanned(banmap);
145  return true;
146  }
147  return false;
148  }
149  bool ban(const CNetAddr &net_addr, int64_t ban_time_offset) override {
150  if (m_context->banman) {
151  m_context->banman->Ban(net_addr, ban_time_offset);
152  return true;
153  }
154  return false;
155  }
156  bool unban(const CSubNet &ip) override {
157  if (m_context->banman) {
158  m_context->banman->Unban(ip);
159  return true;
160  }
161  return false;
162  }
163  bool disconnectByAddress(const CNetAddr &net_addr) override {
164  if (m_context->connman) {
165  return m_context->connman->DisconnectNode(net_addr);
166  }
167  return false;
168  }
169  bool disconnectById(NodeId id) override {
170  if (m_context->connman) {
171  return m_context->connman->DisconnectNode(id);
172  }
173  return false;
174  }
175  int64_t getTotalBytesRecv() override {
176  return m_context->connman ? m_context->connman->GetTotalBytesRecv()
177  : 0;
178  }
179  int64_t getTotalBytesSent() override {
180  return m_context->connman ? m_context->connman->GetTotalBytesSent()
181  : 0;
182  }
183  size_t getMempoolSize() override {
184  return m_context->mempool ? m_context->mempool->size() : 0;
185  }
186  size_t getMempoolDynamicUsage() override {
187  return m_context->mempool ? m_context->mempool->DynamicMemoryUsage()
188  : 0;
189  }
190  bool getHeaderTip(int &height, int64_t &block_time) override {
191  LOCK(::cs_main);
192  auto best_header = chainman().m_best_header;
193  if (best_header) {
194  height = best_header->nHeight;
195  block_time = best_header->GetBlockTime();
196  return true;
197  }
198  return false;
199  }
200  int getNumBlocks() override {
201  LOCK(::cs_main);
202  return chainman().ActiveChain().Height();
203  }
204  BlockHash getBestBlockHash() override {
205  const CBlockIndex *tip =
206  WITH_LOCK(::cs_main, return chainman().ActiveTip());
207  return tip ? tip->GetBlockHash()
208  : Params().GenesisBlock().GetHash();
209  }
210  int64_t getLastBlockTime() override {
211  LOCK(::cs_main);
212  if (chainman().ActiveChain().Tip()) {
213  return chainman().ActiveChain().Tip()->GetBlockTime();
214  }
215  // Genesis block's time of current network
216  return Params().GenesisBlock().GetBlockTime();
217  }
218  double getVerificationProgress() override {
219  const CBlockIndex *tip;
220  {
221  LOCK(::cs_main);
222  tip = chainman().ActiveChain().Tip();
223  }
224  return GuessVerificationProgress(Params().TxData(), tip);
225  }
226  bool isInitialBlockDownload() override {
227  return chainman().ActiveChainstate().IsInitialBlockDownload();
228  }
229  bool getReindex() override { return node::fReindex; }
230  bool getImporting() override { return node::fImporting; }
231  void setNetworkActive(bool active) override {
232  if (m_context->connman) {
233  m_context->connman->SetNetworkActive(active);
234  }
235  }
236  bool getNetworkActive() override {
237  return m_context->connman && m_context->connman->GetNetworkActive();
238  }
239  CFeeRate getDustRelayFee() override { return ::dustRelayFee; }
240  UniValue executeRpc(const Config &config, const std::string &command,
241  const UniValue &params,
242  const std::string &uri) override {
243  JSONRPCRequest req;
244  req.context = m_context;
245  req.params = params;
246  req.strMethod = command;
247  req.URI = uri;
248  return ::tableRPC.execute(config, req);
249  }
250  std::vector<std::string> listRpcCommands() override {
252  }
253  void rpcSetTimerInterfaceIfUnset(RPCTimerInterface *iface) override {
255  }
256  void rpcUnsetTimerInterface(RPCTimerInterface *iface) override {
257  RPCUnsetTimerInterface(iface);
258  }
259  bool getUnspentOutput(const COutPoint &output, Coin &coin) override {
260  LOCK(::cs_main);
261  return chainman().ActiveChainstate().CoinsTip().GetCoin(output,
262  coin);
263  }
264  WalletClient &walletClient() override {
265  return *Assert(m_context->wallet_client);
266  }
267  std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override {
268  return MakeHandler(::uiInterface.InitMessage_connect(fn));
269  }
270  std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) override {
271  return MakeHandler(::uiInterface.ThreadSafeMessageBox_connect(fn));
272  }
273  std::unique_ptr<Handler> handleQuestion(QuestionFn fn) override {
274  return MakeHandler(::uiInterface.ThreadSafeQuestion_connect(fn));
275  }
276  std::unique_ptr<Handler>
277  handleShowProgress(ShowProgressFn fn) override {
278  return MakeHandler(::uiInterface.ShowProgress_connect(fn));
279  }
280  std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(
281  NotifyNumConnectionsChangedFn fn) override {
282  return MakeHandler(
283  ::uiInterface.NotifyNumConnectionsChanged_connect(fn));
284  }
285  std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(
286  NotifyNetworkActiveChangedFn fn) override {
287  return MakeHandler(
288  ::uiInterface.NotifyNetworkActiveChanged_connect(fn));
289  }
290  std::unique_ptr<Handler>
291  handleNotifyAlertChanged(NotifyAlertChangedFn fn) override {
292  return MakeHandler(::uiInterface.NotifyAlertChanged_connect(fn));
293  }
294  std::unique_ptr<Handler>
295  handleBannedListChanged(BannedListChangedFn fn) override {
296  return MakeHandler(::uiInterface.BannedListChanged_connect(fn));
297  }
298  std::unique_ptr<Handler>
299  handleNotifyBlockTip(NotifyBlockTipFn fn) override {
300  return MakeHandler(::uiInterface.NotifyBlockTip_connect(
301  [fn](SynchronizationState sync_state,
302  const CBlockIndex *block) {
303  fn(sync_state,
304  BlockTip{block->nHeight, block->GetBlockTime(),
305  block->GetBlockHash()},
306  GuessVerificationProgress(Params().TxData(), block));
307  }));
308  }
309  std::unique_ptr<Handler>
310  handleNotifyHeaderTip(NotifyHeaderTipFn fn) override {
311  /* verification progress is unused when a header was received */
312  return MakeHandler(::uiInterface.NotifyHeaderTip_connect(
313  [fn](SynchronizationState sync_state,
314  const CBlockIndex *block) {
315  fn(sync_state,
316  BlockTip{block->nHeight, block->GetBlockTime(),
317  block->GetBlockHash()},
318  0);
319  }));
320  }
321  NodeContext *context() override { return m_context; }
322  void setContext(NodeContext *context) override { m_context = context; }
323  NodeContext *m_context{nullptr};
324  };
325 
326  bool FillBlock(const CBlockIndex *index, const FoundBlock &block,
327  UniqueLock<RecursiveMutex> &lock, const CChain &active) {
328  if (!index) {
329  return false;
330  }
331  if (block.m_hash) {
332  *block.m_hash = index->GetBlockHash();
333  }
334  if (block.m_height) {
335  *block.m_height = index->nHeight;
336  }
337  if (block.m_time) {
338  *block.m_time = index->GetBlockTime();
339  }
340  if (block.m_max_time) {
341  *block.m_max_time = index->GetBlockTimeMax();
342  }
343  if (block.m_mtp_time) {
344  *block.m_mtp_time = index->GetMedianTimePast();
345  }
346  if (block.m_in_active_chain) {
347  *block.m_in_active_chain = active[index->nHeight] == index;
348  }
349  if (block.m_next_block) {
350  FillBlock(active[index->nHeight] == index
351  ? active[index->nHeight + 1]
352  : nullptr,
353  *block.m_next_block, lock, active);
354  }
355  if (block.m_data) {
356  REVERSE_LOCK(lock);
357  if (!ReadBlockFromDisk(*block.m_data, index,
358  Params().GetConsensus())) {
359  block.m_data->SetNull();
360  }
361  }
362  return true;
363  }
364 
365  class NotificationsProxy : public CValidationInterface {
366  public:
367  explicit NotificationsProxy(
368  std::shared_ptr<Chain::Notifications> notifications)
369  : m_notifications(std::move(notifications)) {}
370  virtual ~NotificationsProxy() = default;
372  uint64_t mempool_sequence) override {
373  m_notifications->transactionAddedToMempool(tx, mempool_sequence);
374  }
376  MemPoolRemovalReason reason,
377  uint64_t mempool_sequence) override {
378  m_notifications->transactionRemovedFromMempool(tx, reason,
379  mempool_sequence);
380  }
381  void BlockConnected(const std::shared_ptr<const CBlock> &block,
382  const CBlockIndex *index) override {
383  m_notifications->blockConnected(*block, index->nHeight);
384  }
385  void BlockDisconnected(const std::shared_ptr<const CBlock> &block,
386  const CBlockIndex *index) override {
387  m_notifications->blockDisconnected(*block, index->nHeight);
388  }
389  void UpdatedBlockTip(const CBlockIndex *index,
390  const CBlockIndex *fork_index,
391  bool is_ibd) override {
392  m_notifications->updatedBlockTip();
393  }
394  void ChainStateFlushed(const CBlockLocator &locator) override {
395  m_notifications->chainStateFlushed(locator);
396  }
397  std::shared_ptr<Chain::Notifications> m_notifications;
398  };
399 
400  class NotificationsHandlerImpl : public Handler {
401  public:
402  explicit NotificationsHandlerImpl(
403  std::shared_ptr<Chain::Notifications> notifications)
404  : m_proxy(std::make_shared<NotificationsProxy>(
405  std::move(notifications))) {
407  }
408  ~NotificationsHandlerImpl() override { disconnect(); }
409  void disconnect() override {
410  if (m_proxy) {
412  m_proxy.reset();
413  }
414  }
415  std::shared_ptr<NotificationsProxy> m_proxy;
416  };
417 
418  class RpcHandlerImpl : public Handler {
419  public:
420  explicit RpcHandlerImpl(const CRPCCommand &command)
421  : m_command(command), m_wrapped_command(&command) {
422  m_command.actor = [this](const Config &config,
423  const JSONRPCRequest &request,
424  UniValue &result, bool last_handler) {
425  if (!m_wrapped_command) {
426  return false;
427  }
428  try {
429  return m_wrapped_command->actor(config, request, result,
430  last_handler);
431  } catch (const UniValue &e) {
432  // If this is not the last handler and a wallet not found
433  // exception was thrown, return false so the next handler
434  // can try to handle the request. Otherwise, reraise the
435  // exception.
436  if (!last_handler) {
437  const UniValue &code = e["code"];
438  if (code.isNum() &&
439  code.get_int() == RPC_WALLET_NOT_FOUND) {
440  return false;
441  }
442  }
443  throw;
444  }
445  };
447  }
448 
449  void disconnect() final {
450  if (m_wrapped_command) {
451  m_wrapped_command = nullptr;
453  }
454  }
455 
456  ~RpcHandlerImpl() override { disconnect(); }
457 
460  };
461 
462  class ChainImpl : public Chain {
463  private:
464  ChainstateManager &chainman() { return *Assert(m_node.chainman); }
465 
466  public:
467  explicit ChainImpl(NodeContext &node, const CChainParams &params)
468  : m_node(node), m_params(params) {}
469  std::optional<int> getHeight() override {
470  LOCK(::cs_main);
471  const CChain &active = Assert(m_node.chainman)->ActiveChain();
472  int height = active.Height();
473  if (height >= 0) {
474  return height;
475  }
476  return std::nullopt;
477  }
478  BlockHash getBlockHash(int height) override {
479  LOCK(::cs_main);
480  const CChain &active = Assert(m_node.chainman)->ActiveChain();
481  CBlockIndex *block = active[height];
482  assert(block);
483  return block->GetBlockHash();
484  }
485  bool haveBlockOnDisk(int height) override {
486  LOCK(cs_main);
487  const CChain &active = Assert(m_node.chainman)->ActiveChain();
488  CBlockIndex *block = active[height];
489  return block && (block->nStatus.hasData() != 0) && block->nTx > 0;
490  }
491  CBlockLocator getTipLocator() override {
492  LOCK(cs_main);
493  const CChain &active = Assert(m_node.chainman)->ActiveChain();
494  return active.GetLocator();
495  }
496  std::optional<int>
497  findLocatorFork(const CBlockLocator &locator) override {
498  LOCK(cs_main);
499  const Chainstate &active =
500  Assert(m_node.chainman)->ActiveChainstate();
501  if (const CBlockIndex *fork =
502  active.FindForkInGlobalIndex(locator)) {
503  return fork->nHeight;
504  }
505  return std::nullopt;
506  }
507  bool findBlock(const BlockHash &hash,
508  const FoundBlock &block) override {
509  WAIT_LOCK(cs_main, lock);
510  const CChain &active = Assert(m_node.chainman)->ActiveChain();
511  return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash),
512  block, lock, active);
513  }
514  bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height,
515  const FoundBlock &block) override {
516  WAIT_LOCK(cs_main, lock);
517  const CChain &active = Assert(m_node.chainman)->ActiveChain();
518  return FillBlock(active.FindEarliestAtLeast(min_time, min_height),
519  block, lock, active);
520  }
521  bool findAncestorByHeight(const BlockHash &block_hash,
522  int ancestor_height,
523  const FoundBlock &ancestor_out) override {
524  WAIT_LOCK(cs_main, lock);
525  const CChain &active = Assert(m_node.chainman)->ActiveChain();
526  if (const CBlockIndex *block =
527  m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
528  if (const CBlockIndex *ancestor =
529  block->GetAncestor(ancestor_height)) {
530  return FillBlock(ancestor, ancestor_out, lock, active);
531  }
532  }
533  return FillBlock(nullptr, ancestor_out, lock, active);
534  }
535  bool findAncestorByHash(const BlockHash &block_hash,
536  const BlockHash &ancestor_hash,
537  const FoundBlock &ancestor_out) override {
538  WAIT_LOCK(cs_main, lock);
539  const CChain &active = Assert(m_node.chainman)->ActiveChain();
540  const CBlockIndex *block =
541  m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
542  const CBlockIndex *ancestor =
543  m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
544  if (block && ancestor &&
545  block->GetAncestor(ancestor->nHeight) != ancestor) {
546  ancestor = nullptr;
547  }
548  return FillBlock(ancestor, ancestor_out, lock, active);
549  }
550  bool findCommonAncestor(const BlockHash &block_hash1,
551  const BlockHash &block_hash2,
552  const FoundBlock &ancestor_out,
553  const FoundBlock &block1_out,
554  const FoundBlock &block2_out) override {
555  WAIT_LOCK(cs_main, lock);
556  const CChain &active = Assert(m_node.chainman)->ActiveChain();
557  const CBlockIndex *block1 =
558  m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
559  const CBlockIndex *block2 =
560  m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
561  const CBlockIndex *ancestor =
562  block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
563  // Using & instead of && below to avoid short circuiting and leaving
564  // output uninitialized. Cast bool to int to avoid
565  // -Wbitwise-instead-of-logical compiler warnings.
566  return int{FillBlock(ancestor, ancestor_out, lock, active)} &
567  int{FillBlock(block1, block1_out, lock, active)} &
568  int{FillBlock(block2, block2_out, lock, active)};
569  }
570  void findCoins(std::map<COutPoint, Coin> &coins) override {
571  return FindCoins(m_node, coins);
572  }
573  double guessVerificationProgress(const BlockHash &block_hash) override {
574  LOCK(cs_main);
576  Params().TxData(),
577  chainman().m_blockman.LookupBlockIndex(block_hash));
578  }
579  bool hasBlocks(const BlockHash &block_hash, int min_height,
580  std::optional<int> max_height) override {
581  // hasBlocks returns true if all ancestors of block_hash in
582  // specified range have block data (are not pruned), false if any
583  // ancestors in specified range are missing data.
584  //
585  // For simplicity and robustness, min_height and max_height are only
586  // used to limit the range, and passing min_height that's too low or
587  // max_height that's too high will not crash or change the result.
588  LOCK(::cs_main);
589  if (const CBlockIndex *block =
590  chainman().m_blockman.LookupBlockIndex(block_hash)) {
591  if (max_height && block->nHeight >= *max_height) {
592  block = block->GetAncestor(*max_height);
593  }
594  for (; block->nStatus.hasData(); block = block->pprev) {
595  // Check pprev to not segfault if min_height is too low
596  if (block->nHeight <= min_height || !block->pprev) {
597  return true;
598  }
599  }
600  }
601  return false;
602  }
603  bool broadcastTransaction(const Config &config,
604  const CTransactionRef &tx,
605  const Amount &max_tx_fee, bool relay,
606  std::string &err_string) override {
607  const TransactionError err =
608  BroadcastTransaction(m_node, tx, err_string, max_tx_fee, relay,
609  /*wait_callback=*/false);
610  // Chain clients only care about failures to accept the tx to the
611  // mempool. Disregard non-mempool related failures. Note: this will
612  // need to be updated if BroadcastTransactions() is updated to
613  // return other non-mempool failures that Chain clients do not need
614  // to know about.
615  return err == TransactionError::OK;
616  }
617  CFeeRate estimateFee() const override {
618  if (!m_node.mempool) {
619  return {};
620  }
621  return m_node.mempool->estimateFee();
622  }
625  bool havePruned() override {
626  LOCK(cs_main);
627  return m_node.chainman->m_blockman.m_have_pruned;
628  }
629  bool isReadyToBroadcast() override {
630  return !node::fImporting && !node::fReindex &&
632  }
633  bool isInitialBlockDownload() override {
634  return chainman().ActiveChainstate().IsInitialBlockDownload();
635  }
636  bool shutdownRequested() override { return ShutdownRequested(); }
637  int64_t getAdjustedTime() override { return GetAdjustedTime(); }
638  void initMessage(const std::string &message) override {
639  ::uiInterface.InitMessage(message);
640  }
641  void initWarning(const bilingual_str &message) override {
642  InitWarning(message);
643  }
644  void initError(const bilingual_str &message) override {
645  InitError(message);
646  }
647  void showProgress(const std::string &title, int progress,
648  bool resume_possible) override {
649  ::uiInterface.ShowProgress(title, progress, resume_possible);
650  }
651  std::unique_ptr<Handler> handleNotifications(
652  std::shared_ptr<Notifications> notifications) override {
653  return std::make_unique<NotificationsHandlerImpl>(
654  std::move(notifications));
655  }
656  void
657  waitForNotificationsIfTipChanged(const BlockHash &old_tip) override {
658  if (!old_tip.IsNull()) {
659  LOCK(::cs_main);
660  const CChain &active = Assert(m_node.chainman)->ActiveChain();
661  if (old_tip == active.Tip()->GetBlockHash()) {
662  return;
663  }
664  }
666  }
667 
668  std::unique_ptr<Handler>
669  handleRpc(const CRPCCommand &command) override {
670  return std::make_unique<RpcHandlerImpl>(command);
671  }
672  bool rpcEnableDeprecated(const std::string &method) override {
673  return IsDeprecatedRPCEnabled(gArgs, method);
674  }
675  void rpcRunLater(const std::string &name, std::function<void()> fn,
676  int64_t seconds) override {
677  RPCRunLater(name, std::move(fn), seconds);
678  }
679  int rpcSerializationFlags() override { return RPCSerializationFlags(); }
680  util::SettingsValue getRwSetting(const std::string &name) override {
681  util::SettingsValue result;
682  gArgs.LockSettings([&](const util::Settings &settings) {
683  if (const util::SettingsValue *value =
684  util::FindKey(settings.rw_settings, name)) {
685  result = *value;
686  }
687  });
688  return result;
689  }
690  bool updateRwSetting(const std::string &name,
691  const util::SettingsValue &value) override {
692  gArgs.LockSettings([&](util::Settings &settings) {
693  if (value.isNull()) {
694  settings.rw_settings.erase(name);
695  } else {
696  settings.rw_settings[name] = value;
697  }
698  });
699  return gArgs.WriteSettingsFile();
700  }
701  void requestMempoolTransactions(Notifications &notifications) override {
702  if (!m_node.mempool) {
703  return;
704  }
705  LOCK2(::cs_main, m_node.mempool->cs);
706  for (const CTxMemPoolEntry &entry : m_node.mempool->mapTx) {
707  notifications.transactionAddedToMempool(entry.GetSharedTx(),
708  /*mempool_sequence=*/0);
709  }
710  }
711  const CChainParams &params() const override { return m_params; }
712  NodeContext &m_node;
714  };
715 } // namespace
716 } // namespace node
717 
718 namespace interfaces {
719 std::unique_ptr<Node> MakeNode(node::NodeContext *context) {
720  return std::make_unique<node::NodeImpl>(context);
721 }
722 std::unique_ptr<Chain> MakeChain(node::NodeContext &node,
723  const CChainParams &params) {
724  return std::make_unique<node::ChainImpl>(node, params);
725 }
726 } // namespace interfaces
int flags
Definition: bitcoin-tx.cpp:538
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:112
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
Definition: chain.cpp:115
const CChainParams & Params()
Return the currently selected parameters.
#define Assert(val)
Identity function.
Definition: check.h:65
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr) const
Write settings file.
Definition: system.cpp:554
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: system.h:426
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:601
BlockHash GetHash() const
Definition: block.cpp:11
int64_t GetBlockTime() const
Definition: block.h:52
void SetNull()
Definition: block.h:75
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:26
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:33
int64_t GetBlockTime() const
Definition: blockindex.h:174
int64_t GetMedianTimePast() const
Definition: blockindex.h:186
int64_t GetBlockTimeMax() const
Definition: blockindex.h:176
unsigned int nTx
Number of transactions in this block.
Definition: blockindex.h:61
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: blockindex.cpp:71
BlockHash GetBlockHash() const
Definition: blockindex.h:147
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:39
An in-memory indexed chain of blocks.
Definition: chain.h:141
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:157
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip).
Definition: chain.cpp:21
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:65
int Height() const
Return the maximal height in the chain.
Definition: chain.h:193
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:74
const CBlock & GenesisBlock() const
Definition: chainparams.h:99
NumConnections
Definition: net.h:909
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:22
std::string name
Definition: server.h:174
Actor actor
Definition: server.h:175
bool removeCommand(const std::string &name, const CRPCCommand *pcmd)
Definition: server.cpp:333
std::vector< std::string > listCommands() const
Returns a list of registered commands.
Definition: server.cpp:547
UniValue execute(const Config &config, const JSONRPCRequest &request) const
Execute a method.
Definition: server.cpp:508
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:325
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
Definition: txmempool.h:84
CTransactionRef GetSharedTx() const
Definition: txmempool.h:129
Implement this to subscribe to events generated in validation.
virtual void TransactionAddedToMempool(const CTransactionRef &tx, uint64_t mempool_sequence)
Notifies listeners of a transaction having been added to mempool.
virtual void ChainStateFlushed(const CBlockLocator &locator)
Notifies listeners of the new active block chain on-disk.
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:647
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:132
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:1062
A UTXO entry.
Definition: coins.h:27
Definition: config.h:17
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
Class for registering and managing all RPC calls.
Definition: server.h:39
RPC timer "driver".
Definition: server.h:99
bool isNull() const
Definition: univalue.h:89
bool isNum() const
Definition: univalue.h:94
int get_int() const
Wrapper around std::unique_lock style lock for Mutex.
Definition: sync.h:137
bool IsNull() const
Definition: uint256.h:30
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 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 updateRwSetting(const std::string &name, const util::SettingsValue &value)=0
Write a setting to <datadir>/settings.json.
virtual bool isReadyToBroadcast()=0
Check if the node is ready to broadcast transactions.
virtual int64_t getAdjustedTime()=0
Get adjusted time.
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 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.
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:57
Wallet chain client that in addition to having chain client methods for starting up,...
Definition: wallet.h:308
TransactionError
Definition: error.h:22
void Interrupt(NodeContext &node)
Interrupt threads.
Definition: init.cpp:182
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:1597
bool AppInitLockDataDirectory()
Lock bitcoin data directory.
Definition: init.cpp:2074
void Shutdown(NodeContext &node)
Definition: init.cpp:206
bool AppInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, NodeContext &node, interfaces::BlockAndHeaderTipInfo *tip_info)
Bitcoin main initialization.
Definition: init.cpp:2096
bool AppInitBasicSetup(const ArgsManager &args)
Initialize bitcoin: Basic context setup.
Definition: init.cpp:1624
bool AppInitSanityChecks()
Initialization sanity checks: ecc init, sanity checks, dir lock.
Definition: init.cpp:2056
bool AppInitInterfaces(NodeContext &node)
Initialize node and wallet interface pointers.
Definition: init.cpp:2086
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:1463
bool AppInitParameterInteraction(Config &config, const ArgsManager &args)
Initialization: parameter interaction.
Definition: init.cpp:1671
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< Chain > MakeChain(node::NodeContext &node, const CChainParams &params)
Return implementation of Chain interface.
Definition: interfaces.cpp:722
std::unique_ptr< Node > MakeNode(node::NodeContext *context=nullptr)
Return implementation of Node interface.
Definition: interfaces.cpp:719
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
std::atomic_bool fImporting
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &params)
Functions for disk access for blocks.
void FindCoins(const NodeContext &node, std::map< COutPoint, Coin > &coins)
Look up unspent output information.
Definition: coin.cpp:12
std::atomic_bool fReindex
auto FindKey(Map &&map, Key &&key) -> decltype(&map.at(key))
Map lookup helper.
Definition: settings.h:110
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:712
NodeContext * m_context
Definition: interfaces.cpp:323
std::shared_ptr< Chain::Notifications > m_notifications
Definition: interfaces.cpp:397
CRPCCommand m_command
Definition: interfaces.cpp:458
const CChainParams & m_params
Definition: interfaces.cpp:713
const CRPCCommand * m_wrapped_command
Definition: interfaces.cpp:459
std::shared_ptr< NotificationsProxy > m_proxy
Definition: interfaces.cpp:415
int64_t NodeId
Definition: nodeid.h:10
CFeeRate dustRelayFee
Definition: settings.cpp:11
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:321
const char * name
Definition: rest.cpp:49
@ 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:572
bool IsDeprecatedRPCEnabled(const ArgsManager &args, const std::string &method)
Definition: server.cpp:405
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
Unset factory function for timers.
Definition: server.cpp:582
void RPCRunLater(const std::string &name, std::function< void()> func, int64_t nSeconds)
Run func nSeconds from now.
Definition: server.cpp:588
void StopRPC()
Definition: server.cpp:363
int RPCSerializationFlags()
Retrieves any serialization flags requested in command line argument.
Definition: server.cpp:603
void InterruptRPC()
Definition: server.cpp:352
CRPCTable tableRPC
Definition: server.cpp:607
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:100
Bilingual messages:
Definition: translation.h:17
Block and header tip information.
Definition: node.h:48
Block tip (could be a header or not, depends on the subscribed signal).
Definition: node.h:251
NodeContext struct containing references to chain state and connection state.
Definition: context.h:38
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
#define WAIT_LOCK(cs, name)
Definition: sync.h:251
#define LOCK2(cs1, cs2)
Definition: sync.h:246
#define LOCK(cs)
Definition: sync.h:243
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:276
#define TRY_LOCK(cs, name)
Definition: sync.h:249
#define REVERSE_LOCK(g)
Definition: sync.h:235
ArgsManager gArgs
Definition: system.cpp:79
int64_t GetAdjustedTime()
Definition: timedata.cpp:34
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
Definition: txmempool.h:240
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...
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation)
Definition: validation.cpp:125
assert(!tx.IsCoinBase())
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition: validation.h:122
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