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