Bitcoin ABC 0.34.2
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 <feerate.h>
12#include <init.h>
13#include <interfaces/chain.h>
14#include <interfaces/handler.h>
15#include <interfaces/node.h>
16#include <interfaces/wallet.h>
18#include <logging.h>
19#include <mapport.h>
20#include <net.h>
21#include <net_processing.h>
22#include <netaddress.h>
23#include <netbase.h>
24#include <node/blockstorage.h>
25#include <node/coin.h>
26#include <node/context.h>
27#include <node/transaction.h>
28#include <node/types.h>
29#include <node/ui_interface.h>
30#include <policy/settings.h>
31#include <primitives/block.h>
33#include <rpc/blockchain.h>
34#include <rpc/protocol.h>
35#include <rpc/server.h>
36#include <shutdown.h>
37#include <sync.h>
38#include <txmempool.h>
39#include <uint256.h>
40#include <util/check.h>
41#include <util/translation.h>
42#include <validation.h>
43#include <validationinterface.h>
44#include <warnings.h>
45
46#if defined(HAVE_CONFIG_H)
47#include <config/bitcoin-config.h>
48#endif
49
50#include <univalue.h>
51
52#include <boost/signals2/signal.hpp>
53
54#include <memory>
55#include <utility>
56
58
66
67namespace node {
68namespace {
69
70 class NodeImpl : public Node {
71 private:
72 ChainstateManager &chainman() { return *Assert(m_context->chainman); }
73
74 public:
75 explicit NodeImpl(NodeContext *context) { setContext(context); }
76 void initLogging() override { InitLogging(*Assert(m_context->args)); }
77 void initParameterInteraction() override {
79 }
80 bilingual_str getWarnings() override { return GetWarnings(true); }
81 int getExitStatus() override {
82 return Assert(m_context)->exit_status.load();
83 }
84 bool baseInitialize(Config &config) override {
85 if (!AppInitBasicSetup(gArgs, Assert(context())->exit_status)) {
86 return false;
87 }
88 if (!AppInitParameterInteraction(config, gArgs)) {
89 return false;
90 }
91
92 m_context->kernel = std::make_unique<kernel::Context>();
93 if (!AppInitSanityChecks(*m_context->kernel)) {
94 return false;
95 }
96
98 return false;
99 }
101 return false;
102 }
103
104 return true;
105 }
106 bool appInitMain(Config &config, RPCServer &rpcServer,
107 HTTPRPCRequestProcessor &httpRPCRequestProcessor,
108 interfaces::BlockAndHeaderTipInfo *tip_info) override {
109 if (AppInitMain(config, rpcServer, httpRPCRequestProcessor,
110 *m_context, tip_info)) {
111 return true;
112 }
113 // Error during initialization, set exit status before continue
114 m_context->exit_status.store(EXIT_FAILURE);
115 return false;
116 }
117 void appShutdown() override {
120 }
121 void startShutdown() override {
123 // Stop RPC for clean shutdown if any of waitfor* commands is
124 // executed.
125 if (gArgs.GetBoolArg("-server", false)) {
126 InterruptRPC();
127 StopRPC();
128 }
129 }
130 bool shutdownRequested() override { return ShutdownRequested(); }
131 bool isPersistentSettingIgnored(const std::string &name) override {
132 bool ignored = false;
133 gArgs.LockSettings([&](util::Settings &settings) {
134 if (auto *options =
136 ignored = !options->empty();
137 }
138 });
139 return ignored;
140 }
142 getPersistentSetting(const std::string &name) override {
144 }
145 void updateRwSetting(const std::string &name,
146 const util::SettingsValue &value) override {
147 gArgs.LockSettings([&](util::Settings &settings) {
148 if (value.isNull()) {
149 settings.rw_settings.erase(name);
150 } else {
151 settings.rw_settings[name] = value;
152 }
153 });
155 }
156 void forceSetting(const std::string &name,
157 const util::SettingsValue &value) override {
158 gArgs.LockSettings([&](util::Settings &settings) {
159 if (value.isNull()) {
160 settings.forced_settings.erase(name);
161 } else {
162 settings.forced_settings[name] = value;
163 }
164 });
165 }
166 void resetSettings() override {
167 gArgs.WriteSettingsFile(/*errors=*/nullptr, /*backup=*/true);
168 gArgs.LockSettings([&](util::Settings &settings) {
169 settings.rw_settings.clear();
170 });
172 }
173 void mapPort(bool enable) override { StartMapPort(enable); }
174 bool getProxy(Network net, Proxy &proxy_info) override {
175 return GetProxy(net, proxy_info);
176 }
177 size_t getNodeCount(ConnectionDirection flags) override {
178 return m_context->connman ? m_context->connman->GetNodeCount(flags)
179 : 0;
180 }
181 bool getNodesStats(NodesStats &stats) override {
182 stats.clear();
183
184 if (m_context->connman) {
185 std::vector<CNodeStats> stats_temp;
186 m_context->connman->GetNodeStats(stats_temp);
187
188 stats.reserve(stats_temp.size());
189 for (auto &node_stats_temp : stats_temp) {
190 stats.emplace_back(std::move(node_stats_temp), false,
192 }
193
194 // Try to retrieve the CNodeStateStats for each node.
195 if (m_context->peerman) {
196 TRY_LOCK(::cs_main, lockMain);
197 if (lockMain) {
198 for (auto &node_stats : stats) {
199 std::get<1>(node_stats) =
200 m_context->peerman->GetNodeStateStats(
201 std::get<0>(node_stats).nodeid,
202 std::get<2>(node_stats));
203 }
204 }
205 }
206 return true;
207 }
208 return false;
209 }
210 bool getBanned(banmap_t &banmap) override {
211 if (m_context->banman) {
212 m_context->banman->GetBanned(banmap);
213 return true;
214 }
215 return false;
216 }
217 bool ban(const CNetAddr &net_addr, int64_t ban_time_offset) override {
218 if (m_context->banman) {
219 m_context->banman->Ban(net_addr, ban_time_offset);
220 return true;
221 }
222 return false;
223 }
224 bool unban(const CSubNet &ip) override {
225 if (m_context->banman) {
226 m_context->banman->Unban(ip);
227 return true;
228 }
229 return false;
230 }
231 bool disconnectByAddress(const CNetAddr &net_addr) override {
232 if (m_context->connman) {
233 return m_context->connman->DisconnectNode(net_addr);
234 }
235 return false;
236 }
237 bool disconnectById(NodeId id) override {
238 if (m_context->connman) {
239 return m_context->connman->DisconnectNode(id);
240 }
241 return false;
242 }
243 int64_t getTotalBytesRecv() override {
244 return m_context->connman ? m_context->connman->GetTotalBytesRecv()
245 : 0;
246 }
247 int64_t getTotalBytesSent() override {
248 return m_context->connman ? m_context->connman->GetTotalBytesSent()
249 : 0;
250 }
251 size_t getMempoolSize() override {
252 return m_context->mempool ? m_context->mempool->size() : 0;
253 }
254 size_t getMempoolDynamicUsage() override {
255 return m_context->mempool ? m_context->mempool->DynamicMemoryUsage()
256 : 0;
257 }
258 bool getHeaderTip(int &height, int64_t &block_time) override {
260 auto best_header = chainman().m_best_header;
261 if (best_header) {
262 height = best_header->nHeight;
263 block_time = best_header->GetBlockTime();
264 return true;
265 }
266 return false;
267 }
268 int getNumBlocks() override {
270 return chainman().ActiveChain().Height();
271 }
272 BlockHash getBestBlockHash() override {
273 const CBlockIndex *tip =
274 WITH_LOCK(::cs_main, return chainman().ActiveTip());
275 return tip ? tip->GetBlockHash()
276 : chainman().GetParams().GenesisBlock().GetHash();
277 }
278 int64_t getLastBlockTime() override {
280 if (chainman().ActiveChain().Tip()) {
281 return chainman().ActiveChain().Tip()->GetBlockTime();
282 }
283 // Genesis block's time of current network
284 return chainman().GetParams().GenesisBlock().GetBlockTime();
285 }
286 double getVerificationProgress() override {
287 const CBlockIndex *tip;
288 {
290 tip = chainman().ActiveChain().Tip();
291 }
292 return GuessVerificationProgress(chainman().GetParams().TxData(),
293 tip);
294 }
295 bool isInitialBlockDownload() override {
296 return chainman().IsInitialBlockDownload();
297 }
298 bool isLoadingBlocks() override {
299 return chainman().m_blockman.LoadingBlocks();
300 }
301 void setNetworkActive(bool active) override {
302 if (m_context->connman) {
303 m_context->connman->SetNetworkActive(active);
304 }
305 }
306 bool getNetworkActive() override {
307 return m_context->connman && m_context->connman->GetNetworkActive();
308 }
309 CFeeRate getDustRelayFee() override {
310 if (!m_context->mempool) {
312 }
313 return m_context->mempool->m_opts.dust_relay_feerate;
314 }
315 UniValue executeRpc(const Config &config, const std::string &command,
316 const UniValue &params,
317 const std::string &uri) override {
318 JSONRPCRequest req;
319 req.context = m_context;
320 req.params = params;
321 req.strMethod = command;
322 req.URI = uri;
323 return ::tableRPC.execute(config, req);
324 }
325 std::vector<std::string> listRpcCommands() override {
327 }
328 void rpcSetTimerInterfaceIfUnset(RPCTimerInterface *iface) override {
330 }
331 void rpcUnsetTimerInterface(RPCTimerInterface *iface) override {
333 }
334 std::optional<Coin> getUnspentOutput(const COutPoint &output) override {
336 return chainman().ActiveChainstate().CoinsTip().GetCoin(output);
337 }
338 WalletClient &walletClient() override {
339 return *Assert(m_context->wallet_client);
340 }
341 std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override {
342 return MakeHandler(::uiInterface.InitMessage_connect(fn));
343 }
344 std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) override {
345 return MakeHandler(::uiInterface.ThreadSafeMessageBox_connect(fn));
346 }
347 std::unique_ptr<Handler> handleQuestion(QuestionFn fn) override {
348 return MakeHandler(::uiInterface.ThreadSafeQuestion_connect(fn));
349 }
350 std::unique_ptr<Handler>
351 handleShowProgress(ShowProgressFn fn) override {
352 return MakeHandler(::uiInterface.ShowProgress_connect(fn));
353 }
354 std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(
355 NotifyNumConnectionsChangedFn fn) override {
356 return MakeHandler(
357 ::uiInterface.NotifyNumConnectionsChanged_connect(fn));
358 }
359 std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(
360 NotifyNetworkActiveChangedFn fn) override {
361 return MakeHandler(
362 ::uiInterface.NotifyNetworkActiveChanged_connect(fn));
363 }
364 std::unique_ptr<Handler>
365 handleNotifyAlertChanged(NotifyAlertChangedFn fn) override {
366 return MakeHandler(::uiInterface.NotifyAlertChanged_connect(fn));
367 }
368 std::unique_ptr<Handler>
369 handleBannedListChanged(BannedListChangedFn fn) override {
370 return MakeHandler(::uiInterface.BannedListChanged_connect(fn));
371 }
372 std::unique_ptr<Handler>
373 handleNotifyBlockTip(NotifyBlockTipFn fn) override {
374 return MakeHandler(::uiInterface.NotifyBlockTip_connect(
375 [fn](SynchronizationState sync_state,
376 const CBlockIndex *block) {
377 fn(sync_state,
378 BlockTip{block->nHeight, block->GetBlockTime(),
379 block->GetBlockHash()},
380 GuessVerificationProgress(Params().TxData(), block));
381 }));
382 }
383 std::unique_ptr<Handler>
384 handleNotifyHeaderTip(NotifyHeaderTipFn fn) override {
385 /* verification progress is unused when a header was received */
386 return MakeHandler(::uiInterface.NotifyHeaderTip_connect(
387 [fn](SynchronizationState sync_state, int64_t height,
388 int64_t timestamp, bool presync) {
389 fn(sync_state,
390 BlockTip{int(height), timestamp, BlockHash{}}, presync);
391 }));
392 }
393 NodeContext *context() override { return m_context; }
394 void setContext(NodeContext *context) override { m_context = context; }
395 NodeContext *m_context{nullptr};
396 };
397
398 bool FillBlock(const CBlockIndex *index, const FoundBlock &block,
399 UniqueLock<RecursiveMutex> &lock, const CChain &active,
400 const BlockManager &blockman) {
401 if (!index) {
402 return false;
403 }
404 if (block.m_hash) {
405 *block.m_hash = index->GetBlockHash();
406 }
407 if (block.m_height) {
408 *block.m_height = index->nHeight;
409 }
410 if (block.m_time) {
411 *block.m_time = index->GetBlockTime();
412 }
413 if (block.m_max_time) {
414 *block.m_max_time = index->GetBlockTimeMax();
415 }
416 if (block.m_mtp_time) {
417 *block.m_mtp_time = index->GetMedianTimePast();
418 }
419 if (block.m_in_active_chain) {
420 *block.m_in_active_chain = active[index->nHeight] == index;
421 }
422 if (block.m_locator) {
423 *block.m_locator = GetLocator(index);
424 }
425 if (block.m_next_block) {
426 FillBlock(active[index->nHeight] == index
427 ? active[index->nHeight + 1]
428 : nullptr,
429 *block.m_next_block, lock, active, blockman);
430 }
431 if (block.m_data) {
432 REVERSE_LOCK(lock);
433 if (!blockman.ReadBlock(*block.m_data, *index)) {
434 block.m_data->SetNull();
435 }
436 }
437 return true;
438 }
439
440 class NotificationsProxy : public CValidationInterface {
441 public:
442 explicit NotificationsProxy(
443 std::shared_ptr<Chain::Notifications> notifications)
444 : m_notifications(std::move(notifications)) {}
445 virtual ~NotificationsProxy() = default;
446 void TransactionAddedToMempool(const CTransactionRef &tx,
447 std::shared_ptr<const std::vector<Coin>>,
448 uint64_t mempool_sequence) override {
449 m_notifications->transactionAddedToMempool(tx, mempool_sequence);
450 }
451 void TransactionRemovedFromMempool(const CTransactionRef &tx,
453 uint64_t mempool_sequence) override {
454 m_notifications->transactionRemovedFromMempool(tx, reason,
455 mempool_sequence);
456 }
457 void BlockConnected(ChainstateRole role,
458 const std::shared_ptr<const CBlock> &block,
459 const CBlockIndex *index) override {
460 m_notifications->blockConnected(role, *block, index->nHeight);
461 }
462 void BlockDisconnected(const std::shared_ptr<const CBlock> &block,
463 const CBlockIndex *index) override {
464 m_notifications->blockDisconnected(*block, index->nHeight);
465 }
466 void UpdatedBlockTip(const CBlockIndex *index,
467 const CBlockIndex *fork_index,
468 bool is_ibd) override {
469 m_notifications->updatedBlockTip();
470 }
471 void ChainStateFlushed(ChainstateRole role,
472 const CBlockLocator &locator) override {
473 m_notifications->chainStateFlushed(role, locator);
474 }
475 std::shared_ptr<Chain::Notifications> m_notifications;
476 };
477
478 class NotificationsHandlerImpl : public Handler {
479 public:
480 explicit NotificationsHandlerImpl(
481 ValidationSignals &signals,
482 std::shared_ptr<Chain::Notifications> notifications)
483 : m_signals{signals}, m_proxy{std::make_shared<NotificationsProxy>(
484 std::move(notifications))} {
486 }
487 ~NotificationsHandlerImpl() override { disconnect(); }
488 void disconnect() override {
489 if (m_proxy) {
491 m_proxy.reset();
492 }
493 }
495 std::shared_ptr<NotificationsProxy> m_proxy;
496 };
497
498 class RpcHandlerImpl : public Handler {
499 public:
500 explicit RpcHandlerImpl(const CRPCCommand &command)
501 : m_command(command), m_wrapped_command(&command) {
502 m_command.actor = [this](const Config &config,
503 const JSONRPCRequest &request,
504 UniValue &result, bool last_handler) {
505 if (!m_wrapped_command) {
506 return false;
507 }
508 try {
509 return m_wrapped_command->actor(config, request, result,
510 last_handler);
511 } catch (const UniValue &e) {
512 // If this is not the last handler and a wallet not found
513 // exception was thrown, return false so the next handler
514 // can try to handle the request. Otherwise, reraise the
515 // exception.
516 if (!last_handler) {
517 const UniValue &code = e["code"];
518 if (code.isNum() &&
519 code.getInt<int>() == RPC_WALLET_NOT_FOUND) {
520 return false;
521 }
522 }
523 throw;
524 }
525 };
527 }
528
529 void disconnect() final {
530 if (m_wrapped_command) {
531 m_wrapped_command = nullptr;
533 }
534 }
535
536 ~RpcHandlerImpl() override { disconnect(); }
537
540 };
541
542 class ChainImpl : public Chain {
543 private:
544 ChainstateManager &chainman() { return *Assert(m_node.chainman); }
545
546 public:
547 explicit ChainImpl(NodeContext &node, const CChainParams &params)
548 : m_node(node), m_params(params) {}
549 std::optional<int> getHeight() override {
551 const CChain &active = Assert(m_node.chainman)->ActiveChain();
552 int height = active.Height();
553 if (height >= 0) {
554 return height;
555 }
556 return std::nullopt;
557 }
558 BlockHash getBlockHash(int height) override {
560 const CChain &active = Assert(m_node.chainman)->ActiveChain();
561 CBlockIndex *block = active[height];
562 assert(block);
563 return block->GetBlockHash();
564 }
565 bool haveBlockOnDisk(int height) override {
566 LOCK(cs_main);
567 const CChain &active = Assert(m_node.chainman)->ActiveChain();
568 CBlockIndex *block = active[height];
569 return block && (block->nStatus.hasData() != 0) && block->nTx > 0;
570 }
571 CBlockLocator getTipLocator() override {
572 LOCK(cs_main);
573 const CChain &active = Assert(m_node.chainman)->ActiveChain();
574 return active.GetLocator();
575 }
576 // TODO: backport core#25036 with changes from core#25717
577 std::optional<int>
578 findLocatorFork(const CBlockLocator &locator) override {
579 LOCK(cs_main);
580 const Chainstate &active =
581 Assert(m_node.chainman)->ActiveChainstate();
582 if (const CBlockIndex *fork =
583 active.FindForkInGlobalIndex(locator)) {
584 return fork->nHeight;
585 }
586 return std::nullopt;
587 }
588 bool findBlock(const BlockHash &hash,
589 const FoundBlock &block) override {
590 WAIT_LOCK(cs_main, lock);
591 const CChain &active = Assert(m_node.chainman)->ActiveChain();
592 return FillBlock(m_node.chainman->m_blockman.LookupBlockIndex(hash),
593 block, lock, active, chainman().m_blockman);
594 }
595 bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height,
596 const FoundBlock &block) override {
597 WAIT_LOCK(cs_main, lock);
598 const CChain &active = Assert(m_node.chainman)->ActiveChain();
599 return FillBlock(active.FindEarliestAtLeast(min_time, min_height),
600 block, lock, active, chainman().m_blockman);
601 }
602 bool findAncestorByHeight(const BlockHash &block_hash,
603 int ancestor_height,
604 const FoundBlock &ancestor_out) override {
605 WAIT_LOCK(cs_main, lock);
606 const CChain &active = Assert(m_node.chainman)->ActiveChain();
607 if (const CBlockIndex *block =
608 m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
609 if (const CBlockIndex *ancestor =
610 block->GetAncestor(ancestor_height)) {
611 return FillBlock(ancestor, ancestor_out, lock, active,
612 chainman().m_blockman);
613 }
614 }
615 return FillBlock(nullptr, ancestor_out, lock, active,
616 chainman().m_blockman);
617 }
618 bool findAncestorByHash(const BlockHash &block_hash,
619 const BlockHash &ancestor_hash,
620 const FoundBlock &ancestor_out) override {
621 WAIT_LOCK(cs_main, lock);
622 const CChain &active = Assert(m_node.chainman)->ActiveChain();
623 const CBlockIndex *block =
624 m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
625 const CBlockIndex *ancestor =
626 m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
627 if (block && ancestor &&
628 block->GetAncestor(ancestor->nHeight) != ancestor) {
629 ancestor = nullptr;
630 }
631 return FillBlock(ancestor, ancestor_out, lock, active,
632 chainman().m_blockman);
633 }
634 bool findCommonAncestor(const BlockHash &block_hash1,
635 const BlockHash &block_hash2,
636 const FoundBlock &ancestor_out,
637 const FoundBlock &block1_out,
638 const FoundBlock &block2_out) override {
639 WAIT_LOCK(cs_main, lock);
640 const CChain &active = Assert(m_node.chainman)->ActiveChain();
641 const CBlockIndex *block1 =
642 m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
643 const CBlockIndex *block2 =
644 m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
645 const CBlockIndex *ancestor =
646 block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
647 // Using & instead of && below to avoid short circuiting and leaving
648 // output uninitialized. Cast bool to int to avoid
649 // -Wbitwise-instead-of-logical compiler warnings.
650 return int{FillBlock(ancestor, ancestor_out, lock, active,
651 chainman().m_blockman)} &
652 int{FillBlock(block1, block1_out, lock, active,
653 chainman().m_blockman)} &
654 int{FillBlock(block2, block2_out, lock, active,
655 chainman().m_blockman)};
656 }
657 void findCoins(std::map<COutPoint, Coin> &coins) override {
658 return FindCoins(m_node, coins);
659 }
660 double guessVerificationProgress(const BlockHash &block_hash) override {
661 LOCK(cs_main);
663 chainman().GetParams().TxData(),
664 chainman().m_blockman.LookupBlockIndex(block_hash));
665 }
666 bool hasBlocks(const BlockHash &block_hash, int min_height,
667 std::optional<int> max_height) override {
668 // hasBlocks returns true if all ancestors of block_hash in
669 // specified range have block data (are not pruned), false if any
670 // ancestors in specified range are missing data.
671 //
672 // For simplicity and robustness, min_height and max_height are only
673 // used to limit the range, and passing min_height that's too low or
674 // max_height that's too high will not crash or change the result.
676 if (const CBlockIndex *block =
677 chainman().m_blockman.LookupBlockIndex(block_hash)) {
678 if (max_height && block->nHeight >= *max_height) {
679 block = block->GetAncestor(*max_height);
680 }
681 for (; block->nStatus.hasData(); block = block->pprev) {
682 // Check pprev to not segfault if min_height is too low
683 if (block->nHeight <= min_height || !block->pprev) {
684 return true;
685 }
686 }
687 }
688 return false;
689 }
690 bool broadcastTransaction(const Config &config,
691 const CTransactionRef &tx,
692 const Amount &max_tx_fee, bool relay,
693 std::string &err_string) override {
694 const TransactionError err =
695 BroadcastTransaction(m_node, tx, err_string, max_tx_fee, relay,
696 /*wait_callback=*/false);
697 // Chain clients only care about failures to accept the tx to the
698 // mempool. Disregard non-mempool related failures. Note: this will
699 // need to be updated if BroadcastTransactions() is updated to
700 // return other non-mempool failures that Chain clients do not need
701 // to know about.
702 return err == TransactionError::OK;
703 }
704 CFeeRate estimateFee() const override {
705 if (!m_node.mempool) {
706 return CFeeRate{Amount::zero()};
707 }
708 return m_node.mempool->estimateFee();
709 }
710 CFeeRate relayMinFee() override {
711 if (!m_node.mempool) {
713 }
714 return m_node.mempool->m_opts.min_relay_feerate;
715 }
716 CFeeRate relayDustFee() override {
717 if (!m_node.mempool) {
719 }
720 return m_node.mempool->m_opts.dust_relay_feerate;
721 }
722 bool havePruned() override {
723 LOCK(cs_main);
724 return m_node.chainman->m_blockman.m_have_pruned;
725 }
726 bool isReadyToBroadcast() override {
727 return !chainman().m_blockman.LoadingBlocks() &&
728 !isInitialBlockDownload();
729 }
730 std::optional<int> getPruneHeight() override {
731 LOCK(chainman().GetMutex());
732 return GetPruneHeight(chainman().m_blockman,
733 chainman().ActiveChain());
734 }
735 bool isInitialBlockDownload() override {
736 return chainman().IsInitialBlockDownload();
737 }
738 bool shutdownRequested() override { return ShutdownRequested(); }
739 void initMessage(const std::string &message) override {
740 ::uiInterface.InitMessage(message);
741 }
742 void initWarning(const bilingual_str &message) override {
743 InitWarning(message);
744 }
745 void initError(const bilingual_str &message) override {
746 InitError(message);
747 }
748 void showProgress(const std::string &title, int progress,
749 bool resume_possible) override {
750 ::uiInterface.ShowProgress(title, progress, resume_possible);
751 }
752 std::unique_ptr<Handler> handleNotifications(
753 std::shared_ptr<Notifications> notifications) override {
754 return std::make_unique<NotificationsHandlerImpl>(
755 validation_signals(), std::move(notifications));
756 }
757 void
758 waitForNotificationsIfTipChanged(const BlockHash &old_tip) override {
759 if (!old_tip.IsNull()) {
761 const CChain &active = Assert(m_node.chainman)->ActiveChain();
762 if (old_tip == active.Tip()->GetBlockHash()) {
763 return;
764 }
765 }
766 validation_signals().SyncWithValidationInterfaceQueue();
767 }
768
769 std::unique_ptr<Handler>
770 handleRpc(const CRPCCommand &command) override {
771 return std::make_unique<RpcHandlerImpl>(command);
772 }
773 bool rpcEnableDeprecated(const std::string &method) override {
774 return IsDeprecatedRPCEnabled(gArgs, method);
775 }
776 void rpcRunLater(const std::string &name, std::function<void()> fn,
777 int64_t seconds) override {
778 RPCRunLater(name, std::move(fn), seconds);
779 }
780 util::SettingsValue getSetting(const std::string &name) override {
781 return gArgs.GetSetting(name);
782 }
783 std::vector<util::SettingsValue>
784 getSettingsList(const std::string &name) override {
785 return gArgs.GetSettingsList(name);
786 }
787 util::SettingsValue getRwSetting(const std::string &name) override {
788 util::SettingsValue result;
789 gArgs.LockSettings([&](const util::Settings &settings) {
790 if (const util::SettingsValue *value =
791 util::FindKey(settings.rw_settings, name)) {
792 result = *value;
793 }
794 });
795 return result;
796 }
797 bool updateRwSetting(const std::string &name,
798 const util::SettingsValue &value,
799 bool write) override {
800 gArgs.LockSettings([&](util::Settings &settings) {
801 if (value.isNull()) {
802 settings.rw_settings.erase(name);
803 } else {
804 settings.rw_settings[name] = value;
805 }
806 });
807 return !write || gArgs.WriteSettingsFile();
808 }
809 void requestMempoolTransactions(Notifications &notifications) override {
810 if (!m_node.mempool) {
811 return;
812 }
813 LOCK2(::cs_main, m_node.mempool->cs);
814 for (const CTxMemPoolEntryRef &entry : m_node.mempool->mapTx) {
815 notifications.transactionAddedToMempool(entry->GetSharedTx(),
816 /*mempool_sequence=*/0);
817 }
818 }
819 bool hasAssumedValidChain() override {
820 return Assert(m_node.chainman)->IsSnapshotActive();
821 }
822 const CChainParams &params() const override { return m_params; }
823 NodeContext *context() override { return &m_node; }
824 ValidationSignals &validation_signals() {
825 return *Assert(m_node.validation_signals);
826 }
827 NodeContext &m_node;
829 };
830} // namespace
831} // namespace node
832
833namespace interfaces {
834std::unique_ptr<Node> MakeNode(node::NodeContext *context) {
835 return std::make_unique<node::NodeImpl>(context);
836}
837std::unique_ptr<Chain> MakeChain(node::NodeContext &node,
838 const CChainParams &params) {
839 return std::make_unique<node::ChainImpl>(node, params);
840}
841} // namespace interfaces
ArgsManager gArgs
Definition: args.cpp:39
int flags
Definition: bitcoin-tx.cpp:544
std::optional< int > GetPruneHeight(const BlockManager &blockman, const CChain &chain)
Definition: blockchain.cpp:857
CBlockLocator GetLocator(const CBlockIndex *index)
Get a locator for a block index entry.
Definition: chain.cpp:41
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:21
#define Assert(val)
Identity function.
Definition: check.h:87
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:451
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: args.h:422
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr, bool backup=false) const
Write settings file or backup settings file.
Definition: args.cpp:425
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: args.cpp:829
util::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
Definition: args.cpp:820
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: args.cpp:524
void SetNull()
Definition: block.h:82
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:159
int64_t GetMedianTimePast() const
Definition: blockindex.h:171
int64_t GetBlockTimeMax() const
Definition: blockindex.h:161
unsigned int nTx
Number of transactions in this block.
Definition: blockindex.h:55
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: blockindex.cpp:62
BlockHash GetBlockHash() const
Definition: blockindex.h:129
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:138
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:154
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:190
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:86
Fee rate in satoshis per virtualbyte: Amount / vB the feerate is represented internally as FeeFrac.
Definition: feerate.h:24
Network address.
Definition: netaddress.h:114
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:338
std::vector< std::string > listCommands() const
Returns a list of registered commands.
Definition: server.cpp:626
UniValue execute(const Config &config, const JSONRPCRequest &request) const
Execute a method.
Definition: server.cpp:585
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:330
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:727
void ClearBlockIndexCandidates() EXCLUSIVE_LOCKS_REQUIRED(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:1176
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: netbase.h:67
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 MutexType.
Definition: sync.h:168
void RegisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Register subscriber.
void UnregisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Unregister subscriber.
constexpr bool IsNull() const
Definition: uint256.h:44
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:136
Helper for findBlock to selectively return pieces of block data.
Definition: chain.h:55
const FoundBlock * m_next_block
Definition: chain.h:107
BlockHash * m_hash
Definition: chain.h:100
int64_t * m_max_time
Definition: chain.h:103
int64_t * m_time
Definition: chain.h:102
bool * m_in_active_chain
Definition: chain.h:105
int64_t * m_mtp_time
Definition: chain.h:104
CBlockLocator * m_locator
Definition: chain.h:106
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:305
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:7
int64_t NodeId
Definition: eviction.h:16
void Interrupt(NodeContext &node)
Interrupt threads.
Definition: init.cpp:222
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:1856
bool AppInitLockDataDirectory()
Lock bitcoin data directory.
Definition: init.cpp:2252
void Shutdown(NodeContext &node)
Definition: init.cpp:249
bool AppInitBasicSetup(const ArgsManager &args, std::atomic< int > &exit_status)
Initialize bitcoin: Basic context setup.
Definition: init.cpp:1883
bool AppInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, NodeContext &node, interfaces::BlockAndHeaderTipInfo *tip_info)
Bitcoin main initialization.
Definition: init.cpp:2274
bool AppInitInterfaces(NodeContext &node)
Initialize node and wallet interface pointers.
Definition: init.cpp:2264
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:1732
bool AppInitParameterInteraction(Config &config, const ArgsManager &args)
Initialization: parameter interaction.
Definition: init.cpp:1925
bool AppInitSanityChecks(const kernel::Context &kernel)
Initialization sanity checks.
Definition: init.cpp:2236
ChainstateRole
This enum describes the various roles a specific Chainstate instance can take.
Definition: chain.h:14
void StartMapPort(bool enable)
Definition: mapport.cpp:176
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:834
std::unique_ptr< Chain > MakeChain(node::NodeContext &node, const CChainParams &params)
Return implementation of Chain interface.
Definition: interfaces.cpp:837
Definition: messages.h:12
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:38
TransactionError
Definition: types.h:17
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:37
bool GetProxy(enum Network net, Proxy &proxyInfoOut)
Definition: netbase.cpp:809
ConnectionDirection
Definition: netbase.h:37
ValidationSignals & m_signals
Definition: interfaces.cpp:494
NodeContext & m_node
Definition: interfaces.cpp:827
NodeContext * m_context
Definition: interfaces.cpp:395
std::shared_ptr< Chain::Notifications > m_notifications
Definition: interfaces.cpp:475
CRPCCommand m_command
Definition: interfaces.cpp:538
const CChainParams & m_params
Definition: interfaces.cpp:828
const CRPCCommand * m_wrapped_command
Definition: interfaces.cpp:539
std::shared_ptr< NotificationsProxy > m_proxy
Definition: interfaces.cpp:495
is a home for public enum and struct type definitions that are used by internally by node code,...
static constexpr Amount DUST_RELAY_TX_FEE(3000 *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:46
@ 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:652
bool IsDeprecatedRPCEnabled(const ArgsManager &args, const std::string &method)
Definition: server.cpp:410
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
Unset factory function for timers.
Definition: server.cpp:662
void RPCRunLater(const std::string &name, std::function< void()> func, int64_t nSeconds)
Run func nSeconds from now.
Definition: server.cpp:668
void StopRPC()
Definition: server.cpp:368
void InterruptRPC()
Definition: server.cpp:357
CRPCTable tableRPC
Definition: server.cpp:683
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
Definition: shutdown.cpp:29
void StartShutdown()
Request shutdown of the application.
Definition: shutdown.cpp:16
Definition: amount.h:23
static constexpr Amount zero() noexcept
Definition: amount.h:36
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:108
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:273
NodeContext struct containing references to chain state and connection state.
Definition: context.h:50
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:304
#define LOCK2(cs1, cs2)
Definition: sync.h:298
#define LOCK(cs)
Definition: sync.h:295
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:343
#define TRY_LOCK(cs, name)
Definition: sync.h:303
#define REVERSE_LOCK(g)
Definition: sync.h:267
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
Definition: txmempool.h:159
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:112
bilingual_str GetWarnings(bool verbose)
Format a string that describes several potential problems detected by the core.
Definition: warnings.cpp:43