Bitcoin Core  0.20.99
P2P Digital Currency
node.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018-2020 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 <interfaces/node.h>
6 
7 #include <addrdb.h>
8 #include <banman.h>
9 #include <chain.h>
10 #include <chainparams.h>
11 #include <init.h>
12 #include <interfaces/chain.h>
13 #include <interfaces/handler.h>
14 #include <interfaces/wallet.h>
15 #include <net.h>
16 #include <net_processing.h>
17 #include <netaddress.h>
18 #include <netbase.h>
19 #include <node/context.h>
20 #include <node/ui_interface.h>
21 #include <policy/feerate.h>
22 #include <policy/fees.h>
23 #include <policy/settings.h>
24 #include <primitives/block.h>
25 #include <rpc/server.h>
26 #include <shutdown.h>
28 #include <sync.h>
29 #include <txmempool.h>
30 #include <util/ref.h>
31 #include <util/system.h>
32 #include <util/translation.h>
33 #include <validation.h>
34 #include <warnings.h>
35 
36 #if defined(HAVE_CONFIG_H)
37 #include <config/bitcoin-config.h>
38 #endif
39 
40 #include <univalue.h>
41 
42 #include <boost/signals2/signal.hpp>
43 
44 class CWallet;
45 fs::path GetWalletDir();
46 std::vector<fs::path> ListWalletDir();
47 std::vector<std::shared_ptr<CWallet>> GetWallets();
48 std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings);
49 WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings, std::shared_ptr<CWallet>& result);
50 std::unique_ptr<interfaces::Handler> HandleLoadWallet(interfaces::Node::LoadWalletFn load_wallet);
51 
52 namespace interfaces {
53 
54 namespace {
55 
56 class NodeImpl : public Node
57 {
58 public:
59  void initError(const bilingual_str& message) override { InitError(message); }
60  bool parseParameters(int argc, const char* const argv[], std::string& error) override
61  {
62  return gArgs.ParseParameters(argc, argv, error);
63  }
64  bool readConfigFiles(std::string& error) override { return gArgs.ReadConfigFiles(error, true); }
65  void forceSetArg(const std::string& arg, const std::string& value) override { gArgs.ForceSetArg(arg, value); }
66  bool softSetArg(const std::string& arg, const std::string& value) override { return gArgs.SoftSetArg(arg, value); }
67  bool softSetBoolArg(const std::string& arg, bool value) override { return gArgs.SoftSetBoolArg(arg, value); }
68  void selectParams(const std::string& network) override { SelectParams(network); }
69  uint64_t getAssumedBlockchainSize() override { return Params().AssumedBlockchainSize(); }
70  uint64_t getAssumedChainStateSize() override { return Params().AssumedChainStateSize(); }
71  std::string getNetwork() override { return Params().NetworkIDString(); }
72  void initLogging() override { InitLogging(); }
73  void initParameterInteraction() override { InitParameterInteraction(); }
74  bilingual_str getWarnings() override { return GetWarnings(true); }
75  uint32_t getLogCategories() override { return LogInstance().GetCategoryMask(); }
76  bool baseInitialize() override
77  {
80  }
81  bool appInitMain() override
82  {
85  }
86  void appShutdown() override
87  {
90  }
91  void startShutdown() override
92  {
93  StartShutdown();
94  // Stop RPC for clean shutdown if any of waitfor* commands is executed.
95  if (gArgs.GetBoolArg("-server", false)) {
96  InterruptRPC();
97  StopRPC();
98  }
99  }
100  bool shutdownRequested() override { return ShutdownRequested(); }
101  void mapPort(bool use_upnp) override
102  {
103  if (use_upnp) {
104  StartMapPort();
105  } else {
107  StopMapPort();
108  }
109  }
110  void setupServerArgs() override { return SetupServerArgs(m_context); }
111  bool getProxy(Network net, proxyType& proxy_info) override { return GetProxy(net, proxy_info); }
112  size_t getNodeCount(CConnman::NumConnections flags) override
113  {
114  return m_context.connman ? m_context.connman->GetNodeCount(flags) : 0;
115  }
116  bool getNodesStats(NodesStats& stats) override
117  {
118  stats.clear();
119 
120  if (m_context.connman) {
121  std::vector<CNodeStats> stats_temp;
122  m_context.connman->GetNodeStats(stats_temp);
123 
124  stats.reserve(stats_temp.size());
125  for (auto& node_stats_temp : stats_temp) {
126  stats.emplace_back(std::move(node_stats_temp), false, CNodeStateStats());
127  }
128 
129  // Try to retrieve the CNodeStateStats for each node.
130  TRY_LOCK(::cs_main, lockMain);
131  if (lockMain) {
132  for (auto& node_stats : stats) {
133  std::get<1>(node_stats) =
134  GetNodeStateStats(std::get<0>(node_stats).nodeid, std::get<2>(node_stats));
135  }
136  }
137  return true;
138  }
139  return false;
140  }
141  bool getBanned(banmap_t& banmap) override
142  {
143  if (m_context.banman) {
144  m_context.banman->GetBanned(banmap);
145  return true;
146  }
147  return false;
148  }
149  bool ban(const CNetAddr& net_addr, int64_t ban_time_offset) override
150  {
151  if (m_context.banman) {
152  m_context.banman->Ban(net_addr, ban_time_offset);
153  return true;
154  }
155  return false;
156  }
157  bool unban(const CSubNet& ip) override
158  {
159  if (m_context.banman) {
160  m_context.banman->Unban(ip);
161  return true;
162  }
163  return false;
164  }
165  bool disconnectByAddress(const CNetAddr& net_addr) override
166  {
167  if (m_context.connman) {
168  return m_context.connman->DisconnectNode(net_addr);
169  }
170  return false;
171  }
172  bool disconnectById(NodeId id) override
173  {
174  if (m_context.connman) {
175  return m_context.connman->DisconnectNode(id);
176  }
177  return false;
178  }
179  int64_t getTotalBytesRecv() override { return m_context.connman ? m_context.connman->GetTotalBytesRecv() : 0; }
180  int64_t getTotalBytesSent() override { return m_context.connman ? m_context.connman->GetTotalBytesSent() : 0; }
181  size_t getMempoolSize() override { return m_context.mempool ? m_context.mempool->size() : 0; }
182  size_t getMempoolDynamicUsage() override { return m_context.mempool ? m_context.mempool->DynamicMemoryUsage() : 0; }
183  bool getHeaderTip(int& height, int64_t& block_time) override
184  {
185  LOCK(::cs_main);
186  if (::pindexBestHeader) {
187  height = ::pindexBestHeader->nHeight;
188  block_time = ::pindexBestHeader->GetBlockTime();
189  return true;
190  }
191  return false;
192  }
193  int getNumBlocks() override
194  {
195  LOCK(::cs_main);
197  }
198  uint256 getBestBlockHash() override
199  {
200  const CBlockIndex* tip = WITH_LOCK(::cs_main, return ::ChainActive().Tip());
201  return tip ? tip->GetBlockHash() : Params().GenesisBlock().GetHash();
202  }
203  int64_t getLastBlockTime() override
204  {
205  LOCK(::cs_main);
206  if (::ChainActive().Tip()) {
208  }
209  return Params().GenesisBlock().GetBlockTime(); // Genesis block's time of current network
210  }
211  double getVerificationProgress() override
212  {
213  const CBlockIndex* tip;
214  {
215  LOCK(::cs_main);
216  tip = ::ChainActive().Tip();
217  }
218  return GuessVerificationProgress(Params().TxData(), tip);
219  }
220  bool isInitialBlockDownload() override { return ::ChainstateActive().IsInitialBlockDownload(); }
221  bool getReindex() override { return ::fReindex; }
222  bool getImporting() override { return ::fImporting; }
223  void setNetworkActive(bool active) override
224  {
225  if (m_context.connman) {
226  m_context.connman->SetNetworkActive(active);
227  }
228  }
229  bool getNetworkActive() override { return m_context.connman && m_context.connman->GetNetworkActive(); }
230  CFeeRate estimateSmartFee(int num_blocks, bool conservative, int* returned_target = nullptr) override
231  {
232  FeeCalculation fee_calc;
233  CFeeRate result = ::feeEstimator.estimateSmartFee(num_blocks, &fee_calc, conservative);
234  if (returned_target) {
235  *returned_target = fee_calc.returnedTarget;
236  }
237  return result;
238  }
239  CFeeRate getDustRelayFee() override { return ::dustRelayFee; }
240  UniValue executeRpc(const std::string& command, const UniValue& params, const std::string& uri) override
241  {
243  req.params = params;
244  req.strMethod = command;
245  req.URI = uri;
247  }
248  std::vector<std::string> listRpcCommands() override { return ::tableRPC.listCommands(); }
249  void rpcSetTimerInterfaceIfUnset(RPCTimerInterface* iface) override { RPCSetTimerInterfaceIfUnset(iface); }
250  void rpcUnsetTimerInterface(RPCTimerInterface* iface) override { RPCUnsetTimerInterface(iface); }
251  bool getUnspentOutput(const COutPoint& output, Coin& coin) override
252  {
253  LOCK(::cs_main);
254  return ::ChainstateActive().CoinsTip().GetCoin(output, coin);
255  }
256  std::string getWalletDir() override
257  {
258  return GetWalletDir().string();
259  }
260  std::vector<std::string> listWalletDir() override
261  {
262  std::vector<std::string> paths;
263  for (auto& path : ListWalletDir()) {
264  paths.push_back(path.string());
265  }
266  return paths;
267  }
268  std::vector<std::unique_ptr<Wallet>> getWallets() override
269  {
270  std::vector<std::unique_ptr<Wallet>> wallets;
271  for (auto& client : m_context.chain_clients) {
272  auto client_wallets = client->getWallets();
273  std::move(client_wallets.begin(), client_wallets.end(), std::back_inserter(wallets));
274  }
275  return wallets;
276  }
277  std::unique_ptr<Wallet> loadWallet(const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings) override
278  {
279  return MakeWallet(LoadWallet(*m_context.chain, name, error, warnings));
280  }
281  std::unique_ptr<Wallet> createWallet(const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings, WalletCreationStatus& status) override
282  {
283  std::shared_ptr<CWallet> wallet;
284  status = CreateWallet(*m_context.chain, passphrase, wallet_creation_flags, name, error, warnings, wallet);
285  return MakeWallet(wallet);
286  }
287  std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
288  {
289  return MakeHandler(::uiInterface.InitMessage_connect(fn));
290  }
291  std::unique_ptr<Handler> handleMessageBox(MessageBoxFn fn) override
292  {
293  return MakeHandler(::uiInterface.ThreadSafeMessageBox_connect(fn));
294  }
295  std::unique_ptr<Handler> handleQuestion(QuestionFn fn) override
296  {
297  return MakeHandler(::uiInterface.ThreadSafeQuestion_connect(fn));
298  }
299  std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
300  {
301  return MakeHandler(::uiInterface.ShowProgress_connect(fn));
302  }
303  std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override
304  {
305  return HandleLoadWallet(std::move(fn));
306  }
307  std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
308  {
309  return MakeHandler(::uiInterface.NotifyNumConnectionsChanged_connect(fn));
310  }
311  std::unique_ptr<Handler> handleNotifyNetworkActiveChanged(NotifyNetworkActiveChangedFn fn) override
312  {
313  return MakeHandler(::uiInterface.NotifyNetworkActiveChanged_connect(fn));
314  }
315  std::unique_ptr<Handler> handleNotifyAlertChanged(NotifyAlertChangedFn fn) override
316  {
317  return MakeHandler(::uiInterface.NotifyAlertChanged_connect(fn));
318  }
319  std::unique_ptr<Handler> handleBannedListChanged(BannedListChangedFn fn) override
320  {
321  return MakeHandler(::uiInterface.BannedListChanged_connect(fn));
322  }
323  std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override
324  {
325  return MakeHandler(::uiInterface.NotifyBlockTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
326  fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
327  GuessVerificationProgress(Params().TxData(), block));
328  }));
329  }
330  std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override
331  {
332  return MakeHandler(
333  ::uiInterface.NotifyHeaderTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) {
334  fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()},
335  /* verification progress is unused when a header was received */ 0);
336  }));
337  }
338  NodeContext* context() override { return &m_context; }
341 };
342 
343 } // namespace
344 
345 std::unique_ptr<Node> MakeNode() { return MakeUnique<NodeImpl>(); }
346 
347 } // namespace interfaces
NODISCARD bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:744
std::string NetworkIDString() const
Return the network string.
Definition: chainparams.h:81
std::vector< std::unique_ptr< interfaces::ChainClient > > chain_clients
Definition: context.h:42
bool ShutdownRequested()
Definition: shutdown.cpp:20
RPC timer "driver".
Definition: server.h:59
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition: validation.h:109
BCLog::Logger & LogInstance()
Definition: logging.cpp:14
void InitLogging()
Initialize global loggers.
Definition: init.cpp:862
int64_t GetBlockTime() const
Definition: chain.h:247
int returnedTarget
Definition: fees.h:73
#define TRY_LOCK(cs, name)
Definition: sync.h:230
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn&#39;t already have a value.
Definition: system.cpp:406
void Shutdown(NodeContext &node)
Definition: init.cpp:176
A UTXO entry.
Definition: coins.h:30
Bilingual messages:
Definition: translation.h:16
CChain & ChainActive()
Please prefer the identical ChainstateManager::ActiveChain.
Definition: validation.cpp:112
std::unique_ptr< BanMan > banman
Definition: context.h:39
uint64_t AssumedChainStateSize() const
Minimum free space (in GB) needed for data directory when pruned; Does not include prune target...
Definition: chainparams.h:77
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
size_t DynamicMemoryUsage() const
Definition: txmempool.cpp:918
util::Ref m_context_ref
Definition: node.cpp:340
int Height() const
Return the maximal height in the chain.
Definition: chain.h:421
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:60
std::unique_ptr< interfaces::Chain > chain
Definition: context.h:41
unsigned long size() const
Definition: txmempool.h:680
void InterruptRPC()
Definition: server.cpp:294
const CBlock & GenesisBlock() const
Definition: chainparams.h:64
NODISCARD bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:283
std::unique_ptr< Handler > MakeHandler(boost::signals2::connection connection)
Return handler wrapping a boost signal connection.
Definition: handler.cpp:36
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:392
bool AppInitMain(const util::Ref &context, NodeContext &node)
Bitcoin core main initialization.
Definition: init.cpp:1242
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: system.cpp:414
WalletCreationStatus
Definition: wallet.h:59
bool AppInitBasicSetup()
Initialize bitcoin core: Basic context setup.
Definition: init.cpp:908
void SetupServerArgs(NodeContext &node)
Register all arguments with the ArgsManager.
Definition: init.cpp:368
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn&#39;t already have a value.
Definition: system.cpp:398
std::shared_ptr< CWallet > LoadWallet(interfaces::Chain &chain, const std::string &name, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: dummywallet.cpp:76
std::unique_ptr< Chain > MakeChain(NodeContext &node)
Return implementation of Chain interface.
Definition: chain.cpp:386
void RPCUnsetTimerInterface(RPCTimerInterface *iface)
Unset factory function for timers.
Definition: server.cpp:496
interfaces::Chain & chain() const
Interface for accessing chain state.
Definition: wallet.h:794
UniValue execute(const JSONRPCRequest &request) const
Execute a method.
Definition: server.cpp:438
void InitParameterInteraction()
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:793
uint256 GetBlockHash() const
Definition: chain.h:233
CBlockPolicyEstimator feeEstimator
Definition: validation.cpp:151
std::vector< std::shared_ptr< CWallet > > GetWallets()
Definition: dummywallet.cpp:71
void StopMapPort()
Definition: net.cpp:1587
CRPCTable tableRPC
Definition: server.cpp:520
bool AppInitSanityChecks()
Initialization sanity checks: ecc init, sanity checks, dir lock.
Definition: init.cpp:1209
NodeContext struct containing references to chain state and connection state.
Definition: context.h:34
std::unique_ptr< CConnman > connman
Definition: context.h:35
void Interrupt(NodeContext &node)
Interrupt threads.
Definition: init.cpp:160
CBlockIndex * pindexBestHeader
Best header we&#39;ve seen so far (used for getheaders queries&#39; starting points).
Definition: validation.cpp:130
fs::path GetWalletDir()
Definition: dummywallet.cpp:61
#define LOCK(cs)
Definition: sync.h:226
const char * name
Definition: rest.cpp:41
CFeeRate estimateSmartFee(int confTarget, FeeCalculation *feeCalc, bool conservative) const
Estimate feerate needed to get be included in a block within confTarget blocks.
Definition: fees.cpp:785
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given chain name.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: validation.cpp:128
uint32_t GetCategoryMask() const
Definition: logging.h:129
std::unique_ptr< interfaces::Handler > HandleLoadWallet(interfaces::Node::LoadWalletFn load_wallet)
Network
Definition: netaddress.h:19
int64_t NodeId
Definition: net.h:90
bool InitError(const bilingual_str &str)
Show error message.
NumConnections
Definition: net.h:122
std::atomic_bool fImporting
std::function< void(std::unique_ptr< interfaces::Wallet > wallet)> LoadWalletFn
Definition: dummywallet.cpp:86
std::function< void(std::unique_ptr< Wallet > wallet)> LoadWalletFn
Register handler for load wallet messages.
Definition: node.h:237
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:18
int64_t GetBlockTime() const
Definition: block.h:55
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:253
std::unique_ptr< Wallet > MakeWallet(const std::shared_ptr< CWallet > &wallet)
Return implementation of Wallet interface.
Definition: dummywallet.cpp:94
Type-safe dynamic reference.
Definition: ref.h:21
void RPCSetTimerInterfaceIfUnset(RPCTimerInterface *iface)
Set the factory function for timer, but only, if unset.
Definition: server.cpp:485
bool AppInitParameterInteraction()
Initialization: parameter interaction.
Definition: init.cpp:950
int flags
Definition: bitcoin-tx.cpp:509
std::atomic_bool fReindex
WalletCreationStatus CreateWallet(interfaces::Chain &chain, const SecureString &passphrase, uint64_t wallet_creation_flags, const std::string &name, bilingual_str &error, std::vector< bilingual_str > &warnings, std::shared_ptr< CWallet > &result)
Definition: dummywallet.cpp:81
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Definition: netaddress.h:31
uint256 GetHash() const
Definition: block.cpp:11
256-bit opaque blob.
Definition: uint256.h:120
CChainState & ChainstateActive()
Please prefer the identical ChainstateManager::ActiveChainstate.
Definition: validation.cpp:105
bilingual_str GetWarnings(bool verbose)
Format a string that describes several potential problems detected by the core.
Definition: warnings.cpp:44
void StopRPC()
Definition: server.cpp:305
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: coins.cpp:59
uint64_t AssumedBlockchainSize() const
Minimum free space (in GB) needed for data directory.
Definition: chainparams.h:75
Interface giving clients (wallet processes, maybe other analysis tools in the future) ability to acce...
Definition: chain.h:82
std::unique_ptr< Node > MakeNode()
Return implementation of Node interface.
Definition: node.cpp:345
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:137
const CChainParams & Params()
Return the currently selected parameters.
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...
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:390
bool IsInitialBlockDownload() const
Check whether we are doing an initial block download (synchronizing from disk or network) ...
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:618
ArgsManager gArgs
Definition: system.cpp:77
Fee rate in satoshis per kilobyte: CAmount / kB.
Definition: feerate.h:29
void StartShutdown()
Definition: shutdown.cpp:12
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Definition: validation.h:552
std::map< CSubNet, CBanEntry > banmap_t
Definition: net_types.h:13
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:720
bool AppInitLockDataDirectory()
Lock bitcoin core data directory.
Definition: init.cpp:1230
CClientUIInterface uiInterface
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:150
NodeContext m_context
Definition: node.cpp:339
std::vector< std::string > listCommands() const
Returns a list of registered commands.
Definition: server.cpp:478
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
CFeeRate dustRelayFee
Definition: settings.cpp:13
void StartMapPort()
Definition: net.cpp:1579
void InterruptMapPort()
Definition: net.cpp:1583
std::vector< fs::path > ListWalletDir()
Definition: dummywallet.cpp:66
CTxMemPool * mempool
Definition: context.h:36