Bitcoin Core 32.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>
37#include <node/blockstorage.h>
38#include <node/coin.h>
39#include <node/context.h>
40#include <node/interface_ui.h>
42#include <node/miner.h>
43#include <node/mini_miner.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/expected.h>
65#include <util/fees.h>
66#include <util/result.h>
68#include <util/string.h>
69#include <util/time.h>
70#include <util/translation.h>
71#include <validation.h>
72#include <validationinterface.h>
73
74#include <any>
75#include <atomic>
76#include <condition_variable>
77#include <cstdint>
78#include <cstdlib>
79#include <functional>
80#include <map>
81#include <memory>
82#include <optional>
83#include <string>
84#include <tuple>
85#include <utility>
86#include <vector>
87
97using interfaces::Rpc;
102using node::CoinbaseTx;
103using util::Join;
104
105namespace node {
106// All members of the classes in this namespace are intentionally public, as the
107// classes themselves are private.
108namespace {
109#ifdef ENABLE_EXTERNAL_SIGNER
110class ExternalSignerImpl : public interfaces::ExternalSigner
111{
112public:
113 ExternalSignerImpl(::ExternalSigner signer) : m_signer(std::move(signer)) {}
114 std::string getName() override { return m_signer.m_name; }
116};
117#endif
118
119class NodeImpl : public Node
120{
121public:
122 explicit NodeImpl(NodeContext& context) { setContext(&context); }
123 void initLogging() override { InitLogging(args()); }
124 void initParameterInteraction() override { InitParameterInteraction(args()); }
125 bilingual_str getWarnings() override { return Join(Assert(m_context->warnings)->GetMessages(), Untranslated("<hr />")); }
126 int getExitStatus() override { return Assert(m_context)->exit_status.load(); }
127 BCLog::CategoryMask getLogCategories() override { return LogInstance().GetCategoryMask(); }
128 bool baseInitialize() override
129 {
130 if (!AppInitBasicSetup(args(), Assert(context())->exit_status)) return false;
131 if (!AppInitParameterInteraction(args())) return false;
132
133 m_context->warnings = std::make_unique<node::Warnings>();
134 m_context->kernel = std::make_unique<kernel::Context>();
135 m_context->ecc_context = std::make_unique<ECC_Context>();
136 if (!AppInitSanityChecks(*m_context->kernel)) return false;
137
138 if (!AppInitLockDirectories()) return false;
139 if (!AppInitInterfaces(*m_context)) return false;
140
141 return true;
142 }
143 bool appInitMain(interfaces::BlockAndHeaderTipInfo* tip_info) override
144 {
145 if (AppInitMain(*m_context, tip_info)) return true;
146 // Error during initialization, set exit status before continue
147 m_context->exit_status.store(EXIT_FAILURE);
148 return false;
149 }
150 void appShutdown() override
151 {
153 }
154 void startShutdown() override
155 {
156 NodeContext& ctx{*Assert(m_context)};
157 if (!(Assert(ctx.shutdown_request))()) {
158 LogError("Failed to send shutdown signal\n");
159 }
161 }
162 bool shutdownRequested() override { return ShutdownRequested(*Assert(m_context)); };
163 bool isSettingIgnored(const std::string& name) override
164 {
165 bool ignored = false;
166 args().LockSettings([&](common::Settings& settings) {
167 if (auto* options = common::FindKey(settings.command_line_options, name)) {
168 ignored = !options->empty();
169 }
170 });
171 return ignored;
172 }
173 common::SettingsValue getPersistentSetting(const std::string& name) override { return args().GetPersistentSetting(name); }
174 void updateRwSetting(const std::string& name, const common::SettingsValue& value) override
175 {
176 args().LockSettings([&](common::Settings& settings) {
177 if (value.isNull()) {
178 settings.rw_settings.erase(name);
179 } else {
180 settings.rw_settings[name] = value;
181 }
182 });
184 }
185 void forceSetting(const std::string& name, const common::SettingsValue& value) override
186 {
187 args().LockSettings([&](common::Settings& settings) {
188 if (value.isNull()) {
189 settings.forced_settings.erase(name);
190 } else {
191 settings.forced_settings[name] = value;
192 }
193 });
194 }
195 void resetSettings() override
196 {
197 args().WriteSettingsFile(/*errors=*/nullptr, /*backup=*/true);
198 args().LockSettings([&](common::Settings& settings) {
199 settings.rw_settings.clear();
200 });
202 }
203 void mapPort(bool enable) override { StartMapPort(enable); }
204 std::optional<Proxy> getProxy(Network net) override { return GetProxy(net); }
205 size_t getNodeCount(ConnectionDirection flags) override
206 {
207 return m_context->connman ? m_context->connman->GetNodeCount(flags) : 0;
208 }
209 bool getNodesStats(NodesStats& stats) override
210 {
211 stats.clear();
212
213 if (m_context->connman) {
214 std::vector<CNodeStats> stats_temp;
215 m_context->connman->GetNodeStats(stats_temp);
216
217 stats.reserve(stats_temp.size());
218 for (auto& node_stats_temp : stats_temp) {
219 stats.emplace_back(std::move(node_stats_temp), false, CNodeStateStats());
220 }
221
222 // Try to retrieve the CNodeStateStats for each node.
223 if (m_context->peerman) {
224 TRY_LOCK(::cs_main, lockMain);
225 if (lockMain) {
226 for (auto& node_stats : stats) {
227 std::get<1>(node_stats) =
228 m_context->peerman->GetNodeStateStats(std::get<0>(node_stats).nodeid, std::get<2>(node_stats));
229 }
230 }
231 }
232 return true;
233 }
234 return false;
235 }
236 bool getBanned(banmap_t& banmap) override
237 {
238 if (m_context->banman) {
239 m_context->banman->GetBanned(banmap);
240 return true;
241 }
242 return false;
243 }
244 bool ban(const CNetAddr& net_addr, int64_t ban_time_offset) override
245 {
246 if (m_context->banman) {
247 m_context->banman->Ban(net_addr, ban_time_offset);
248 return true;
249 }
250 return false;
251 }
252 bool unban(const CSubNet& ip) override
253 {
254 if (m_context->banman) {
255 m_context->banman->Unban(ip);
256 return true;
257 }
258 return false;
259 }
260 bool disconnectByAddress(const CNetAddr& net_addr) override
261 {
262 if (m_context->connman) {
263 return m_context->connman->DisconnectNode(net_addr);
264 }
265 return false;
266 }
267 bool disconnectById(NodeId id) override
268 {
269 if (m_context->connman) {
270 return m_context->connman->DisconnectNode(id);
271 }
272 return false;
273 }
274 std::vector<std::unique_ptr<interfaces::ExternalSigner>> listExternalSigners() override
275 {
276#ifdef ENABLE_EXTERNAL_SIGNER
277 std::vector<ExternalSigner> signers = {};
278 const std::string command = args().GetArg("-signer", "");
279 if (command == "") return {};
280 ExternalSigner::Enumerate(command, signers, Params().GetChainTypeString());
281 std::vector<std::unique_ptr<interfaces::ExternalSigner>> result;
282 result.reserve(signers.size());
283 for (auto& signer : signers) {
284 result.emplace_back(std::make_unique<ExternalSignerImpl>(std::move(signer)));
285 }
286 return result;
287#else
288 // This result is indistinguishable from a successful call that returns
289 // no signers. For the current GUI this doesn't matter, because the wallet
290 // creation dialog disables the external signer checkbox in both
291 // cases. The return type could be changed to std::optional<std::vector>
292 // (or something that also includes error messages) if this distinction
293 // becomes important.
294 return {};
295#endif // ENABLE_EXTERNAL_SIGNER
296 }
297 int64_t getTotalBytesRecv() override { return m_context->connman ? m_context->connman->GetTotalBytesRecv() : 0; }
298 int64_t getTotalBytesSent() override { return m_context->connman ? m_context->connman->GetTotalBytesSent() : 0; }
299 size_t getMempoolSize() override { return m_context->mempool ? m_context->mempool->size() : 0; }
300 size_t getMempoolDynamicUsage() override { return m_context->mempool ? m_context->mempool->DynamicMemoryUsage() : 0; }
301 size_t getMempoolMaxUsage() override { return m_context->mempool ? m_context->mempool->m_opts.max_size_bytes : 0; }
302 bool getHeaderTip(int& height, int64_t& block_time) override
303 {
305 auto best_header = chainman().m_best_header;
306 if (best_header) {
307 height = best_header->nHeight;
308 block_time = best_header->GetBlockTime();
309 return true;
310 }
311 return false;
312 }
313 std::map<CNetAddr, LocalServiceInfo> getNetLocalAddresses() override
314 {
315 if (m_context->connman)
316 return m_context->connman->getNetLocalAddresses();
317 else
318 return {};
319 }
320 int getNumBlocks() override
321 {
323 return chainman().ActiveChain().Height();
324 }
325 uint256 getBestBlockHash() override
326 {
327 const CBlockIndex* tip = WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip());
328 return tip ? tip->GetBlockHash() : chainman().GetParams().GenesisBlock().GetHash();
329 }
330 int64_t getLastBlockTime() override
331 {
333 if (chainman().ActiveChain().Tip()) {
334 return chainman().ActiveChain().Tip()->GetBlockTime();
335 }
336 return chainman().GetParams().GenesisBlock().GetBlockTime(); // Genesis block's time of current network
337 }
338 double getVerificationProgress() override
339 {
340 LOCK(chainman().GetMutex());
341 return chainman().GuessVerificationProgress(chainman().ActiveTip());
342 }
343 bool isInitialBlockDownload() override
344 {
345 return chainman().IsInitialBlockDownload();
346 }
347 bool isLoadingBlocks() override { return chainman().m_blockman.LoadingBlocks(); }
348 void setNetworkActive(bool active) override
349 {
350 if (m_context->connman) {
351 m_context->connman->SetNetworkActive(active);
352 }
353 }
354 bool getNetworkActive() override { return m_context->connman && m_context->connman->GetNetworkActive(); }
355 CFeeRate getDustRelayFee() override
356 {
357 if (!m_context->mempool) return CFeeRate{DUST_RELAY_TX_FEE};
358 return m_context->mempool->m_opts.dust_relay_feerate;
359 }
360 UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
361 {
362 JSONRPCRequest req;
363 req.context = m_context;
364 req.params = params;
365 req.strMethod = command;
366 req.URI = uri;
368 }
369 std::vector<std::string> listRpcCommands() override { return ::tableRPC.listCommands(); }
370 std::optional<Coin> getUnspentOutput(const COutPoint& output) override
371 {
373 return chainman().ActiveChainstate().CoinsTip().GetCoin(output);
374 }
375 TransactionError broadcastTransaction(CTransactionRef tx, CAmount max_tx_fee, CFeeRate max_tx_fee_rate, std::string& err_string) override
376 {
377 return BroadcastTransaction(*m_context, std::move(tx), err_string, max_tx_fee, max_tx_fee_rate, /*broadcast_method=*/TxBroadcast::MEMPOOL_AND_BROADCAST_TO_ALL, /*wait_callback=*/false);
378 }
379 WalletLoader& walletLoader() override
380 {
381 return *Assert(m_context->wallet_loader);
382 }
383 std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
384 {
385 return MakeSignalHandler(::uiInterface.InitMessage.connect(fn));
386 }
387 std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) override
388 {
390 }
391 std::unique_ptr<Handler> handleQuestion(QuestionFn fn) override
392 {
393 return MakeSignalHandler(::uiInterface.ThreadSafeQuestion.connect(fn));
394 }
395 std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
396 {
397 return MakeSignalHandler(::uiInterface.ShowProgress.connect(fn));
398 }
399 std::unique_ptr<Handler> handleInitWallet(InitWalletFn fn) override
400 {
401 return MakeSignalHandler(::uiInterface.InitWallet.connect(fn));
402 }
403 std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
404 {
405 return MakeSignalHandler(::uiInterface.NotifyNumConnectionsChanged.connect(fn));
406 }
407 std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) override
408 {
409 return MakeSignalHandler(::uiInterface.NotifyNetworkActiveChanged.connect(fn));
410 }
411 std::unique_ptr<Handler> handleNotifyAlertChanged(NotifyAlertChangedFn fn) override
412 {
413 return MakeSignalHandler(::uiInterface.NotifyAlertChanged.connect(fn));
414 }
415 std::unique_ptr<Handler> handleBannedListChanged(BannedListChangedFn fn) override
416 {
417 return MakeSignalHandler(::uiInterface.BannedListChanged.connect(fn));
418 }
419 std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
420 {
421 return MakeSignalHandler(::uiInterface.NotifyBlockTip.connect([fn](SynchronizationState sync_state, const CBlockIndex& block, double verification_progress) {
422 fn(sync_state, BlockTip{block.nHeight, block.GetBlockTime(), block.GetBlockHash()}, verification_progress);
423 }));
424 }
425 std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
426 {
427 return MakeSignalHandler(
428 ::uiInterface.NotifyHeaderTip.connect([fn](SynchronizationState sync_state, int64_t height, int64_t timestamp, bool presync) {
429 fn(sync_state, BlockTip{(int)height, timestamp, uint256{}}, presync);
430 }));
431 }
432 NodeContext* context() override { return m_context; }
433 void setContext(NodeContext* context) override
434 {
436 }
437 ArgsManager& args() { return *Assert(Assert(m_context)->args); }
438 ChainstateManager& chainman() { return *Assert(m_context->chainman); }
439 NodeContext* m_context{nullptr};
440};
441
442// NOLINTNEXTLINE(misc-no-recursion)
443bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<RecursiveMutex>& lock, const CChain& active, const BlockManager& blockman) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
444{
445 if (!index) return false;
446 if (block.m_hash) *block.m_hash = index->GetBlockHash();
447 if (block.m_height) *block.m_height = index->nHeight;
448 if (block.m_time) *block.m_time = index->GetBlockTime();
449 if (block.m_max_time) *block.m_max_time = index->GetBlockTimeMax();
450 if (block.m_mtp_time) *block.m_mtp_time = index->GetMedianTimePast();
451 if (block.m_in_active_chain) *block.m_in_active_chain = active[index->nHeight] == index;
452 if (block.m_locator) { *block.m_locator = GetLocator(index); }
453 if (block.m_next_block) FillBlock(active[index->nHeight] == index ? active[index->nHeight + 1] : nullptr, *block.m_next_block, lock, active, blockman);
454 if (block.m_data) {
455 REVERSE_LOCK(lock, cs_main);
456 if (!blockman.ReadBlock(*block.m_data, *index)) block.m_data->SetNull();
457 }
458 block.found = true;
459 return true;
460}
461
462class NotificationsProxy : public CValidationInterface
463{
464public:
465 explicit NotificationsProxy(std::shared_ptr<Chain::Notifications> notifications)
466 : m_notifications(std::move(notifications)) {}
467 virtual ~NotificationsProxy() = default;
468 void TransactionAddedToMempool(const NewMempoolTransactionInfo& tx, uint64_t mempool_sequence) override
469 {
470 m_notifications->transactionAddedToMempool(tx.info.m_tx);
471 }
472 void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) override
473 {
474 m_notifications->transactionRemovedFromMempool(tx, reason);
475 }
476 void BlockConnected(const ChainstateRole& role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
477 {
478 m_notifications->blockConnected(role, kernel::MakeBlockInfo(index, block.get()));
479 }
480 void BlockDisconnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
481 {
482 m_notifications->blockDisconnected(kernel::MakeBlockInfo(index, block.get()));
483 }
484 void UpdatedBlockTip(const CBlockIndex* index, const CBlockIndex* fork_index, bool is_ibd) override
485 {
486 m_notifications->updatedBlockTip();
487 }
488 void ChainStateFlushed(const ChainstateRole& role, const CBlockLocator& locator) override
489 {
490 m_notifications->chainStateFlushed(role, locator);
491 }
492 std::shared_ptr<Chain::Notifications> m_notifications;
493};
494
495class NotificationsHandlerImpl : public Handler
496{
497public:
498 explicit NotificationsHandlerImpl(ValidationSignals& signals, std::shared_ptr<Chain::Notifications> notifications)
499 : m_signals{signals}, m_proxy{std::make_shared<NotificationsProxy>(std::move(notifications))}
500 {
502 }
503 ~NotificationsHandlerImpl() override { disconnect(); }
504 void disconnect() override
505 {
506 if (m_proxy) {
508 m_proxy.reset();
509 }
510 }
512 std::shared_ptr<NotificationsProxy> m_proxy;
513};
514
515class RpcHandlerImpl : public Handler
516{
517public:
518 explicit RpcHandlerImpl(const CRPCCommand& command) : m_command(command), m_wrapped_command(&command)
519 {
520 m_command.actor = [this](const JSONRPCRequest& request, UniValue& result, bool last_handler) {
521 if (!m_wrapped_command) return false;
522 try {
523 return m_wrapped_command->actor(request, result, last_handler);
524 } catch (const UniValue& e) {
525 // If this is not the last handler and a wallet not found
526 // exception was thrown, return false so the next handler can
527 // try to handle the request. Otherwise, reraise the exception.
528 if (!last_handler) {
529 const UniValue& code = e["code"];
530 if (code.isNum() && code.getInt<int>() == RPC_WALLET_NOT_FOUND) {
531 return false;
532 }
533 }
534 throw;
535 }
536 };
538 }
539
540 void disconnect() final
541 {
542 if (m_wrapped_command) {
543 m_wrapped_command = nullptr;
545 }
546 }
547
548 ~RpcHandlerImpl() override { disconnect(); }
549
552};
553
554class ChainImpl : public Chain
555{
556public:
557 explicit ChainImpl(NodeContext& node) : m_node(node) {}
558 std::optional<int> getHeight() override
559 {
560 const int height{WITH_LOCK(::cs_main, return chainman().ActiveChain().Height())};
561 return height >= 0 ? std::optional{height} : std::nullopt;
562 }
563 uint256 getBlockHash(int height) override
564 {
566 return Assert(chainman().ActiveChain()[height])->GetBlockHash();
567 }
568 bool haveBlockOnDisk(int height) override
569 {
571 const CBlockIndex* block{chainman().ActiveChain()[height]};
572 return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && block->nTx > 0;
573 }
574 std::optional<int> findLocatorFork(const CBlockLocator& locator) override
575 {
577 if (const CBlockIndex* fork = chainman().ActiveChainstate().FindForkInGlobalIndex(locator)) {
578 return fork->nHeight;
579 }
580 return std::nullopt;
581 }
582 bool hasBlockFilterIndex(BlockFilterType filter_type) override
583 {
584 return GetBlockFilterIndex(filter_type) != nullptr;
585 }
586 std::optional<bool> blockFilterMatchesAny(BlockFilterType filter_type, const uint256& block_hash, const GCSFilter::ElementSet& filter_set) override
587 {
588 const BlockFilterIndex* block_filter_index{GetBlockFilterIndex(filter_type)};
589 if (!block_filter_index) return std::nullopt;
590
591 BlockFilter filter;
592 const CBlockIndex* index{WITH_LOCK(::cs_main, return chainman().m_blockman.LookupBlockIndex(block_hash))};
593 if (index == nullptr || !block_filter_index->LookupFilter(index, filter)) return std::nullopt;
594 return filter.GetFilter().MatchAny(filter_set);
595 }
596 bool findBlock(const uint256& hash, const FoundBlock& block) override
597 {
598 WAIT_LOCK(cs_main, lock);
599 return FillBlock(chainman().m_blockman.LookupBlockIndex(hash), block, lock, chainman().ActiveChain(), chainman().m_blockman);
600 }
601 bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override
602 {
603 WAIT_LOCK(cs_main, lock);
604 const CChain& active = chainman().ActiveChain();
605 return FillBlock(active.FindEarliestAtLeast(min_time, min_height), block, lock, active, chainman().m_blockman);
606 }
607 bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out) override
608 {
609 WAIT_LOCK(cs_main, lock);
610 const CChain& active = chainman().ActiveChain();
611 if (const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
612 if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) {
613 return FillBlock(ancestor, ancestor_out, lock, active, chainman().m_blockman);
614 }
615 }
616 return FillBlock(nullptr, ancestor_out, lock, active, chainman().m_blockman);
617 }
618 bool findAncestorByHash(const uint256& block_hash, const uint256& ancestor_hash, const FoundBlock& ancestor_out) override
619 {
620 WAIT_LOCK(cs_main, lock);
621 const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash);
622 const CBlockIndex* ancestor = chainman().m_blockman.LookupBlockIndex(ancestor_hash);
623 if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr;
624 return FillBlock(ancestor, ancestor_out, lock, chainman().ActiveChain(), chainman().m_blockman);
625 }
626 bool findCommonAncestor(const uint256& block_hash1, const uint256& block_hash2, const FoundBlock& ancestor_out, const FoundBlock& block1_out, const FoundBlock& block2_out) override
627 {
628 WAIT_LOCK(cs_main, lock);
629 const CChain& active = chainman().ActiveChain();
630 const CBlockIndex* block1 = chainman().m_blockman.LookupBlockIndex(block_hash1);
631 const CBlockIndex* block2 = chainman().m_blockman.LookupBlockIndex(block_hash2);
632 const CBlockIndex* ancestor = block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr;
633 // Using & instead of && below to avoid short circuiting and leaving
634 // output uninitialized. Cast bool to int to avoid -Wbitwise-instead-of-logical
635 // compiler warnings.
636 return int{FillBlock(ancestor, ancestor_out, lock, active, chainman().m_blockman)} &
637 int{FillBlock(block1, block1_out, lock, active, chainman().m_blockman)} &
638 int{FillBlock(block2, block2_out, lock, active, chainman().m_blockman)};
639 }
640 void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); }
641 double guessVerificationProgress(const uint256& block_hash) override
642 {
643 LOCK(chainman().GetMutex());
644 return chainman().GuessVerificationProgress(chainman().m_blockman.LookupBlockIndex(block_hash));
645 }
646 bool hasBlocks(const uint256& block_hash, int min_height, std::optional<int> max_height) override
647 {
648 // hasBlocks returns true if all ancestors of block_hash in specified
649 // range have block data (are not pruned), false if any ancestors in
650 // specified range are missing data.
651 //
652 // For simplicity and robustness, min_height and max_height are only
653 // used to limit the range, and passing min_height that's too low or
654 // max_height that's too high will not crash or change the result.
656 if (const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
657 if (max_height && block->nHeight >= *max_height) block = block->GetAncestor(*max_height);
658 for (; block->nStatus & BLOCK_HAVE_DATA; block = block->pprev) {
659 // Check pprev to not segfault if min_height is too low
660 if (block->nHeight <= min_height || !block->pprev) return true;
661 }
662 }
663 return false;
664 }
666 {
667 if (!m_node.mempool) return IsRBFOptInEmptyMempool(tx);
668 LOCK(m_node.mempool->cs);
669 return IsRBFOptIn(tx, *m_node.mempool);
670 }
671 bool isInMempool(const Txid& txid) override
672 {
673 if (!m_node.mempool) return false;
674 return m_node.mempool->exists(txid);
675 }
676 bool hasDescendantsInMempool(const Txid& txid) override
677 {
678 if (!m_node.mempool) return false;
679 return m_node.mempool->HasDescendants(txid);
680 }
682 const CAmount& max_tx_fee,
683 const CFeeRate& max_tx_fee_rate,
684 TxBroadcast broadcast_method,
685 std::string& err_string) override
686 {
687 const TransactionError err = BroadcastTransaction(m_node, tx, err_string, max_tx_fee, max_tx_fee_rate, broadcast_method, /*wait_callback=*/false);
688 // Chain clients only care about failures to accept the tx to the mempool. Disregard non-mempool related failures.
689 // Note: this will need to be updated if BroadcastTransactions() is updated to return other non-mempool failures
690 // that Chain clients do not need to know about.
691 return TransactionError::OK == err;
692 }
693 void getTransactionAncestry(const Txid& txid, size_t& ancestors, size_t& cluster_count, size_t* ancestorsize, CAmount* ancestorfees) override
694 {
695 ancestors = cluster_count = 0;
696 if (!m_node.mempool) return;
697 m_node.mempool->GetTransactionAncestry(txid, ancestors, cluster_count, ancestorsize, ancestorfees);
698 }
699
700 std::map<COutPoint, CAmount> calculateIndividualBumpFees(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) override
701 {
702 if (!m_node.mempool) {
703 std::map<COutPoint, CAmount> bump_fees;
704 for (const auto& outpoint : outpoints) {
705 bump_fees.emplace(outpoint, 0);
706 }
707 return bump_fees;
708 }
709 return MiniMiner(*m_node.mempool, outpoints).CalculateBumpFees(target_feerate);
710 }
711
712 std::optional<CAmount> calculateCombinedBumpFee(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) override
713 {
714 if (!m_node.mempool) {
715 return 0;
716 }
717 return MiniMiner(*m_node.mempool, outpoints).CalculateTotalBumpFees(target_feerate);
718 }
719 void getPackageLimits(unsigned int& limit_ancestor_count, unsigned int& limit_descendant_count) override
720 {
721 const CTxMemPool::Limits default_limits{};
722
723 const CTxMemPool::Limits& limits{m_node.mempool ? m_node.mempool->m_opts.limits : default_limits};
724
725 limit_ancestor_count = limits.ancestor_count;
726 limit_descendant_count = limits.descendant_count;
727 }
729 {
730 if (!m_node.mempool) return {};
731 if (!m_node.mempool->CheckPolicyLimits(tx)) {
732 return util::Error{Untranslated("too many unconfirmed transactions in cluster")};
733 }
734 return {};
735 }
736 util::Expected<FeeRateEstimation, FeeRateEstimationError> getFeeRateEstimate(int num_blocks, bool conservative) const override
737 {
738 if (!m_node.fee_estimator_man) return EstimationError(FeeRateEstimatorType::AUTO, /*returned_target=*/0, /*error=*/{});
739 return m_node.fee_estimator_man->GetFeeRateEstimate(num_blocks, conservative);
740 }
741 unsigned int maximumFeeEstimationTargetBlocks() const override
742 {
743 if (!m_node.fee_estimator_man) return 0;
744 return m_node.fee_estimator_man->MaximumTarget();
745 }
746 CFeeRate mempoolMinFee() override
747 {
748 if (!m_node.mempool) return {};
749 return m_node.mempool->GetMinFee();
750 }
751 CFeeRate relayMinFee() override
752 {
753 if (!m_node.mempool) return CFeeRate{DEFAULT_MIN_RELAY_TX_FEE};
754 return m_node.mempool->m_opts.min_relay_feerate;
755 }
757 {
758 if (!m_node.mempool) return CFeeRate{DEFAULT_INCREMENTAL_RELAY_FEE};
759 return m_node.mempool->m_opts.incremental_relay_feerate;
760 }
761 CFeeRate relayDustFee() override
762 {
763 if (!m_node.mempool) return CFeeRate{DUST_RELAY_TX_FEE};
764 return m_node.mempool->m_opts.dust_relay_feerate;
765 }
766 bool havePruned() override
767 {
769 return chainman().m_blockman.m_have_pruned;
770 }
771 std::optional<int> getPruneHeight() override
772 {
773 LOCK(chainman().GetMutex());
774 return GetPruneHeight(chainman().m_blockman, chainman().ActiveChain());
775 }
776 bool isReadyToBroadcast() override { return !chainman().m_blockman.LoadingBlocks() && !isInitialBlockDownload(); }
777 bool isInitialBlockDownload() override
778 {
779 return chainman().IsInitialBlockDownload();
780 }
781 bool shutdownRequested() override { return ShutdownRequested(m_node); }
782 void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }
783 void initWarning(const bilingual_str& message) override { InitWarning(message); }
784 void initError(const bilingual_str& message) override { InitError(message); }
785 void showProgress(const std::string& title, int progress, bool resume_possible) override
786 {
787 ::uiInterface.ShowProgress(title, progress, resume_possible);
788 }
789 std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) override
790 {
791 return std::make_unique<NotificationsHandlerImpl>(validation_signals(), std::move(notifications));
792 }
793 void waitForNotificationsIfTipChanged(const uint256& old_tip) override
794 {
795 if (!old_tip.IsNull() && old_tip == WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()->GetBlockHash())) return;
796 validation_signals().SyncWithValidationInterfaceQueue();
797 }
798 void waitForNotifications() override
799 {
800 validation_signals().SyncWithValidationInterfaceQueue();
801 }
802 std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override
803 {
804 return std::make_unique<RpcHandlerImpl>(command);
805 }
806 bool rpcEnableDeprecated(const std::string& method) override { return IsDeprecatedRPCEnabled(method); }
807 common::SettingsValue getSetting(const std::string& name) override
808 {
809 return args().GetSetting(name);
810 }
811 std::vector<common::SettingsValue> getSettingsList(const std::string& name) override
812 {
813 return args().GetSettingsList(name);
814 }
815 common::SettingsValue getRwSetting(const std::string& name) override
816 {
818 args().LockSettings([&](const common::Settings& settings) {
819 if (const common::SettingsValue* value = common::FindKey(settings.rw_settings, name)) {
820 result = *value;
821 }
822 });
823 return result;
824 }
825 bool updateRwSetting(const std::string& name,
826 const interfaces::SettingsUpdate& update_settings_func) override
827 {
828 std::optional<interfaces::SettingsAction> action;
829 args().LockSettings([&](common::Settings& settings) {
830 if (auto* value = common::FindKey(settings.rw_settings, name)) {
831 action = update_settings_func(*value);
832 if (value->isNull()) settings.rw_settings.erase(name);
833 } else {
834 UniValue new_value;
835 action = update_settings_func(new_value);
836 if (!new_value.isNull()) settings.rw_settings[name] = std::move(new_value);
837 }
838 });
839 if (!action) return false;
840 // Now dump value to disk if requested
842 }
843 bool overwriteRwSetting(const std::string& name, common::SettingsValue value, interfaces::SettingsAction action) override
844 {
845 return updateRwSetting(name, [&](common::SettingsValue& settings) {
846 settings = std::move(value);
847 return action;
848 });
849 }
850 bool deleteRwSettings(const std::string& name, interfaces::SettingsAction action) override
851 {
852 return overwriteRwSetting(name, {}, action);
853 }
854 void requestMempoolTransactions(Notifications& notifications) override
855 {
856 if (!m_node.mempool) return;
857 LOCK2(::cs_main, m_node.mempool->cs);
858 for (const CTxMemPoolEntry& entry : m_node.mempool->entryAll()) {
859 notifications.transactionAddedToMempool(entry.GetSharedTx());
860 }
861 }
862 bool hasAssumedValidChain() override
863 {
865 return bool{chainman().CurrentChainstate().m_from_snapshot_blockhash};
866 }
867
868 NodeContext* context() override { return &m_node; }
869 ArgsManager& args() { return *Assert(m_node.args); }
870 ChainstateManager& chainman() { return *Assert(m_node.chainman); }
871 ValidationSignals& validation_signals() { return *Assert(m_node.validation_signals); }
872 NodeContext& m_node;
873};
874
875class BlockTemplateImpl : public BlockTemplate
876{
877public:
878 explicit BlockTemplateImpl(BlockCreateOptions create_options,
879 std::unique_ptr<CBlockTemplate> block_template,
880 const NodeContext& node) : m_create_options(std::move(create_options)),
881 m_block_template(std::move(block_template)),
882 m_node(node)
883 {
885 }
886
888 {
889 return m_block_template->block;
890 }
891
892 CBlock getBlock() override
893 {
894 return m_block_template->block;
895 }
896
897 std::vector<CAmount> getTxFees() override
898 {
899 return m_block_template->vTxFees;
900 }
901
902 std::vector<int64_t> getTxSigops() override
903 {
904 return m_block_template->vTxSigOpsCost;
905 }
906
907 CoinbaseTx getCoinbaseTx() override
908 {
909 return m_block_template->m_coinbase_tx;
910 }
911
912 std::vector<uint256> getCoinbaseMerklePath() override
913 {
914 return TransactionMerklePath(m_block_template->block, 0);
915 }
916
917 bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CTransactionRef coinbase, std::string& reason, std::string& debug) override
918 {
919 if (!coinbase) return false;
920 AddMerkleRootAndCoinbase(m_block_template->block, std::move(coinbase), version, timestamp, nonce);
921 return block_template_manager().SubmitBlock(std::make_shared<const CBlock>(m_block_template->block), reason, debug);
922 }
923
924 std::unique_ptr<BlockTemplate> waitNext(BlockWaitOptions options) override
925 {
926 auto new_template = block_template_manager().WaitAndCreateNewBlock(
928 if (new_template) return std::make_unique<BlockTemplateImpl>(m_create_options, std::move(new_template), m_node);
929 return nullptr;
930 }
931
932 void interruptWait() override
933 {
934 block_template_manager().InterruptWait(m_interrupt_wait);
935 }
936
938
939 const std::unique_ptr<CBlockTemplate> m_block_template;
940
941 bool m_interrupt_wait{false};
942 node::BlockTemplateManager& block_template_manager() { return *Assert(m_node.block_template_manager); }
943 const NodeContext& m_node;
944};
945
946class MinerImpl : public Mining
947{
948public:
949 explicit MinerImpl(const NodeContext& node) : m_node(node) {}
950
951 bool isTestChain() override
952 {
953 return chainman().GetParams().IsTestChain();
954 }
955
956 bool isInitialBlockDownload() override
957 {
958 return chainman().IsInitialBlockDownload();
959 }
960
961 std::optional<BlockRef> getTip() override
962 {
963 return block_template_manager().GetTip();
964 }
965
966 std::optional<BlockRef> waitTipChanged(uint256 current_tip, MillisecondsDouble timeout) override
967 {
968 return block_template_manager().WaitTipChanged(current_tip, timeout, m_interrupt_mining);
969 }
970
971 std::unique_ptr<BlockTemplate> createNewBlock(const BlockCreateOptions& options, bool cooldown) override
972 {
973 // Ensure m_tip_block is set so consumers of BlockTemplate can rely on that.
974 std::optional<BlockRef> maybe_tip{waitTipChanged(uint256::ZERO, MillisecondsDouble::max())};
975
976 if (!maybe_tip) return {};
977
978 if (cooldown) {
979 // Do not return a template during IBD, because it can have long
980 // pauses and sometimes takes a while to get started. Although this
981 // is useful in general, it's gated behind the cooldown argument,
982 // because on regtest and single miner signets this would wait
983 // forever if no block was mined in the past day.
984 while (chainman().IsInitialBlockDownload()) {
985 maybe_tip = waitTipChanged(maybe_tip->hash, MillisecondsDouble{1000});
986 if (!maybe_tip || chainman().m_interrupt || WITH_LOCK(notifications().m_tip_block_mutex, return m_interrupt_mining)) return {};
987 }
988
989 // Also wait during the final catch-up moments after IBD.
990 if (!block_template_manager().CooldownIfHeadersAhead(*maybe_tip, m_interrupt_mining)) return {};
991 }
992 auto new_template = block_template_manager().CreateNewTemplate(options);
993 return std::make_unique<BlockTemplateImpl>(options, std::move(new_template), m_node);
994 }
995
996 void interrupt() override
997 {
998 block_template_manager().InterruptWait(m_interrupt_mining);
999 }
1000
1001 bool checkBlock(const CBlock& block, const node::BlockCheckOptions& options, std::string& reason, std::string& debug) override
1002 {
1003 LOCK(chainman().GetMutex());
1004 BlockValidationState state{TestBlockValidity(chainman().ActiveChainstate(), block, /*check_pow=*/options.check_pow, /*check_merkle_root=*/options.check_merkle_root)};
1005 reason = state.GetRejectReason();
1006 debug = state.GetDebugMessage();
1007 return state.IsValid();
1008 }
1009
1010 bool submitBlock(const CBlock& block_in, std::string& reason, std::string& debug) override
1011 {
1012 return block_template_manager().SubmitBlock(std::make_shared<const CBlock>(block_in), reason, debug);
1013 }
1014
1015 std::vector<CTransactionRef> getTransactionsByTxID(const std::vector<Txid>& txids) override
1016 {
1017 if (!m_node.mempool) return {};
1018
1019 std::vector<CTransactionRef> results;
1020 results.reserve(txids.size());
1021 LOCK(m_node.mempool->cs);
1022 for (const auto& txid : txids) {
1023 results.emplace_back(m_node.mempool->get(txid));
1024 }
1025 return results;
1026 }
1027
1028 std::vector<CTransactionRef> getTransactionsByWitnessID(const std::vector<Wtxid>& wtxids) override
1029 {
1030 if (!m_node.mempool) return {};
1031
1032 std::vector<CTransactionRef> results;
1033 results.reserve(wtxids.size());
1034 LOCK(m_node.mempool->cs);
1035 for (const auto& wtxid : wtxids) {
1036 results.emplace_back(m_node.mempool->get(wtxid));
1037 }
1038 return results;
1039 }
1040
1041 const NodeContext* context() override { return &m_node; }
1042 ChainstateManager& chainman() { return *Assert(m_node.chainman); }
1043 KernelNotifications& notifications() { return *Assert(m_node.notifications); }
1044 node::BlockTemplateManager& block_template_manager() { return *Assert(m_node.block_template_manager); }
1045 // Treat as if guarded by notifications().m_tip_block_mutex
1047 const NodeContext& m_node;
1048};
1049
1050class RpcImpl : public Rpc
1051{
1052public:
1053 explicit RpcImpl(NodeContext& node) : m_node(node) {}
1054
1055 UniValue executeRpc(UniValue request, std::string uri, std::string user) override
1056 {
1057 JSONRPCRequest req;
1058 req.context = &m_node;
1059 req.URI = std::move(uri);
1060 req.authUser = std::move(user);
1061 HTTPStatusCode status;
1062 return ExecuteHTTPRPC(request, req, status);
1063 }
1064
1065 NodeContext& m_node;
1066};
1067} // namespace
1068} // namespace node
1069
1070namespace interfaces {
1071std::unique_ptr<Node> MakeNode(node::NodeContext& context) { return std::make_unique<node::NodeImpl>(context); }
1072std::unique_ptr<Chain> MakeChain(node::NodeContext& context) { return std::make_unique<node::ChainImpl>(context); }
1073std::unique_ptr<Mining> MakeMining(const node::NodeContext& context, bool wait_loaded)
1074{
1075 if (wait_loaded) {
1076 node::KernelNotifications& kernel_notifications(*Assert(context.notifications));
1077 util::SignalInterrupt& interrupt(*Assert(context.shutdown_signal));
1078 WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock);
1079 kernel_notifications.m_tip_block_cv.wait(lock, [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) {
1080 return kernel_notifications.m_state.chainstate_loaded || interrupt;
1081 });
1082 if (interrupt) return nullptr;
1083 }
1084 return std::make_unique<node::MinerImpl>(context);
1085}
1086std::unique_ptr<Rpc> MakeRpc(node::NodeContext& context) { return std::make_unique<node::RpcImpl>(context); }
1087} // namespace interfaces
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
int flags
Definition: bitcoin-tx.cpp:531
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:922
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:976
common::SettingsValue GetSetting(const std::string &arg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Get setting value.
Definition: args.cpp:970
bool GetSettingsPath(fs::path *filepath=nullptr, bool temp=false, bool backup=false) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Get settings file path, or return false if read-write settings were disabled with -nosettings.
Definition: args.cpp:436
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:485
void LockSettings(Fn &&fn) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
Access settings with lock held.
Definition: args.h:442
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:505
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:517
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:30
std::string name
Definition: server.h:69
Actor actor
Definition: server.h:70
bool removeCommand(const std::string &name, const CRPCCommand *pcmd)
Definition: server.cpp:634
std::vector< std::string > listCommands() const
Returns a list of registered commands.
Definition: server.cpp:896
UniValue execute(const JSONRPCRequest &request) const
Execute a method.
Definition: server.cpp:859
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Definition: server.cpp:627
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:287
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:950
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:59
std::string strMethod
Definition: request.h:58
std::string URI
Definition: request.h:61
std::string authUser
Definition: request.h:62
std::any context
Definition: request.h:64
bool isNull() const
Definition: univalue.h:81
Int getInt() const
Definition: univalue.h:143
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:116
constexpr bool IsNull() const
Definition: uint256.h:50
Block template interface.
Definition: mining.h:31
virtual std::vector< int64_t > getTxSigops()=0
virtual bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CTransactionRef coinbase, std::string &reason, std::string &debug)=0
Construct and broadcast the block.
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 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:117
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 util::Expected< FeeRateEstimation, FeeRateEstimationError > getFeeRateEstimate(int num_blocks, bool conservative) const =0
Estimate a fee rate.
virtual bool broadcastTransaction(const CTransactionRef &tx, const CAmount &max_tx_fee, const CFeeRate &max_tx_fee_rate, 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 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:396
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 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 unsigned int maximumFeeEstimationTargetBlocks() const =0
Fee estimator max target.
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 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:56
Helper for findBlock to selectively return pieces of block data.
Definition: chain.h:52
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:108
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:209
virtual std::vector< CTransactionRef > getTransactionsByTxID(const std::vector< Txid > &txids)=0
Fetch raw transactions from the mempool by txid.
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::vector< CTransactionRef > getTransactionsByWitnessID(const std::vector< Wtxid > &wtxids)=0
Fetch raw transactions from the mempool by wtxid.
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:66
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:325
Creates block templates, submits solved blocks, and provides tip-waiting helpers for mining code.
256-bit opaque blob.
Definition: uint256.h:196
static const uint256 ZERO
Definition: uint256.h:204
The util::Expected class provides a standard way for low-level functions to return either error value...
Definition: expected.h:44
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:182
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:103
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:884
bool AppInitBasicSetup(const ArgsManager &args, std::atomic< int > &exit_status)
Initialize bitcoin core: Basic context setup.
Definition: init.cpp:913
bool ShutdownRequested(node::NodeContext &node)
Return whether node shutdown was requested.
Definition: init.cpp:269
bool AppInitParameterInteraction(const ArgsManager &args)
Initialization: parameter interaction.
Definition: init.cpp:950
bool AppInitInterfaces(NodeContext &node)
Initialize node and wallet interface pointers.
Definition: init.cpp:1274
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:795
bool AppInitMain(NodeContext &node, interfaces::BlockAndHeaderTipInfo *tip_info)
Bitcoin core main initialization.
Definition: init.cpp:1490
bool AppInitLockDirectories()
Lock bitcoin core critical directories.
Definition: init.cpp:1262
bool AppInitSanityChecks(const kernel::Context &kernel)
Initialization sanity checks.
Definition: init.cpp:1243
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:27
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:109
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:48
SettingsAction
The action to be taken after updating a settings value.
Definition: chain.h:85
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:90
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
TransactionError BroadcastTransaction(NodeContext &node, const CTransactionRef tx, std::string &err_string, const CAmount &max_tx_fee, const CFeeRate &max_tx_fee_rate, TxBroadcast broadcast_method, bool wait_callback)
Submit a transaction to the mempool and (optionally) relay it to all P2P peers.
Definition: transaction.cpp:34
TxBroadcast
How to broadcast a local transaction.
Definition: types.h:36
@ 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
void AddMerkleRootAndCoinbase(CBlock &block, CTransactionRef coinbase, uint32_t version, uint32_t timestamp, uint32_t nonce)
Definition: miner.cpp:349
auto Join(const C &container, const S &separator, UnaryOp unary_op)
Join all container items.
Definition: string.h:209
int64_t NodeId
Definition: net.h:105
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:511
::ExternalSigner m_signer
Definition: interfaces.cpp:115
bool m_interrupt_mining
NodeContext & m_node
Definition: interfaces.cpp:872
NodeContext * m_context
Definition: interfaces.cpp:439
std::shared_ptr< Chain::Notifications > m_notifications
Definition: interfaces.cpp:492
CRPCCommand m_command
Definition: interfaces.cpp:550
const BlockCreateOptions m_create_options
Definition: interfaces.cpp:937
bool m_interrupt_wait
Definition: interfaces.cpp:941
const CRPCCommand * m_wrapped_command
Definition: interfaces.cpp:551
const std::unique_ptr< CBlockTemplate > m_block_template
Definition: interfaces.cpp:939
std::shared_ptr< NotificationsProxy > m_proxy
Definition: interfaces.cpp:512
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
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
constexpr unsigned int DUST_RELAY_TX_FEE
Min feerate for defining dust.
Definition: policy.h:68
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:417
const char * name
Definition: rest.cpp:71
HTTPStatusCode
HTTP status codes.
Definition: protocol.h:13
@ RPC_WALLET_NOT_FOUND
Invalid wallet specified.
Definition: protocol.h:106
bool IsDeprecatedRPCEnabled(const std::string &method)
Definition: server.cpp:716
CRPCTable tableRPC
Definition: server.cpp:1003
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:34
std::map< std::string, SettingsValue > rw_settings
Map of setting name to read-write file setting value.
Definition: settings.h:40
std::map< std::string, std::vector< SettingsValue > > command_line_options
Map of setting name to list of command line values.
Definition: settings.h:38
Block and header tip information.
Definition: node.h:46
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:270
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:57
std::unique_ptr< ChainstateManager > chainman
Definition: context.h:74
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
util::Unexpected< FeeRateEstimationError > EstimationError(FeeRateEstimatorType estimator, int returned_target, std::string error)
Build a fee rate estimation error result: a zero-value estimation identifying the estimator and targe...
Definition: fees.h:79
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:96
WalletContext context