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 {
85 m_context->kernel = std::make_unique<kernel::Context>();
102 return AppInitMain(config, rpcServer, httpRPCRequestProcessor,
105 void appShutdown()
override {
109 void startShutdown()
override {
119 bool isPersistentSettingIgnored(
const std::string &
name)
override {
120 bool ignored =
false;
124 ignored = !options->empty();
130 getPersistentSetting(
const std::string &
name)
override {
133 void updateRwSetting(
const std::string &
name,
137 settings.rw_settings.erase(name);
139 settings.rw_settings[name] = value;
144 void forceSetting(
const std::string &
name,
148 settings.forced_settings.erase(name);
150 settings.forced_settings[name] = value;
154 void resetSettings()
override {
161 void mapPort(
bool use_upnp,
bool use_natpmp)
override {
171 bool getNodesStats(NodesStats &stats)
override {
175 std::vector<CNodeStats> stats_temp;
176 m_context->connman->GetNodeStats(stats_temp);
178 stats.reserve(stats_temp.size());
179 for (
auto &node_stats_temp : stats_temp) {
180 stats.emplace_back(std::move(node_stats_temp),
false,
188 for (
auto &node_stats : stats) {
189 std::get<1>(node_stats) =
191 std::get<0>(node_stats).nodeid,
192 std::get<2>(node_stats));
200 bool getBanned(
banmap_t &banmap)
override {
207 bool ban(
const CNetAddr &net_addr, int64_t ban_time_offset)
override {
209 m_context->banman->Ban(net_addr, ban_time_offset);
214 bool unban(
const CSubNet &ip)
override {
221 bool disconnectByAddress(
const CNetAddr &net_addr)
override {
223 return m_context->connman->DisconnectNode(net_addr);
227 bool disconnectById(
NodeId id)
override {
229 return m_context->connman->DisconnectNode(
id);
233 int64_t getTotalBytesRecv()
override {
237 int64_t getTotalBytesSent()
override {
241 size_t getMempoolSize()
override {
244 size_t getMempoolDynamicUsage()
override {
248 bool getHeaderTip(
int &height, int64_t &block_time)
override {
250 auto best_header = chainman().m_best_header;
252 height = best_header->nHeight;
253 block_time = best_header->GetBlockTime();
258 int getNumBlocks()
override {
260 return chainman().ActiveChain().Height();
266 : chainman().GetParams().GenesisBlock().GetHash();
268 int64_t getLastBlockTime()
override {
270 if (chainman().ActiveChain().Tip()) {
271 return chainman().ActiveChain().Tip()->GetBlockTime();
274 return chainman().GetParams().GenesisBlock().GetBlockTime();
276 double getVerificationProgress()
override {
280 tip = chainman().ActiveChain().Tip();
285 bool isInitialBlockDownload()
override {
286 return chainman().IsInitialBlockDownload();
288 bool isLoadingBlocks()
override {
289 return chainman().m_blockman.LoadingBlocks();
291 void setNetworkActive(
bool active)
override {
293 m_context->connman->SetNetworkActive(active);
296 bool getNetworkActive()
override {
299 CFeeRate getDustRelayFee()
override {
303 return m_context->mempool->m_dust_relay_feerate;
305 UniValue executeRpc(
const Config &config,
const std::string &command,
307 const std::string &uri)
override {
315 std::vector<std::string> listRpcCommands()
override {
324 bool getUnspentOutput(
const COutPoint &output,
Coin &coin)
override {
326 return chainman().ActiveChainstate().CoinsTip().GetCoin(output,
332 std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn)
override {
335 std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn)
override {
338 std::unique_ptr<Handler> handleQuestion(QuestionFn fn)
override {
341 std::unique_ptr<Handler>
342 handleShowProgress(ShowProgressFn fn)
override {
345 std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(
346 NotifyNumConnectionsChangedFn fn)
override {
350 std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(
351 NotifyNetworkActiveChangedFn fn)
override {
355 std::unique_ptr<Handler>
356 handleNotifyAlertChanged(NotifyAlertChangedFn fn)
override {
359 std::unique_ptr<Handler>
360 handleBannedListChanged(BannedListChangedFn fn)
override {
363 std::unique_ptr<Handler>
364 handleNotifyBlockTip(NotifyBlockTipFn fn)
override {
374 std::unique_ptr<Handler>
375 handleNotifyHeaderTip(NotifyHeaderTipFn fn)
override {
379 int64_t timestamp,
bool presync) {
384 NodeContext *context()
override {
return m_context; }
385 void setContext(NodeContext *context)
override {
m_context = context; }
391 const BlockManager &blockman) {
415 FillBlock(active[index->
nHeight] == index
422 if (!blockman.ReadBlockFromDisk(*block.
m_data, *index)) {
431 explicit NotificationsProxy(
432 std::shared_ptr<Chain::Notifications> notifications)
434 virtual ~NotificationsProxy() =
default;
436 std::shared_ptr<
const std::vector<Coin>>,
437 uint64_t mempool_sequence)
override {
442 uint64_t mempool_sequence)
override {
446 void BlockConnected(
const std::shared_ptr<const CBlock> &block,
450 void BlockDisconnected(
const std::shared_ptr<const CBlock> &block,
456 bool is_ibd)
override {
459 void ChainStateFlushed(
const CBlockLocator &locator)
override {
465 class NotificationsHandlerImpl :
public Handler {
467 explicit NotificationsHandlerImpl(
468 std::shared_ptr<Chain::Notifications> notifications)
469 :
m_proxy(std::make_shared<NotificationsProxy>(
470 std::move(notifications))) {
473 ~NotificationsHandlerImpl()
override { disconnect(); }
474 void disconnect()
override {
483 class RpcHandlerImpl :
public Handler {
485 explicit RpcHandlerImpl(
const CRPCCommand &command)
489 UniValue &result,
bool last_handler) {
514 void disconnect() final {
521 ~RpcHandlerImpl()
override { disconnect(); }
527 class ChainImpl :
public Chain {
534 std::optional<int> getHeight()
override {
537 int height = active.
Height();
543 BlockHash getBlockHash(
int height)
override {
550 bool haveBlockOnDisk(
int height)
override {
554 return block && (block->nStatus.hasData() != 0) && block->
nTx > 0;
569 return fork->nHeight;
577 return FillBlock(
m_node.chainman->m_blockman.LookupBlockIndex(hash),
578 block, lock, active, chainman().m_blockman);
580 bool findFirstBlockWithTimeAndHeight(int64_t min_time,
int min_height,
585 block, lock, active, chainman().m_blockman);
587 bool findAncestorByHeight(
const BlockHash &block_hash,
593 m_node.chainman->m_blockman.LookupBlockIndex(block_hash)) {
595 block->GetAncestor(ancestor_height)) {
596 return FillBlock(ancestor, ancestor_out, lock, active,
597 chainman().m_blockman);
600 return FillBlock(
nullptr, ancestor_out, lock, active,
601 chainman().m_blockman);
603 bool findAncestorByHash(
const BlockHash &block_hash,
609 m_node.chainman->m_blockman.LookupBlockIndex(block_hash);
611 m_node.chainman->m_blockman.LookupBlockIndex(ancestor_hash);
612 if (block && ancestor &&
616 return FillBlock(ancestor, ancestor_out, lock, active,
617 chainman().m_blockman);
619 bool findCommonAncestor(
const BlockHash &block_hash1,
627 m_node.chainman->m_blockman.LookupBlockIndex(block_hash1);
629 m_node.chainman->m_blockman.LookupBlockIndex(block_hash2);
635 return int{FillBlock(ancestor, ancestor_out, lock, active,
636 chainman().m_blockman)} &
637 int{FillBlock(block1, block1_out, lock, active,
638 chainman().m_blockman)} &
639 int{FillBlock(block2, block2_out, lock, active,
640 chainman().m_blockman)};
642 void findCoins(std::map<COutPoint, Coin> &coins)
override {
645 double guessVerificationProgress(
const BlockHash &block_hash)
override {
648 chainman().GetParams().TxData(),
649 chainman().m_blockman.LookupBlockIndex(block_hash));
651 bool hasBlocks(
const BlockHash &block_hash,
int min_height,
652 std::optional<int> max_height)
override {
662 chainman().m_blockman.LookupBlockIndex(block_hash)) {
663 if (max_height && block->
nHeight >= *max_height) {
666 for (; block->nStatus.hasData(); block = block->
pprev) {
675 bool broadcastTransaction(
const Config &config,
677 const Amount &max_tx_fee,
bool relay,
678 std::string &err_string)
override {
689 CFeeRate estimateFee()
const override {
693 return m_node.mempool->estimateFee();
699 return m_node.mempool->m_min_relay_feerate;
705 return m_node.mempool->m_dust_relay_feerate;
707 bool havePruned()
override {
709 return m_node.chainman->m_blockman.m_have_pruned;
711 bool isReadyToBroadcast()
override {
712 return !chainman().m_blockman.LoadingBlocks() &&
713 !isInitialBlockDownload();
715 bool isInitialBlockDownload()
override {
716 return chainman().IsInitialBlockDownload();
719 void initMessage(
const std::string &message)
override {
728 void showProgress(
const std::string &title,
int progress,
729 bool resume_possible)
override {
730 ::uiInterface.ShowProgress(title, progress, resume_possible);
732 std::unique_ptr<Handler> handleNotifications(
733 std::shared_ptr<Notifications> notifications)
override {
734 return std::make_unique<NotificationsHandlerImpl>(
735 std::move(notifications));
738 waitForNotificationsIfTipChanged(
const BlockHash &old_tip)
override {
749 std::unique_ptr<Handler>
751 return std::make_unique<RpcHandlerImpl>(command);
753 bool rpcEnableDeprecated(
const std::string &method)
override {
756 void rpcRunLater(
const std::string &
name, std::function<
void()> fn,
757 int64_t seconds)
override {
764 std::vector<util::SettingsValue>
765 getSettingsList(
const std::string &
name)
override {
778 bool updateRwSetting(
const std::string &
name,
780 bool write)
override {
783 settings.rw_settings.erase(name);
785 settings.rw_settings[name] = value;
790 void requestMempoolTransactions(Notifications ¬ifications)
override {
796 notifications.transactionAddedToMempool(entry->GetSharedTx(),
800 bool hasAssumedValidChain()
override {
804 NodeContext *context()
override {
return &
m_node; }
813 return std::make_unique<node::NodeImpl>(context);
817 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.
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
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.
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.