8#include <chainparams.h>
39#include <validation.h>
43#if defined(HAVE_CONFIG_H)
44#include <config/bitcoin-config.h>
49#include <boost/signals2/signal.hpp>
67 class NodeImpl :
public Node {
72 explicit NodeImpl(NodeContext *context) { setContext(context); }
74 void initParameterInteraction()
override {
78 bool baseInitialize(
Config &config)
override {
86 m_context->kernel = std::make_unique<kernel::Context>();
103 return AppInitMain(config, rpcServer, httpRPCRequestProcessor,
106 void appShutdown()
override {
110 void startShutdown()
override {
120 bool isPersistentSettingIgnored(
const std::string &
name)
override {
121 bool ignored =
false;
125 ignored = !options->empty();
131 getPersistentSetting(
const std::string &
name)
override {
134 void updateRwSetting(
const std::string &
name,
138 settings.rw_settings.erase(name);
140 settings.rw_settings[name] = value;
145 void forceSetting(
const std::string &
name,
149 settings.forced_settings.erase(name);
151 settings.forced_settings[name] = value;
155 void resetSettings()
override {
162 void mapPort(
bool use_upnp,
bool use_natpmp)
override {
172 bool getNodesStats(NodesStats &stats)
override {
176 std::vector<CNodeStats> stats_temp;
177 m_context->connman->GetNodeStats(stats_temp);
179 stats.reserve(stats_temp.size());
180 for (
auto &node_stats_temp : stats_temp) {
181 stats.emplace_back(std::move(node_stats_temp),
false,
189 for (
auto &node_stats : stats) {
190 std::get<1>(node_stats) =
192 std::get<0>(node_stats).nodeid,
193 std::get<2>(node_stats));
201 bool getBanned(
banmap_t &banmap)
override {
208 bool ban(
const CNetAddr &net_addr, int64_t ban_time_offset)
override {
210 m_context->banman->Ban(net_addr, ban_time_offset);
215 bool unban(
const CSubNet &ip)
override {
222 bool disconnectByAddress(
const CNetAddr &net_addr)
override {
224 return m_context->connman->DisconnectNode(net_addr);
228 bool disconnectById(
NodeId id)
override {
230 return m_context->connman->DisconnectNode(
id);
234 int64_t getTotalBytesRecv()
override {
238 int64_t getTotalBytesSent()
override {
242 size_t getMempoolSize()
override {
245 size_t getMempoolDynamicUsage()
override {
249 bool getHeaderTip(
int &height, int64_t &block_time)
override {
251 auto best_header = chainman().m_best_header;
253 height = best_header->nHeight;
254 block_time = best_header->GetBlockTime();
259 int getNumBlocks()
override {
261 return chainman().ActiveChain().Height();
267 : chainman().GetParams().GenesisBlock().GetHash();
269 int64_t getLastBlockTime()
override {
271 if (chainman().ActiveChain().Tip()) {
272 return chainman().ActiveChain().Tip()->GetBlockTime();
275 return chainman().GetParams().GenesisBlock().GetBlockTime();
277 double getVerificationProgress()
override {
281 tip = chainman().ActiveChain().Tip();
286 bool isInitialBlockDownload()
override {
287 return chainman().IsInitialBlockDownload();
289 bool isLoadingBlocks()
override {
290 return chainman().m_blockman.LoadingBlocks();
292 void setNetworkActive(
bool active)
override {
294 m_context->connman->SetNetworkActive(active);
297 bool getNetworkActive()
override {
300 CFeeRate getDustRelayFee()
override {
304 return m_context->mempool->m_dust_relay_feerate;
306 UniValue executeRpc(
const Config &config,
const std::string &command,
308 const std::string &uri)
override {
316 std::vector<std::string> listRpcCommands()
override {
325 bool getUnspentOutput(
const COutPoint &output,
Coin &coin)
override {
327 return chainman().ActiveChainstate().CoinsTip().GetCoin(output,
333 std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn)
override {
336 std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn)
override {
339 std::unique_ptr<Handler> handleQuestion(QuestionFn fn)
override {
342 std::unique_ptr<Handler>
343 handleShowProgress(ShowProgressFn fn)
override {
346 std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(
347 NotifyNumConnectionsChangedFn fn)
override {
351 std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(
352 NotifyNetworkActiveChangedFn fn)
override {
356 std::unique_ptr<Handler>
357 handleNotifyAlertChanged(NotifyAlertChangedFn fn)
override {
360 std::unique_ptr<Handler>
361 handleBannedListChanged(BannedListChangedFn fn)
override {
364 std::unique_ptr<Handler>
365 handleNotifyBlockTip(NotifyBlockTipFn fn)
override {
375 std::unique_ptr<Handler>
376 handleNotifyHeaderTip(NotifyHeaderTipFn fn)
override {
380 int64_t timestamp,
bool presync) {
385 NodeContext *context()
override {
return m_context; }
386 void setContext(NodeContext *context)
override {
m_context = context; }
392 const BlockManager &blockman) {
418 FillBlock(active[index->
nHeight] == index
425 if (!blockman.ReadBlockFromDisk(*block.
m_data, *index)) {
434 explicit NotificationsProxy(
435 std::shared_ptr<Chain::Notifications> notifications)
437 virtual ~NotificationsProxy() =
default;
439 std::shared_ptr<
const std::vector<Coin>>,
440 uint64_t mempool_sequence)
override {
445 uint64_t mempool_sequence)
override {
450 const std::shared_ptr<const CBlock> &block,
454 void BlockDisconnected(
const std::shared_ptr<const CBlock> &block,
460 bool is_ibd)
override {
470 class NotificationsHandlerImpl :
public Handler {
472 explicit NotificationsHandlerImpl(
473 std::shared_ptr<Chain::Notifications> notifications)
474 :
m_proxy(std::make_shared<NotificationsProxy>(
475 std::move(notifications))) {
478 ~NotificationsHandlerImpl()
override { disconnect(); }
479 void disconnect()
override {
488 class RpcHandlerImpl :
public Handler {
490 explicit RpcHandlerImpl(
const CRPCCommand &command)
494 UniValue &result,
bool last_handler) {
519 void disconnect() final {
526 ~RpcHandlerImpl()
override { disconnect(); }
532 class ChainImpl :
public Chain {
539 std::optional<int> getHeight()
override {
542 int height = active.
Height();
548 BlockHash getBlockHash(
int height)
override {
555 bool haveBlockOnDisk(
int height)
override {
559 return block && (block->nStatus.hasData() != 0) && block->
nTx > 0;
574 return fork->nHeight;
582 return FillBlock(
m_node.chainman->m_blockman.LookupBlockIndex(hash),
583 block, lock, active, chainman().m_blockman);
585 bool findFirstBlockWithTimeAndHeight(int64_t min_time,
int min_height,
590 block, lock, active, chainman().m_blockman);
592 bool findAncestorByHeight(
const BlockHash &block_hash,
598 m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
600 block->GetAncestor(ancestor_height)) {
601 return FillBlock(ancestor, ancestor_out, lock, active,
602 chainman().m_blockman);
605 return FillBlock(
nullptr, ancestor_out, lock, active,
606 chainman().m_blockman);
608 bool findAncestorByHash(
const BlockHash &block_hash,
614 m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
616 m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
617 if (block && ancestor &&
621 return FillBlock(ancestor, ancestor_out, lock, active,
622 chainman().m_blockman);
624 bool findCommonAncestor(
const BlockHash &block_hash1,
632 m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
634 m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
640 return int{FillBlock(ancestor, ancestor_out, lock, active,
641 chainman().m_blockman)} &
642 int{FillBlock(block1, block1_out, lock, active,
643 chainman().m_blockman)} &
644 int{FillBlock(block2, block2_out, lock, active,
645 chainman().m_blockman)};
647 void findCoins(std::map<COutPoint, Coin> &coins)
override {
650 double guessVerificationProgress(
const BlockHash &block_hash)
override {
653 chainman().GetParams().TxData(),
654 chainman().m_blockman.LookupBlockIndex(block_hash));
656 bool hasBlocks(
const BlockHash &block_hash,
int min_height,
657 std::optional<int> max_height)
override {
667 chainman().m_blockman.LookupBlockIndex(block_hash)) {
668 if (max_height && block->
nHeight >= *max_height) {
671 for (; block->nStatus.hasData(); block = block->
pprev) {
680 bool broadcastTransaction(
const Config &config,
682 const Amount &max_tx_fee,
bool relay,
683 std::string &err_string)
override {
694 CFeeRate estimateFee()
const override {
698 return m_node.mempool->estimateFee();
704 return m_node.mempool->m_min_relay_feerate;
710 return m_node.mempool->m_dust_relay_feerate;
712 bool havePruned()
override {
714 return m_node.chainman->m_blockman.m_have_pruned;
716 bool isReadyToBroadcast()
override {
717 return !chainman().m_blockman.LoadingBlocks() &&
718 !isInitialBlockDownload();
720 std::optional<int> getPruneHeight()
override {
721 LOCK(chainman().GetMutex());
723 chainman().ActiveChain());
725 bool isInitialBlockDownload()
override {
726 return chainman().IsInitialBlockDownload();
729 void initMessage(
const std::string &message)
override {
738 void showProgress(
const std::string &title,
int progress,
739 bool resume_possible)
override {
740 ::uiInterface.ShowProgress(title, progress, resume_possible);
742 std::unique_ptr<Handler> handleNotifications(
743 std::shared_ptr<Notifications> notifications)
override {
744 return std::make_unique<NotificationsHandlerImpl>(
745 std::move(notifications));
748 waitForNotificationsIfTipChanged(
const BlockHash &old_tip)
override {
759 std::unique_ptr<Handler>
761 return std::make_unique<RpcHandlerImpl>(command);
763 bool rpcEnableDeprecated(
const std::string &method)
override {
766 void rpcRunLater(
const std::string &
name, std::function<
void()> fn,
767 int64_t seconds)
override {
774 std::vector<util::SettingsValue>
775 getSettingsList(
const std::string &
name)
override {
788 bool updateRwSetting(
const std::string &
name,
790 bool write)
override {
793 settings.rw_settings.erase(name);
795 settings.rw_settings[name] = value;
800 void requestMempoolTransactions(Notifications ¬ifications)
override {
806 notifications.transactionAddedToMempool(entry->GetSharedTx(),
810 bool hasAssumedValidChain()
override {
814 NodeContext *context()
override {
return &
m_node; }
823 return std::make_unique<node::NodeImpl>(context);
827 return std::make_unique<node::ChainImpl>(
node, params);
std::optional< int > GetPruneHeight(const BlockManager &blockman, const CChain &chain)
CBlockLocator GetLocator(const CBlockIndex *index)
Get a locator for a block index entry.
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the last common ancestor two blocks have.
const CChainParams & Params()
Return the currently selected parameters.
#define Assert(val)
Identity function.
util::SettingsValue GetPersistentSetting(const std::string &name) const
Get current setting from config file or read/write settings file, ignoring nonpersistent command line...
void LockSettings(Fn &&fn)
Access settings with lock held.
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr, bool backup=false) const
Write settings file or backup settings file.
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
util::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
The block chain is a tree shaped structure starting with the genesis block at the root,...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
int64_t GetBlockTime() const
int64_t GetMedianTimePast() const
int64_t GetBlockTimeMax() const
unsigned int nTx
Number of transactions in this block.
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
BlockHash GetBlockHash() const
int nHeight
height of the entry in the chain. The genesis block has height 0
An in-memory indexed chain of blocks.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
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...
int Height() const
Return the maximal height in the chain.
CBlockLocator GetLocator() const
Return a CBlockLocator that refers to the tip of this chain.
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Fee rate in satoshis per kilobyte: Amount / kB.
bool removeCommand(const std::string &name, const CRPCCommand *pcmd)
std::vector< std::string > listCommands() const
Returns a list of registered commands.
UniValue execute(const Config &config, const JSONRPCRequest &request) const
Execute a method.
void appendCommand(const std::string &name, const CRPCCommand *pcmd)
Appends a CRPCCommand to the dispatch table.
Implement this to subscribe to events generated in validation.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
void ClearBlockIndexCandidates() EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex * FindForkInGlobalIndex(const CBlockLocator &locator) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Find the last common block of this chain and a locator.
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Class for registering and managing all RPC calls.
Wrapper around std::unique_lock style lock for Mutex.
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Helper for findBlock to selectively return pieces of block data.
const FoundBlock * m_next_block
CBlockLocator * m_locator
Generic interface for managing an event handler or callback function registered with another interfac...
Top-level interface for a bitcoin node (bitcoind process).
Wallet chain client that in addition to having chain client methods for starting up,...
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
void Interrupt(NodeContext &node)
Interrupt threads.
void InitLogging(const ArgsManager &args)
Initialize global loggers.
bool AppInitLockDataDirectory()
Lock bitcoin data directory.
void Shutdown(NodeContext &node)
bool AppInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, NodeContext &node, interfaces::BlockAndHeaderTipInfo *tip_info)
Bitcoin main initialization.
bool AppInitBasicSetup(const ArgsManager &args)
Initialize bitcoin: Basic context setup.
bool AppInitInterfaces(NodeContext &node)
Initialize node and wallet interface pointers.
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
bool AppInitParameterInteraction(Config &config, const ArgsManager &args)
Initialization: parameter interaction.
bool AppInitSanityChecks(const kernel::Context &kernel)
Initialization sanity checks.
ChainstateRole
This enum describes the various roles a specific Chainstate instance can take.
void StartMapPort(bool use_upnp, bool use_natpmp)
std::unique_ptr< Handler > MakeHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
std::unique_ptr< Node > MakeNode(node::NodeContext *context)
Return implementation of Node interface.
std::unique_ptr< Chain > MakeChain(node::NodeContext &node, const CChainParams ¶ms)
Return implementation of Chain interface.
TransactionError BroadcastTransaction(const NodeContext &node, const CTransactionRef tx, std::string &err_string, const Amount max_tx_fee, bool relay, bool wait_callback)
Submit a transaction to the mempool and (optionally) relay it to all P2P peers.
void FindCoins(const NodeContext &node, std::map< COutPoint, Coin > &coins)
Look up unspent output information.
Implement std::hash so RCUPtr can be used as a key for maps or sets.
auto FindKey(Map &&map, Key &&key) -> decltype(&map.at(key))
Map lookup helper.
std::map< CSubNet, CBanEntry > banmap_t
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
std::shared_ptr< Chain::Notifications > m_notifications
const CChainParams & m_params
const CRPCCommand * m_wrapped_command
std::shared_ptr< NotificationsProxy > m_proxy
static constexpr Amount DUST_RELAY_TX_FEE(1000 *SATOSHI)
Min feerate for defining dust.
static constexpr Amount DEFAULT_MIN_RELAY_TX_FEE_PER_KB(1000 *SATOSHI)
Default for -minrelaytxfee, minimum relay fee for transactions.
std::shared_ptr< const CTransaction > CTransactionRef
@ RPC_WALLET_NOT_FOUND
Invalid wallet specified.
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
Set the factory function for timer, but only, if unset.
bool IsDeprecatedRPCEnabled(const ArgsManager &args, const std::string &method)
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
Unset factory function for timers.
void RPCRunLater(const std::string &name, std::function< void()> func, int64_t nSeconds)
Run func nSeconds from now.
int RPCSerializationFlags()
Retrieves any serialization flags requested in command line argument.
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
void StartShutdown()
Request shutdown of the application.
A BlockHash is a unqiue identifier for a block.
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Block and header tip information.
Block tip (could be a header or not, depends on the subscribed signal).
NodeContext struct containing references to chain state and connection state.
std::map< std::string, SettingsValue > rw_settings
Map of setting name to read-write file setting value.
std::map< std::string, std::vector< SettingsValue > > command_line_options
Map of setting name to list of command line values.
#define WAIT_LOCK(cs, name)
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
#define TRY_LOCK(cs, name)
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
CClientUIInterface uiInterface
void InitWarning(const bilingual_str &str)
Show warning message.
bool InitError(const bilingual_str &str)
Show error message.
double GuessVerificationProgress(const ChainTxData &data, const CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index require cs_main if pindex h...
SynchronizationState
Current sync state passed to tip changed callbacks.
void UnregisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Unregister subscriber.
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
void RegisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Register subscriber.
bilingual_str GetWarnings(bool verbose)
Format a string that describes several potential problems detected by the core.