8#include <chainparams.h>
40#include <validation.h>
44#if defined(HAVE_CONFIG_H)
45#include <config/bitcoin-config.h>
50#include <boost/signals2/signal.hpp>
68 class NodeImpl :
public Node {
73 explicit NodeImpl(NodeContext *context) { setContext(context); }
75 void initParameterInteraction()
override {
79 int getExitStatus()
override {
82 bool baseInitialize(
Config &config)
override {
90 m_context->kernel = std::make_unique<kernel::Context>();
107 if (
AppInitMain(config, rpcServer, httpRPCRequestProcessor,
112 m_context->exit_status.store(EXIT_FAILURE);
115 void appShutdown()
override {
119 void startShutdown()
override {
129 bool isPersistentSettingIgnored(
const std::string &
name)
override {
130 bool ignored =
false;
134 ignored = !options->empty();
140 getPersistentSetting(
const std::string &
name)
override {
143 void updateRwSetting(
const std::string &
name,
147 settings.rw_settings.erase(name);
149 settings.rw_settings[name] = value;
154 void forceSetting(
const std::string &
name,
158 settings.forced_settings.erase(name);
160 settings.forced_settings[name] = value;
164 void resetSettings()
override {
171 void mapPort(
bool enable)
override {
StartMapPort(enable); }
172 bool getProxy(
Network net,
Proxy &proxy_info)
override {
179 bool getNodesStats(NodesStats &stats)
override {
183 std::vector<CNodeStats> stats_temp;
184 m_context->connman->GetNodeStats(stats_temp);
186 stats.reserve(stats_temp.size());
187 for (
auto &node_stats_temp : stats_temp) {
188 stats.emplace_back(std::move(node_stats_temp),
false,
196 for (
auto &node_stats : stats) {
197 std::get<1>(node_stats) =
199 std::get<0>(node_stats).nodeid,
200 std::get<2>(node_stats));
208 bool getBanned(
banmap_t &banmap)
override {
215 bool ban(
const CNetAddr &net_addr, int64_t ban_time_offset)
override {
217 m_context->banman->Ban(net_addr, ban_time_offset);
222 bool unban(
const CSubNet &ip)
override {
229 bool disconnectByAddress(
const CNetAddr &net_addr)
override {
231 return m_context->connman->DisconnectNode(net_addr);
235 bool disconnectById(
NodeId id)
override {
237 return m_context->connman->DisconnectNode(
id);
241 int64_t getTotalBytesRecv()
override {
245 int64_t getTotalBytesSent()
override {
249 size_t getMempoolSize()
override {
252 size_t getMempoolDynamicUsage()
override {
256 bool getHeaderTip(
int &height, int64_t &block_time)
override {
258 auto best_header = chainman().m_best_header;
260 height = best_header->nHeight;
261 block_time = best_header->GetBlockTime();
266 int getNumBlocks()
override {
268 return chainman().ActiveChain().Height();
274 : chainman().GetParams().GenesisBlock().GetHash();
276 int64_t getLastBlockTime()
override {
278 if (chainman().ActiveChain().Tip()) {
279 return chainman().ActiveChain().Tip()->GetBlockTime();
282 return chainman().GetParams().GenesisBlock().GetBlockTime();
284 double getVerificationProgress()
override {
288 tip = chainman().ActiveChain().Tip();
293 bool isInitialBlockDownload()
override {
294 return chainman().IsInitialBlockDownload();
296 bool isLoadingBlocks()
override {
297 return chainman().m_blockman.LoadingBlocks();
299 void setNetworkActive(
bool active)
override {
301 m_context->connman->SetNetworkActive(active);
304 bool getNetworkActive()
override {
307 CFeeRate getDustRelayFee()
override {
311 return m_context->mempool->m_dust_relay_feerate;
313 UniValue executeRpc(
const Config &config,
const std::string &command,
315 const std::string &uri)
override {
323 std::vector<std::string> listRpcCommands()
override {
332 std::optional<Coin> getUnspentOutput(
const COutPoint &output)
override {
334 return chainman().ActiveChainstate().CoinsTip().GetCoin(output);
339 std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn)
override {
342 std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn)
override {
345 std::unique_ptr<Handler> handleQuestion(QuestionFn fn)
override {
348 std::unique_ptr<Handler>
349 handleShowProgress(ShowProgressFn fn)
override {
352 std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(
353 NotifyNumConnectionsChangedFn fn)
override {
357 std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(
358 NotifyNetworkActiveChangedFn fn)
override {
362 std::unique_ptr<Handler>
363 handleNotifyAlertChanged(NotifyAlertChangedFn fn)
override {
366 std::unique_ptr<Handler>
367 handleBannedListChanged(BannedListChangedFn fn)
override {
370 std::unique_ptr<Handler>
371 handleNotifyBlockTip(NotifyBlockTipFn fn)
override {
381 std::unique_ptr<Handler>
382 handleNotifyHeaderTip(NotifyHeaderTipFn fn)
override {
386 int64_t timestamp,
bool presync) {
391 NodeContext *context()
override {
return m_context; }
392 void setContext(NodeContext *context)
override {
m_context = context; }
398 const BlockManager &blockman) {
424 FillBlock(active[index->
nHeight] == index
431 if (!blockman.ReadBlock(*block.
m_data, *index)) {
440 explicit NotificationsProxy(
441 std::shared_ptr<Chain::Notifications> notifications)
443 virtual ~NotificationsProxy() =
default;
445 std::shared_ptr<
const std::vector<Coin>>,
446 uint64_t mempool_sequence)
override {
451 uint64_t mempool_sequence)
override {
456 const std::shared_ptr<const CBlock> &block,
460 void BlockDisconnected(
const std::shared_ptr<const CBlock> &block,
466 bool is_ibd)
override {
476 class NotificationsHandlerImpl :
public Handler {
478 explicit NotificationsHandlerImpl(
479 std::shared_ptr<Chain::Notifications> notifications)
480 :
m_proxy(std::make_shared<NotificationsProxy>(
481 std::move(notifications))) {
484 ~NotificationsHandlerImpl()
override { disconnect(); }
485 void disconnect()
override {
494 class RpcHandlerImpl :
public Handler {
496 explicit RpcHandlerImpl(
const CRPCCommand &command)
500 UniValue &result,
bool last_handler) {
525 void disconnect() final {
532 ~RpcHandlerImpl()
override { disconnect(); }
538 class ChainImpl :
public Chain {
545 std::optional<int> getHeight()
override {
548 int height = active.
Height();
554 BlockHash getBlockHash(
int height)
override {
561 bool haveBlockOnDisk(
int height)
override {
565 return block && (block->nStatus.hasData() != 0) && block->
nTx > 0;
580 return fork->nHeight;
588 return FillBlock(
m_node.chainman->m_blockman.LookupBlockIndex(hash),
589 block, lock, active, chainman().m_blockman);
591 bool findFirstBlockWithTimeAndHeight(int64_t min_time,
int min_height,
596 block, lock, active, chainman().m_blockman);
598 bool findAncestorByHeight(
const BlockHash &block_hash,
604 m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
606 block->GetAncestor(ancestor_height)) {
607 return FillBlock(ancestor, ancestor_out, lock, active,
608 chainman().m_blockman);
611 return FillBlock(
nullptr, ancestor_out, lock, active,
612 chainman().m_blockman);
614 bool findAncestorByHash(
const BlockHash &block_hash,
620 m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
622 m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
623 if (block && ancestor &&
627 return FillBlock(ancestor, ancestor_out, lock, active,
628 chainman().m_blockman);
630 bool findCommonAncestor(
const BlockHash &block_hash1,
638 m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
640 m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
646 return int{FillBlock(ancestor, ancestor_out, lock, active,
647 chainman().m_blockman)} &
648 int{FillBlock(block1, block1_out, lock, active,
649 chainman().m_blockman)} &
650 int{FillBlock(block2, block2_out, lock, active,
651 chainman().m_blockman)};
653 void findCoins(std::map<COutPoint, Coin> &coins)
override {
656 double guessVerificationProgress(
const BlockHash &block_hash)
override {
659 chainman().GetParams().TxData(),
660 chainman().m_blockman.LookupBlockIndex(block_hash));
662 bool hasBlocks(
const BlockHash &block_hash,
int min_height,
663 std::optional<int> max_height)
override {
673 chainman().m_blockman.LookupBlockIndex(block_hash)) {
674 if (max_height && block->
nHeight >= *max_height) {
677 for (; block->nStatus.hasData(); block = block->
pprev) {
686 bool broadcastTransaction(
const Config &config,
688 const Amount &max_tx_fee,
bool relay,
689 std::string &err_string)
override {
700 CFeeRate estimateFee()
const override {
704 return m_node.mempool->estimateFee();
710 return m_node.mempool->m_min_relay_feerate;
716 return m_node.mempool->m_dust_relay_feerate;
718 bool havePruned()
override {
720 return m_node.chainman->m_blockman.m_have_pruned;
722 bool isReadyToBroadcast()
override {
723 return !chainman().m_blockman.LoadingBlocks() &&
724 !isInitialBlockDownload();
726 std::optional<int> getPruneHeight()
override {
727 LOCK(chainman().GetMutex());
729 chainman().ActiveChain());
731 bool isInitialBlockDownload()
override {
732 return chainman().IsInitialBlockDownload();
735 void initMessage(
const std::string &message)
override {
744 void showProgress(
const std::string &title,
int progress,
745 bool resume_possible)
override {
746 ::uiInterface.ShowProgress(title, progress, resume_possible);
748 std::unique_ptr<Handler> handleNotifications(
749 std::shared_ptr<Notifications> notifications)
override {
750 return std::make_unique<NotificationsHandlerImpl>(
751 std::move(notifications));
754 waitForNotificationsIfTipChanged(
const BlockHash &old_tip)
override {
765 std::unique_ptr<Handler>
767 return std::make_unique<RpcHandlerImpl>(command);
769 bool rpcEnableDeprecated(
const std::string &method)
override {
772 void rpcRunLater(
const std::string &
name, std::function<
void()> fn,
773 int64_t seconds)
override {
779 std::vector<util::SettingsValue>
780 getSettingsList(
const std::string &
name)
override {
793 bool updateRwSetting(
const std::string &
name,
795 bool write)
override {
798 settings.rw_settings.erase(name);
800 settings.rw_settings[name] = value;
805 void requestMempoolTransactions(Notifications ¬ifications)
override {
811 notifications.transactionAddedToMempool(entry->GetSharedTx(),
815 bool hasAssumedValidChain()
override {
819 NodeContext *context()
override {
return &
m_node; }
828 return std::make_unique<node::NodeImpl>(context);
832 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 AppInitBasicSetup(const ArgsManager &args, std::atomic< int > &exit_status)
Initialize bitcoin: Basic context setup.
bool AppInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, NodeContext &node, interfaces::BlockAndHeaderTipInfo *tip_info)
Bitcoin main initialization.
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 enable)
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, Proxy &proxyInfoOut)
std::shared_ptr< Chain::Notifications > m_notifications
const CChainParams & m_params
const CRPCCommand * m_wrapped_command
std::shared_ptr< NotificationsProxy > m_proxy
is a home for public enum and struct type definitions that are used by internally by node code,...
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.
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.