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