8#include <chainparams.h>
38#include <validation.h>
42#if defined(HAVE_CONFIG_H)
43#include <config/bitcoin-config.h>
48#include <boost/signals2/signal.hpp>
66 class NodeImpl :
public Node {
71 explicit NodeImpl(NodeContext *context) { setContext(context); }
73 void initParameterInteraction()
override {
77 bool baseInitialize(
Config &config)
override {
86 return AppInitMain(config, rpcServer, httpRPCRequestProcessor,
89 void appShutdown()
override {
93 void startShutdown()
override {
103 bool isPersistentSettingIgnored(
const std::string &
name)
override {
104 bool ignored =
false;
108 ignored = !options->empty();
114 getPersistentSetting(
const std::string &
name)
override {
117 void updateRwSetting(
const std::string &
name,
121 settings.rw_settings.erase(name);
123 settings.rw_settings[name] = value;
128 void forceSetting(
const std::string &
name,
132 settings.forced_settings.erase(name);
134 settings.forced_settings[name] = value;
138 void resetSettings()
override {
145 void mapPort(
bool use_upnp,
bool use_natpmp)
override {
155 bool getNodesStats(NodesStats &stats)
override {
159 std::vector<CNodeStats> stats_temp;
160 m_context->connman->GetNodeStats(stats_temp);
162 stats.reserve(stats_temp.size());
163 for (
auto &node_stats_temp : stats_temp) {
164 stats.emplace_back(std::move(node_stats_temp),
false,
172 for (
auto &node_stats : stats) {
173 std::get<1>(node_stats) =
175 std::get<0>(node_stats).nodeid,
176 std::get<2>(node_stats));
184 bool getBanned(
banmap_t &banmap)
override {
191 bool ban(
const CNetAddr &net_addr, int64_t ban_time_offset)
override {
193 m_context->banman->Ban(net_addr, ban_time_offset);
198 bool unban(
const CSubNet &ip)
override {
205 bool disconnectByAddress(
const CNetAddr &net_addr)
override {
207 return m_context->connman->DisconnectNode(net_addr);
211 bool disconnectById(
NodeId id)
override {
213 return m_context->connman->DisconnectNode(
id);
217 int64_t getTotalBytesRecv()
override {
221 int64_t getTotalBytesSent()
override {
225 size_t getMempoolSize()
override {
228 size_t getMempoolDynamicUsage()
override {
232 bool getHeaderTip(
int &height, int64_t &block_time)
override {
234 auto best_header = chainman().m_best_header;
236 height = best_header->nHeight;
237 block_time = best_header->GetBlockTime();
242 int getNumBlocks()
override {
244 return chainman().ActiveChain().Height();
250 : chainman().GetParams().GenesisBlock().GetHash();
252 int64_t getLastBlockTime()
override {
254 if (chainman().ActiveChain().Tip()) {
255 return chainman().ActiveChain().Tip()->GetBlockTime();
258 return chainman().GetParams().GenesisBlock().GetBlockTime();
260 double getVerificationProgress()
override {
264 tip = chainman().ActiveChain().Tip();
269 bool isInitialBlockDownload()
override {
270 return chainman().ActiveChainstate().IsInitialBlockDownload();
272 bool isLoadingBlocks()
override {
273 return chainman().m_blockman.LoadingBlocks();
275 void setNetworkActive(
bool active)
override {
277 m_context->connman->SetNetworkActive(active);
280 bool getNetworkActive()
override {
283 CFeeRate getDustRelayFee()
override {
287 return m_context->mempool->m_dust_relay_feerate;
289 UniValue executeRpc(
const Config &config,
const std::string &command,
291 const std::string &uri)
override {
299 std::vector<std::string> listRpcCommands()
override {
308 bool getUnspentOutput(
const COutPoint &output,
Coin &coin)
override {
310 return chainman().ActiveChainstate().CoinsTip().GetCoin(output,
316 std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn)
override {
319 std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn)
override {
322 std::unique_ptr<Handler> handleQuestion(QuestionFn fn)
override {
325 std::unique_ptr<Handler>
326 handleShowProgress(ShowProgressFn fn)
override {
329 std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(
330 NotifyNumConnectionsChangedFn fn)
override {
334 std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(
335 NotifyNetworkActiveChangedFn fn)
override {
339 std::unique_ptr<Handler>
340 handleNotifyAlertChanged(NotifyAlertChangedFn fn)
override {
343 std::unique_ptr<Handler>
344 handleBannedListChanged(BannedListChangedFn fn)
override {
347 std::unique_ptr<Handler>
348 handleNotifyBlockTip(NotifyBlockTipFn fn)
override {
358 std::unique_ptr<Handler>
359 handleNotifyHeaderTip(NotifyHeaderTipFn fn)
override {
363 int64_t timestamp,
bool presync) {
368 NodeContext *context()
override {
return m_context; }
369 void setContext(NodeContext *context)
override {
m_context = context; }
375 const BlockManager &blockman) {
399 FillBlock(active[index->
nHeight] == index
406 if (!blockman.ReadBlockFromDisk(*block.
m_data, *index)) {
415 explicit NotificationsProxy(
416 std::shared_ptr<Chain::Notifications> notifications)
418 virtual ~NotificationsProxy() =
default;
420 std::shared_ptr<
const std::vector<Coin>>,
421 uint64_t mempool_sequence)
override {
426 uint64_t mempool_sequence)
override {
430 void BlockConnected(
const std::shared_ptr<const CBlock> &block,
434 void BlockDisconnected(
const std::shared_ptr<const CBlock> &block,
440 bool is_ibd)
override {
443 void ChainStateFlushed(
const CBlockLocator &locator)
override {
449 class NotificationsHandlerImpl :
public Handler {
451 explicit NotificationsHandlerImpl(
452 std::shared_ptr<Chain::Notifications> notifications)
453 :
m_proxy(std::make_shared<NotificationsProxy>(
454 std::move(notifications))) {
457 ~NotificationsHandlerImpl()
override { disconnect(); }
458 void disconnect()
override {
467 class RpcHandlerImpl :
public Handler {
469 explicit RpcHandlerImpl(
const CRPCCommand &command)
473 UniValue &result,
bool last_handler) {
498 void disconnect() final {
505 ~RpcHandlerImpl()
override { disconnect(); }
511 class ChainImpl :
public Chain {
518 std::optional<int> getHeight()
override {
521 int height = active.
Height();
527 BlockHash getBlockHash(
int height)
override {
534 bool haveBlockOnDisk(
int height)
override {
538 return block && (block->nStatus.hasData() != 0) && block->
nTx > 0;
553 return fork->nHeight;
561 return FillBlock(
m_node.chainman->m_blockman.LookupBlockIndex(hash),
562 block, lock, active, chainman().m_blockman);
564 bool findFirstBlockWithTimeAndHeight(int64_t min_time,
int min_height,
569 block, lock, active, chainman().m_blockman);
571 bool findAncestorByHeight(
const BlockHash &block_hash,
577 m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
579 block->GetAncestor(ancestor_height)) {
580 return FillBlock(ancestor, ancestor_out, lock, active,
581 chainman().m_blockman);
584 return FillBlock(
nullptr, ancestor_out, lock, active,
585 chainman().m_blockman);
587 bool findAncestorByHash(
const BlockHash &block_hash,
593 m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
595 m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
596 if (block && ancestor &&
600 return FillBlock(ancestor, ancestor_out, lock, active,
601 chainman().m_blockman);
603 bool findCommonAncestor(
const BlockHash &block_hash1,
611 m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
613 m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
619 return int{FillBlock(ancestor, ancestor_out, lock, active,
620 chainman().m_blockman)} &
621 int{FillBlock(block1, block1_out, lock, active,
622 chainman().m_blockman)} &
623 int{FillBlock(block2, block2_out, lock, active,
624 chainman().m_blockman)};
626 void findCoins(std::map<COutPoint, Coin> &coins)
override {
629 double guessVerificationProgress(
const BlockHash &block_hash)
override {
632 chainman().GetParams().TxData(),
633 chainman().m_blockman.LookupBlockIndex(block_hash));
635 bool hasBlocks(
const BlockHash &block_hash,
int min_height,
636 std::optional<int> max_height)
override {
646 chainman().m_blockman.LookupBlockIndex(block_hash)) {
647 if (max_height && block->
nHeight >= *max_height) {
650 for (; block->nStatus.hasData(); block = block->
pprev) {
659 bool broadcastTransaction(
const Config &config,
661 const Amount &max_tx_fee,
bool relay,
662 std::string &err_string)
override {
673 CFeeRate estimateFee()
const override {
677 return m_node.mempool->estimateFee();
683 return m_node.mempool->m_min_relay_feerate;
689 return m_node.mempool->m_dust_relay_feerate;
691 bool havePruned()
override {
693 return m_node.chainman->m_blockman.m_have_pruned;
695 bool isReadyToBroadcast()
override {
696 return !chainman().m_blockman.LoadingBlocks() &&
697 !isInitialBlockDownload();
699 bool isInitialBlockDownload()
override {
700 return chainman().ActiveChainstate().IsInitialBlockDownload();
703 void initMessage(
const std::string &message)
override {
712 void showProgress(
const std::string &title,
int progress,
713 bool resume_possible)
override {
714 ::uiInterface.ShowProgress(title, progress, resume_possible);
716 std::unique_ptr<Handler> handleNotifications(
717 std::shared_ptr<Notifications> notifications)
override {
718 return std::make_unique<NotificationsHandlerImpl>(
719 std::move(notifications));
722 waitForNotificationsIfTipChanged(
const BlockHash &old_tip)
override {
733 std::unique_ptr<Handler>
735 return std::make_unique<RpcHandlerImpl>(command);
737 bool rpcEnableDeprecated(
const std::string &method)
override {
740 void rpcRunLater(
const std::string &
name, std::function<
void()> fn,
741 int64_t seconds)
override {
748 std::vector<util::SettingsValue>
749 getSettingsList(
const std::string &
name)
override {
762 bool updateRwSetting(
const std::string &
name,
764 bool write)
override {
767 settings.rw_settings.erase(name);
769 settings.rw_settings[name] = value;
774 void requestMempoolTransactions(Notifications ¬ifications)
override {
780 notifications.transactionAddedToMempool(entry->GetSharedTx(),
793 return std::make_unique<node::NodeImpl>(context);
797 return std::make_unique<node::ChainImpl>(
node, params);
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.
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
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 AppInitSanityChecks()
Initialization sanity checks: ecc init, sanity checks, dir lock.
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.
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.