Bitcoin ABC 0.30.5
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>
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>
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
62
63namespace node {
64namespace {
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 {
95 // Stop RPC for clean shutdown if any of waitfor* commands is
96 // executed.
97 if (gArgs.GetBoolArg("-server", false)) {
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(ConnectionDirection 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,
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 {
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 {
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 {
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 {
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) {
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 {
307 }
308 bool getUnspentOutput(const COutPoint &output, Coin &coin) override {
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;
419 void TransactionAddedToMempool(const CTransactionRef &tx,
420 std::shared_ptr<const std::vector<Coin>>,
421 uint64_t mempool_sequence) override {
422 m_notifications->transactionAddedToMempool(tx, mempool_sequence);
423 }
424 void TransactionRemovedFromMempool(const CTransactionRef &tx,
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 {
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 {
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.
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) {
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() &&
697 !isInitialBlockDownload();
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()) {
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
791namespace interfaces {
792std::unique_ptr<Node> MakeNode(node::NodeContext *context) {
793 return std::make_unique<node::NodeImpl>(context);
794}
795std::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:541
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
Fee rate in satoshis per kilobyte: Amount / kB.
Definition: feerate.h:21
Network address.
Definition: netaddress.h:121
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.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:699
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:125
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:1219
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
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
Top-level interface for a bitcoin node (bitcoind process).
Definition: node.h:59
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:201
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:1655
bool AppInitLockDataDirectory()
Lock bitcoin data directory.
Definition: init.cpp:2052
void Shutdown(NodeContext &node)
Definition: init.cpp:225
bool AppInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, NodeContext &node, interfaces::BlockAndHeaderTipInfo *tip_info)
Bitcoin main initialization.
Definition: init.cpp:2074
bool AppInitBasicSetup(const ArgsManager &args)
Initialize bitcoin: Basic context setup.
Definition: init.cpp:1682
bool AppInitSanityChecks()
Initialization sanity checks: ecc init, sanity checks, dir lock.
Definition: init.cpp:2034
bool AppInitInterfaces(NodeContext &node)
Initialize node and wallet interface pointers.
Definition: init.cpp:2064
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:1521
bool AppInitParameterInteraction(Config &config, const ArgsManager &args)
Initialization: parameter interaction.
Definition: init.cpp:1729
void StartMapPort(bool use_upnp, bool use_natpmp)
Definition: mapport.cpp:362
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:259
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:715
ConnectionDirection
Definition: netbase.h:32
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:50
Block tip (could be a header or not, depends on the subscribed signal).
Definition: node.h:270
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:151
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:114
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