Bitcoin ABC  0.22.12
P2P Digital Currency
init.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #if defined(HAVE_CONFIG_H)
7 #include <config/bitcoin-config.h>
8 #endif
9 
10 #include <init.h>
11 
12 #include <addrman.h>
13 #include <amount.h>
14 #include <avalanche/processor.h>
15 #include <banman.h>
16 #include <blockdb.h>
17 #include <blockfilter.h>
18 #include <chain.h>
19 #include <chainparams.h>
20 #include <checkpoints.h>
21 #include <compat/sanity.h>
22 #include <config.h>
23 #include <consensus/validation.h>
24 #include <flatfile.h>
25 #include <fs.h>
26 #include <hash.h>
27 #include <httprpc.h>
28 #include <httpserver.h>
29 #include <index/blockfilterindex.h>
30 #include <index/txindex.h>
31 #include <interfaces/chain.h>
32 #include <key.h>
33 #include <miner.h>
34 #include <net.h>
35 #include <net_permissions.h>
36 #include <net_processing.h>
37 #include <netbase.h>
38 #include <network.h>
39 #include <node/context.h>
40 #include <node/ui_interface.h>
41 #include <policy/mempool.h>
42 #include <policy/policy.h>
43 #include <policy/settings.h>
44 #include <rpc/blockchain.h>
45 #include <rpc/register.h>
46 #include <rpc/server.h>
47 #include <rpc/util.h>
48 #include <scheduler.h>
49 #include <script/scriptcache.h>
50 #include <script/sigcache.h>
51 #include <script/standard.h>
52 #include <shutdown.h>
53 #include <timedata.h>
54 #include <torcontrol.h>
55 #include <txdb.h>
56 #include <txmempool.h>
57 #include <util/asmap.h>
58 #include <util/check.h>
59 #include <util/moneystr.h>
60 #include <util/threadnames.h>
61 #include <util/translation.h>
62 #include <validation.h>
63 #include <validationinterface.h>
64 #include <walletinitinterface.h>
65 
66 #include <boost/algorithm/string/classification.hpp>
67 #include <boost/algorithm/string/replace.hpp>
68 #include <boost/algorithm/string/split.hpp>
69 #include <boost/signals2/signal.hpp>
70 #include <boost/thread.hpp>
71 
72 #if ENABLE_ZMQ
75 #include <zmq/zmqrpc.h>
76 #endif
77 
78 #ifndef WIN32
79 #include <attributes.h>
80 #include <cerrno>
81 #include <csignal>
82 #include <sys/stat.h>
83 #endif
84 #include <cstdint>
85 #include <cstdio>
86 #include <functional>
87 #include <set>
88 
89 static const bool DEFAULT_PROXYRANDOMIZE = true;
90 static const bool DEFAULT_REST_ENABLE = false;
91 static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
92 
93 #ifdef WIN32
94 // Win32 LevelDB doesn't use filedescriptors, and the ones used for accessing
95 // block files don't count towards the fd_set size limit anyway.
96 #define MIN_CORE_FILEDESCRIPTORS 0
97 #else
98 #define MIN_CORE_FILEDESCRIPTORS 150
99 #endif
100 
101 static const char *DEFAULT_ASMAP_FILENAME = "ip_asn.map";
102 
106 static const char *BITCOIN_PID_FILENAME = "bitcoind.pid";
107 
108 static fs::path GetPidFile(const ArgsManager &args) {
109  return AbsPathForConfigVal(
110  fs::path(args.GetArg("-pid", BITCOIN_PID_FILENAME)));
111 }
112 
113 NODISCARD static bool CreatePidFile(const ArgsManager &args) {
114  fsbridge::ofstream file{GetPidFile(args)};
115  if (file) {
116 #ifdef WIN32
117  tfm::format(file, "%d\n", GetCurrentProcessId());
118 #else
119  tfm::format(file, "%d\n", getpid());
120 #endif
121  return true;
122  } else {
123  return InitError(strprintf(_("Unable to create the PID file '%s': %s"),
124  GetPidFile(args).string(),
125  std::strerror(errno)));
126  }
127 }
128 
130 //
131 // Shutdown
132 //
133 
134 //
135 // Thread management and startup/shutdown:
136 //
137 // The network-processing threads are all part of a thread group created by
138 // AppInit() or the Qt main() function.
139 //
140 // A clean exit happens when StartShutdown() or the SIGTERM signal handler sets
141 // fRequestShutdown, which makes main thread's WaitForShutdown() interrupts the
142 // thread group.
143 // And then, WaitForShutdown() makes all other on-going threads in the thread
144 // group join the main thread.
145 // Shutdown() is then called to clean up database connections, and stop other
146 // threads that should only be stopped after the main network-processing threads
147 // have exited.
148 //
149 // Shutdown for Qt is very similar, only it uses a QTimer to detect
150 // ShutdownRequested() getting set, and then does the normal Qt shutdown thing.
151 //
152 
153 static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
154 
155 static boost::thread_group threadGroup;
156 
157 void Interrupt(NodeContext &node) {
160  InterruptRPC();
161  InterruptREST();
164  if (g_avalanche) {
165  // Avalanche needs to be stopped before we interrupt the thread group as
166  // the scheduler will stop working then.
167  g_avalanche->stopEventLoop();
168  }
169  if (node.connman) {
170  node.connman->Interrupt();
171  }
172  if (g_txindex) {
173  g_txindex->Interrupt();
174  }
175  ForEachBlockFilterIndex([](BlockFilterIndex &index) { index.Interrupt(); });
176 }
177 
178 void Shutdown(NodeContext &node) {
179  LogPrintf("%s: In progress...\n", __func__);
180  static RecursiveMutex cs_Shutdown;
181  TRY_LOCK(cs_Shutdown, lockShutdown);
182  if (!lockShutdown) {
183  return;
184  }
185  Assert(node.args);
186 
191  util::ThreadRename("shutoff");
193 
194  StopHTTPRPC();
195  StopREST();
196  StopRPC();
197  StopHTTPServer();
198  for (const auto &client : node.chain_clients) {
199  client->flush();
200  }
201  StopMapPort();
202 
203  // Because avalanche and the network depend on each other, it is important
204  // to shut them down in this order:
205  // 1. Stop avalanche event loop.
206  // 2. Shutdown network processing.
207  // 3. Destroy avalanche::Processor.
208  // 4. Destroy CConnman
209  if (g_avalanche) {
210  g_avalanche->stopEventLoop();
211  }
212 
213  // Because these depend on each-other, we make sure that neither can be
214  // using the other before destroying them.
215  if (node.peer_logic) {
217  }
218  // Follow the lock order requirements:
219  // * CheckForStaleTipAndEvictPeers locks cs_main before indirectly calling
220  // GetExtraOutboundCount which locks cs_vNodes.
221  // * ProcessMessage locks cs_main and g_cs_orphans before indirectly calling
222  // ForEachNode which locks cs_vNodes.
223  // * CConnman::Stop calls DeleteNode, which calls FinalizeNode, which locks
224  // cs_main and calls EraseOrphansFor, which locks g_cs_orphans.
225  //
226  // Thus the implicit locking order requirement is:
227  // (1) cs_main, (2) g_cs_orphans, (3) cs_vNodes.
228  if (node.connman) {
229  node.connman->StopThreads();
230  LOCK2(::cs_main, ::g_cs_orphans);
231  node.connman->StopNodes();
232  }
233 
234  StopTorControl();
235 
236  // After everything has been shut down, but before things get flushed, stop
237  // the CScheduler/checkqueue threadGroup
238  if (node.scheduler) {
239  node.scheduler->stop();
240  }
241  threadGroup.interrupt_all();
242  threadGroup.join_all();
243 
244  // After the threads that potentially access these pointers have been
245  // stopped, destruct and reset all to nullptr.
246  node.peer_logic.reset();
247 
248  // Destroy various global instances
249  g_avalanche.reset();
250  node.connman.reset();
251  node.banman.reset();
252 
253  if (::g_mempool.IsLoaded() &&
254  node.args->GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
256  }
257 
258  // FlushStateToDisk generates a ChainStateFlushed callback, which we should
259  // avoid missing
260  if (node.chainman) {
261  LOCK(cs_main);
262  for (CChainState *chainstate : node.chainman->GetAll()) {
263  if (chainstate->CanFlushToDisk()) {
264  chainstate->ForceFlushStateToDisk();
265  }
266  }
267  }
268 
269  // After there are no more peers/RPC left to give us new data which may
270  // generate CValidationInterface callbacks, flush them...
272 
273  // Stop and delete all indexes only after flushing background callbacks.
274  if (g_txindex) {
275  g_txindex->Stop();
276  g_txindex.reset();
277  }
278  ForEachBlockFilterIndex([](BlockFilterIndex &index) { index.Stop(); });
280 
281  // Any future callbacks will be dropped. This should absolutely be safe - if
282  // missing a callback results in an unrecoverable situation, unclean
283  // shutdown would too. The only reason to do the above flushes is to let the
284  // wallet catch up with our current chain to avoid any strange pruning edge
285  // cases and make next startup faster by avoiding rescan.
286 
287  if (node.chainman) {
288  LOCK(cs_main);
289  for (CChainState *chainstate : node.chainman->GetAll()) {
290  if (chainstate->CanFlushToDisk()) {
291  chainstate->ForceFlushStateToDisk();
292  chainstate->ResetCoinsViews();
293  }
294  }
295  pblocktree.reset();
296  }
297  for (const auto &client : node.chain_clients) {
298  client->stop();
299  }
300 
301 #if ENABLE_ZMQ
306  }
307 #endif
308 
309  node.chain_clients.clear();
312  globalVerifyHandle.reset();
313  ECC_Stop();
314  node.mempool = nullptr;
315  node.chainman = nullptr;
316  node.scheduler.reset();
317 
318  try {
319  if (!fs::remove(GetPidFile(*node.args))) {
320  LogPrintf("%s: Unable to remove PID file: File does not exist\n",
321  __func__);
322  }
323  } catch (const fs::filesystem_error &e) {
324  LogPrintf("%s: Unable to remove PID file: %s\n", __func__,
326  }
327 
328  node.args = nullptr;
329  LogPrintf("%s: done\n", __func__);
330 }
331 
337 #ifndef WIN32
338 static void HandleSIGTERM(int) {
339  StartShutdown();
340 }
341 
342 static void HandleSIGHUP(int) {
343  LogInstance().m_reopen_file = true;
344 }
345 #else
346 static BOOL WINAPI consoleCtrlHandler(DWORD dwCtrlType) {
347  StartShutdown();
348  Sleep(INFINITE);
349  return true;
350 }
351 #endif
352 
353 #ifndef WIN32
354 static void registerSignalHandler(int signal, void (*handler)(int)) {
355  struct sigaction sa;
356  sa.sa_handler = handler;
357  sigemptyset(&sa.sa_mask);
358  sa.sa_flags = 0;
359  sigaction(signal, &sa, NULL);
360 }
361 #endif
362 
363 static boost::signals2::connection rpc_notify_block_change_connection;
364 static void OnRPCStarted() {
365  rpc_notify_block_change_connection = uiInterface.NotifyBlockTip_connect(
366  std::bind(RPCNotifyBlockChange, std::placeholders::_2));
367 }
368 
369 static void OnRPCStopped() {
370  rpc_notify_block_change_connection.disconnect();
371  RPCNotifyBlockChange(nullptr);
372  g_best_block_cv.notify_all();
373  LogPrint(BCLog::RPC, "RPC stopped.\n");
374 }
375 
377  assert(!node.args);
378  node.args = &gArgs;
379  ArgsManager &argsman = *node.args;
380 
381  SetupHelpOptions(argsman);
382  // server-only for now
383  argsman.AddArg("-help-debug",
384  "Print help message with debugging options and exit", false,
386 
387  const auto defaultBaseParams =
389  const auto testnetBaseParams =
391  const auto regtestBaseParams =
393  const auto defaultChainParams = CreateChainParams(CBaseChainParams::MAIN);
394  const auto testnetChainParams =
396  const auto regtestChainParams =
398 
399  // Hidden Options
400  std::vector<std::string> hidden_args = {
401  "-dbcrashratio", "-forcecompactdb", "-parkdeepreorg",
402  "-automaticunparking", "-replayprotectionactivationtime",
403  "-enableminerfund",
404  // GUI args. These will be overwritten by SetupUIArgs for the GUI
405  "-allowselfsignedrootcertificates", "-choosedatadir", "-lang=<lang>",
406  "-min", "-resetguisettings", "-rootcertificates=<file>", "-splash",
407  "-uiplatform",
408  // TODO remove after the November 2020 upgrade
409  "-axionactivationtime"};
410 
411  // Set all of the args and their help
412  // When adding new options to the categories, please keep and ensure
413  // alphabetical ordering. Do not translate _(...) -help-debug options, Many
414  // technical terms, and only a very small audience, so is unnecessary stress
415  // to translators.
416  argsman.AddArg("-version", "Print version and exit", ArgsManager::ALLOW_ANY,
418 #if defined(HAVE_SYSTEM)
419  argsman.AddArg(
420  "-alertnotify=<cmd>",
421  "Execute command when a relevant alert is received or we see "
422  "a really long fork (%s in cmd is replaced by message)",
424 #endif
425  argsman.AddArg(
426  "-assumevalid=<hex>",
427  strprintf(
428  "If this block is in the chain assume that it and its ancestors "
429  "are valid and potentially skip their script verification (0 to "
430  "verify all, default: %s, testnet: %s)",
431  defaultChainParams->GetConsensus().defaultAssumeValid.GetHex(),
432  testnetChainParams->GetConsensus().defaultAssumeValid.GetHex()),
434  argsman.AddArg("-blocksdir=<dir>",
435  "Specify directory to hold blocks subdirectory for *.dat "
436  "files (default: <datadir>)",
438 #if defined(HAVE_SYSTEM)
439  argsman.AddArg("-blocknotify=<cmd>",
440  "Execute command when the best block changes (%s in cmd is "
441  "replaced by block hash)",
443 #endif
444  argsman.AddArg("-blockreconstructionextratxn=<n>",
445  strprintf("Extra transactions to keep in memory for compact "
446  "block reconstructions (default: %u)",
449  argsman.AddArg(
450  "-blocksonly",
451  strprintf("Whether to reject transactions from network peers. "
452  "Automatic broadcast and rebroadcast of any transactions "
453  "from inbound peers is disabled, unless "
454  "'-whitelistforcerelay' is '1', in which case whitelisted "
455  "peers' transactions will be relayed. RPC transactions are"
456  " not affected. (default: %u)",
459  argsman.AddArg(
460  "-conf=<file>",
461  strprintf("Specify path to read-only configuration file. Relative "
462  "paths will be prefixed by datadir location. (default: %s)",
465  argsman.AddArg("-datadir=<dir>", "Specify data directory",
467  argsman.AddArg(
468  "-dbbatchsize",
469  strprintf("Maximum database write batch size in bytes (default: %u)",
473  argsman.AddArg(
474  "-dbcache=<n>",
475  strprintf("Set database cache size in MiB (%d to %d, default: %d)",
478  argsman.AddArg(
479  "-debuglogfile=<file>",
480  strprintf("Specify location of debug log file. Relative paths "
481  "will be prefixed by a net-specific datadir "
482  "location. (0 to disable; default: %s)",
485  argsman.AddArg("-feefilter",
486  strprintf("Tell other nodes to filter invs to us by our "
487  "mempool min fee (default: %d)",
491  argsman.AddArg(
492  "-finalizationdelay=<n>",
493  strprintf("Set the minimum amount of time to wait between a "
494  "block header reception and the block finalization. "
495  "Unit is seconds (default: %d)",
498  argsman.AddArg(
499  "-includeconf=<file>",
500  "Specify additional configuration file, relative to the -datadir path "
501  "(only useable from configuration file, not command line)",
503  argsman.AddArg("-maxreorgdepth=<n>",
504  strprintf("Configure at what depth blocks are considered "
505  "final (default: %d). Use -1 to disable.",
508  argsman.AddArg("-loadblock=<file>",
509  "Imports blocks from external file on startup",
511  argsman.AddArg("-maxmempool=<n>",
512  strprintf("Keep the transaction memory pool below <n> "
513  "megabytes (default: %u)",
516  argsman.AddArg("-maxorphantx=<n>",
517  strprintf("Keep at most <n> unconnectable transactions in "
518  "memory (default: %u)",
521  argsman.AddArg("-mempoolexpiry=<n>",
522  strprintf("Do not keep transactions in the mempool longer "
523  "than <n> hours (default: %u)",
526  argsman.AddArg(
527  "-minimumchainwork=<hex>",
528  strprintf(
529  "Minimum work assumed to exist on a valid chain in hex "
530  "(default: %s, testnet: %s)",
531  defaultChainParams->GetConsensus().nMinimumChainWork.GetHex(),
532  testnetChainParams->GetConsensus().nMinimumChainWork.GetHex()),
535  argsman.AddArg(
536  "-par=<n>",
537  strprintf("Set the number of script verification threads (%u to %d, 0 "
538  "= auto, <0 = leave that many cores free, default: %d)",
542  argsman.AddArg("-persistmempool",
543  strprintf("Whether to save the mempool on shutdown and load "
544  "on restart (default: %u)",
547  argsman.AddArg(
548  "-pid=<file>",
549  strprintf("Specify pid file. Relative paths will be prefixed "
550  "by a net-specific datadir location. (default: %s)",
553  argsman.AddArg(
554  "-prune=<n>",
555  strprintf("Reduce storage requirements by enabling pruning (deleting) "
556  "of old blocks. This allows the pruneblockchain RPC to be "
557  "called to delete specific blocks, and enables automatic "
558  "pruning of old blocks if a target size in MiB is provided. "
559  "This mode is incompatible with -txindex and -rescan. "
560  "Warning: Reverting this setting requires re-downloading the "
561  "entire blockchain. (default: 0 = disable pruning blocks, 1 "
562  "= allow manual pruning via RPC, >=%u = automatically prune "
563  "block files to stay under the specified target size in MiB)",
564  MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024),
566  argsman.AddArg(
567  "-reindex-chainstate",
568  "Rebuild chain state from the currently indexed blocks. When "
569  "in pruning mode or if blocks on disk might be corrupted, use "
570  "full -reindex instead.",
572  argsman.AddArg(
573  "-reindex",
574  "Rebuild chain state and block index from the blk*.dat files on disk",
576  argsman.AddArg(
577  "-settings=<file>",
578  strprintf(
579  "Specify path to dynamic settings data file. Can be disabled with "
580  "-nosettings. File is written at runtime and not meant to be "
581  "edited by users (use %s instead for custom settings). Relative "
582  "paths will be prefixed by datadir location. (default: %s)",
585 #ifndef WIN32
586  argsman.AddArg(
587  "-sysperms",
588  "Create new files with system default permissions, instead of umask "
589  "077 (only effective with disabled wallet functionality)",
591 #else
592  hidden_args.emplace_back("-sysperms");
593 #endif
594  argsman.AddArg("-txindex",
595  strprintf("Maintain a full transaction index, used by the "
596  "getrawtransaction rpc call (default: %d)",
599  argsman.AddArg(
600  "-blockfilterindex=<type>",
601  strprintf("Maintain an index of compact filters by block "
602  "(default: %s, values: %s).",
604  " If <type> is not supplied or if <type> = 1, indexes for "
605  "all known types are enabled.",
607  argsman.AddArg(
608  "-usecashaddr",
609  "Use Cash Address for destination encoding instead of base58 "
610  "(activate by default on Jan, 14)",
612 
613  argsman.AddArg(
614  "-addnode=<ip>",
615  "Add a node to connect to and attempt to keep the connection "
616  "open (see the `addnode` RPC command help for more info)",
619  argsman.AddArg("-asmap=<file>",
620  strprintf("Specify asn mapping used for bucketing of the "
621  "peers (default: %s). Relative paths will be "
622  "prefixed by the net-specific datadir location.",
625  argsman.AddArg("-bantime=<n>",
626  strprintf("Default duration (in seconds) of manually "
627  "configured bans (default: %u)",
630  argsman.AddArg("-bind=<addr>",
631  "Bind to given address and always listen on it. Use "
632  "[host]:port notation for IPv6",
635  argsman.AddArg(
636  "-connect=<ip>",
637  "Connect only to the specified node(s); -connect=0 disables automatic "
638  "connections (the rules for this peer are the same as for -addnode)",
641  argsman.AddArg(
642  "-discover",
643  "Discover own IP addresses (default: 1 when listening and no "
644  "-externalip or -proxy)",
646  argsman.AddArg("-dns",
647  strprintf("Allow DNS lookups for -addnode, -seednode and "
648  "-connect (default: %d)",
651  argsman.AddArg(
652  "-dnsseed",
653  "Query for peer addresses via DNS lookup, if low on addresses "
654  "(default: 1 unless -connect used)",
656 
657  argsman.AddArg("-externalip=<ip>", "Specify your own public address",
659  argsman.AddArg(
660  "-forcednsseed",
661  strprintf(
662  "Always query for peer addresses via DNS lookup (default: %d)",
665  argsman.AddArg(
666  "-listen",
667  "Accept connections from outside (default: 1 if no -proxy or -connect)",
669  argsman.AddArg(
670  "-listenonion",
671  strprintf("Automatically create Tor hidden service (default: %d)",
674  argsman.AddArg(
675  "-maxconnections=<n>",
676  strprintf("Maintain at most <n> connections to peers. The effective "
677  "limit depends on system limitations and might be lower than "
678  "the specified value (default: %u)",
681  argsman.AddArg("-maxreceivebuffer=<n>",
682  strprintf("Maximum per-connection receive buffer, <n>*1000 "
683  "bytes (default: %u)",
686  argsman.AddArg(
687  "-maxsendbuffer=<n>",
688  strprintf(
689  "Maximum per-connection send buffer, <n>*1000 bytes (default: %u)",
692  argsman.AddArg(
693  "-maxtimeadjustment",
694  strprintf("Maximum allowed median peer time offset adjustment. Local "
695  "perspective of time may be influenced by peers forward or "
696  "backward by this amount. (default: %u seconds)",
699  argsman.AddArg("-onion=<ip:port>",
700  strprintf("Use separate SOCKS5 proxy to reach peers via Tor "
701  "hidden services (default: %s)",
702  "-proxy"),
704  argsman.AddArg(
705  "-onlynet=<net>",
706  "Make outgoing connections only through network <net> (ipv4, ipv6 or "
707  "onion). Incoming connections are not affected by this option. This "
708  "option can be specified multiple times to allow multiple networks.",
710  argsman.AddArg("-peerbloomfilters",
711  strprintf("Support filtering of blocks and transaction with "
712  "bloom filters (default: %d)",
715  argsman.AddArg(
716  "-peerblockfilters",
717  strprintf(
718  "Serve compact block filters to peers per BIP 157 (default: %u)",
721  argsman.AddArg("-permitbaremultisig",
722  strprintf("Relay non-P2SH multisig (default: %d)",
725  argsman.AddArg("-port=<port>",
726  strprintf("Listen for connections on <port> (default: %u, "
727  "testnet: %u, regtest: %u)",
728  defaultChainParams->GetDefaultPort(),
729  testnetChainParams->GetDefaultPort(),
730  regtestChainParams->GetDefaultPort()),
733  argsman.AddArg("-proxy=<ip:port>", "Connect through SOCKS5 proxy",
735  argsman.AddArg(
736  "-proxyrandomize",
737  strprintf("Randomize credentials for every proxy connection. "
738  "This enables Tor stream isolation (default: %d)",
741  argsman.AddArg(
742  "-seednode=<ip>",
743  "Connect to a node to retrieve peer addresses, and disconnect",
745  argsman.AddArg("-timeout=<n>",
746  strprintf("Specify connection timeout in milliseconds "
747  "(minimum: 1, default: %d)",
750  argsman.AddArg(
751  "-peertimeout=<n>",
752  strprintf("Specify p2p connection timeout in seconds. This option "
753  "determines the amount of time a peer may be inactive before "
754  "the connection to it is dropped. (minimum: 1, default: %d)",
757  argsman.AddArg(
758  "-torcontrol=<ip>:<port>",
759  strprintf(
760  "Tor control port to use if onion listening enabled (default: %s)",
763  argsman.AddArg("-torpassword=<pass>",
764  "Tor control port password (default: empty)",
767 #ifdef USE_UPNP
768 #if USE_UPNP
769  argsman.AddArg("-upnp",
770  "Use UPnP to map the listening port (default: 1 when "
771  "listening and no -proxy)",
773 #else
774  argsman.AddArg(
775  "-upnp",
776  strprintf("Use UPnP to map the listening port (default: %u)", 0),
778 #endif
779 #else
780  hidden_args.emplace_back("-upnp");
781 #endif
782  argsman.AddArg(
783  "-whitebind=<[[email protected]]addr>",
784  "Bind to given address and whitelist peers connecting to it."
785  " Use [host]:port notation for IPv6. Allowed permissions are "
786  "bloomfilter (allow requesting BIP37 filtered blocks and "
787  "transactions), noban (do not ban for misbehavior), "
788  "forcerelay (relay even non-standard transactions), "
789  "relay (relay even in -blocksonly mode), "
790  "and mempool (allow requesting BIP35 mempool contents). "
791  "Specify multiple permissions separated by commas (default: "
792  "noban,mempool,relay). Can be specified multiple times.",
794 
795  argsman.AddArg("-whitelist=<[[email protected]]IP address or network>",
796  "Whitelist peers connecting from the given IP address "
797  "(e.g. 1.2.3.4) or CIDR notated network(e.g. 1.2.3.0/24). "
798  "Uses same permissions as -whitebind. Can be specified "
799  "multiple times.",
801  argsman.AddArg(
802  "-maxuploadtarget=<n>",
803  strprintf("Tries to keep outbound traffic under the given target (in "
804  "MiB per 24h), 0 = no limit (default: %d)",
807 
809 
810 #if ENABLE_ZMQ
811  argsman.AddArg("-zmqpubhashblock=<address>",
812  "Enable publish hash block in <address>",
814  argsman.AddArg("-zmqpubhashtx=<address>",
815  "Enable publish hash transaction in <address>",
817  argsman.AddArg("-zmqpubrawblock=<address>",
818  "Enable publish raw block in <address>",
820  argsman.AddArg("-zmqpubrawtx=<address>",
821  "Enable publish raw transaction in <address>",
823  argsman.AddArg(
824  "-zmqpubhashblockhwm=<n>",
825  strprintf("Set publish hash block outbound message high water "
826  "mark (default: %d)",
828  false, OptionsCategory::ZMQ);
829  argsman.AddArg(
830  "-zmqpubhashtxhwm=<n>",
831  strprintf("Set publish hash transaction outbound message high "
832  "water mark (default: %d)",
834  false, OptionsCategory::ZMQ);
835  argsman.AddArg(
836  "-zmqpubrawblockhwm=<n>",
837  strprintf("Set publish raw block outbound message high water "
838  "mark (default: %d)",
840  false, OptionsCategory::ZMQ);
841  argsman.AddArg(
842  "-zmqpubrawtxhwm=<n>",
843  strprintf("Set publish raw transaction outbound message high "
844  "water mark (default: %d)",
846  false, OptionsCategory::ZMQ);
847 #else
848  hidden_args.emplace_back("-zmqpubhashblock=<address>");
849  hidden_args.emplace_back("-zmqpubhashtx=<address>");
850  hidden_args.emplace_back("-zmqpubrawblock=<address>");
851  hidden_args.emplace_back("-zmqpubrawtx=<address>");
852  hidden_args.emplace_back("-zmqpubhashblockhwm=<n>");
853  hidden_args.emplace_back("-zmqpubhashtxhwm=<n>");
854  hidden_args.emplace_back("-zmqpubrawblockhwm=<n>");
855  hidden_args.emplace_back("-zmqpubrawtxhwm=<n>");
856 #endif
857 
858  argsman.AddArg(
859  "-checkblocks=<n>",
860  strprintf("How many blocks to check at startup (default: %u, 0 = all)",
864  argsman.AddArg(
865  "-checklevel=<n>",
866  strprintf("How thorough the block verification of "
867  "-checkblocks is: "
868  "level 0 reads the blocks from disk, "
869  "level 1 verifies block validity, "
870  "level 2 verifies undo data, "
871  "level 3 checks disconnection of tip blocks, "
872  "and level 4 tries to reconnect the blocks. "
873  "Each level includes the checks of the previous levels "
874  "(0-4, default: %u)",
878  argsman.AddArg("-checkblockindex",
879  strprintf("Do a consistency check for the block tree, "
880  "chainstate, and other validation data structures "
881  "occasionally. (default: %u, regtest: %u)",
882  defaultChainParams->DefaultConsistencyChecks(),
883  regtestChainParams->DefaultConsistencyChecks()),
886  argsman.AddArg(
887  "-checkmempool=<n>",
888  strprintf(
889  "Run checks every <n> transactions (default: %u, regtest: %u)",
890  defaultChainParams->DefaultConsistencyChecks(),
891  regtestChainParams->DefaultConsistencyChecks()),
894  argsman.AddArg("-checkpoints",
895  strprintf("Only accept block chain matching built-in "
896  "checkpoints (default: %d)",
900  argsman.AddArg("-deprecatedrpc=<method>",
901  "Allows deprecated RPC method(s) to be used",
904  argsman.AddArg("-dropmessagestest=<n>",
905  "Randomly drop 1 of every <n> network messages",
908  argsman.AddArg(
909  "-stopafterblockimport",
910  strprintf("Stop running after importing blocks from disk (default: %d)",
914  argsman.AddArg("-stopatheight",
915  strprintf("Stop running after reaching the given height in "
916  "the main chain (default: %u)",
920  argsman.AddArg(
921  "-limitancestorcount=<n>",
922  strprintf("Do not accept transactions if number of in-mempool "
923  "ancestors is <n> or more (default: %u)",
927  argsman.AddArg(
928  "-limitancestorsize=<n>",
929  strprintf("Do not accept transactions whose size with all in-mempool "
930  "ancestors exceeds <n> kilobytes (default: %u)",
934  argsman.AddArg(
935  "-limitdescendantcount=<n>",
936  strprintf("Do not accept transactions if any ancestor would have <n> "
937  "or more in-mempool descendants (default: %u)",
941  argsman.AddArg(
942  "-limitdescendantsize=<n>",
943  strprintf("Do not accept transactions if any ancestor would have more "
944  "than <n> kilobytes of in-mempool descendants (default: %u).",
948  argsman.AddArg("-addrmantest", "Allows to test address relay on localhost",
951 
952  argsman.AddArg("-debug=<category>",
953  strprintf("Output debugging information (default: %u, "
954  "supplying <category> is optional)",
955  0) +
956  ". " +
957  "If <category> is not supplied or if <category> = 1, "
958  "output all debugging information."
959  "<category> can be: " +
960  ListLogCategories() + ".",
962  argsman.AddArg(
963  "-debugexclude=<category>",
964  strprintf("Exclude debugging information for a category. Can be used "
965  "in conjunction with -debug=1 to output debug logs for all "
966  "categories except one or more specified categories."),
968  argsman.AddArg(
969  "-logips",
970  strprintf("Include IP addresses in debug output (default: %d)",
973  argsman.AddArg(
974  "-logtimestamps",
975  strprintf("Prepend debug output with timestamp (default: %d)",
978  argsman.AddArg(
979  "-logthreadnames",
980  strprintf(
981  "Prepend debug output with name of the originating thread (only "
982  "available on platforms supporting thread_local) (default: %u)",
985  argsman.AddArg(
986  "-logtimemicros",
987  strprintf("Add microsecond precision to debug timestamps (default: %d)",
991  argsman.AddArg("-mocktime=<n>",
992  "Replace actual time with " + UNIX_EPOCH_TIME +
993  " (default: 0)",
996  argsman.AddArg(
997  "-maxsigcachesize=<n>",
998  strprintf("Limit size of signature cache to <n> MiB (default: %u)",
1002  argsman.AddArg(
1003  "-maxscriptcachesize=<n>",
1004  strprintf("Limit size of script cache to <n> MiB (default: %u)",
1008  argsman.AddArg("-maxtipage=<n>",
1009  strprintf("Maximum tip age in seconds to consider node in "
1010  "initial block download (default: %u)",
1014 
1015  argsman.AddArg(
1016  "-printtoconsole",
1017  "Send trace/debug info to console instead of debug.log file (default: "
1018  "1 when no -daemon. To disable logging to file, set debuglogfile=0)",
1020  argsman.AddArg("-printpriority",
1021  strprintf("Log transaction priority and fee per kB when "
1022  "mining blocks (default: %d)",
1026  argsman.AddArg(
1027  "-shrinkdebugfile",
1028  "Shrink debug.log file on client startup (default: 1 when no -debug)",
1030 
1031  argsman.AddArg("-uacomment=<cmt>",
1032  "Append comment to the user agent string",
1034 
1035  SetupChainParamsBaseOptions(argsman);
1036 
1037  argsman.AddArg(
1038  "-acceptnonstdtxn",
1039  strprintf(
1040  "Relay and mine \"non-standard\" transactions (%sdefault: %u)",
1041  "testnet/regtest only; ", defaultChainParams->RequireStandard()),
1044  argsman.AddArg("-excessiveblocksize=<n>",
1045  strprintf("Do not accept blocks larger than this limit, in "
1046  "bytes (default: %d)",
1050  argsman.AddArg(
1051  "-dustrelayfee=<amt>",
1052  strprintf("Fee rate (in %s/kB) used to define dust, the value of an "
1053  "output such that it will cost about 1/3 of its value in "
1054  "fees at this fee rate to spend it. (default: %s)",
1058 
1059  argsman.AddArg("-bytespersigop",
1060  strprintf("Equivalent bytes per sigop in transactions for "
1061  "relay and mining (default: %u)",
1064  argsman.AddArg(
1065  "-datacarrier",
1066  strprintf("Relay and mine data carrier transactions (default: %d)",
1069  argsman.AddArg(
1070  "-datacarriersize",
1071  strprintf("Maximum size of data in data carrier transactions "
1072  "we relay and mine (default: %u)",
1075  argsman.AddArg(
1076  "-minrelaytxfee=<amt>",
1077  strprintf("Fees (in %s/kB) smaller than this are rejected for "
1078  "relaying, mining and transaction creation (default: %s)",
1081  argsman.AddArg(
1082  "-whitelistrelay",
1083  strprintf("Add 'relay' permission to whitelisted inbound peers "
1084  "with default permissions. This will accept relayed "
1085  "transactions even when not relaying transactions "
1086  "(default: %d)",
1089  argsman.AddArg(
1090  "-whitelistforcerelay",
1091  strprintf("Add 'forcerelay' permission to whitelisted inbound peers"
1092  " with default permissions. This will relay transactions "
1093  "even if the transactions were already in the mempool or "
1094  "violate local relay policy (default: %d)",
1097 
1098  // Not sure this really belongs here, but it will do for now.
1099  // FIXME: This doesn't work anyways.
1100  argsman.AddArg("-excessutxocharge=<amt>",
1101  strprintf("Fees (in %s/kB) to charge per utxo created for "
1102  "relaying, and mining (default: %s)",
1106 
1107  argsman.AddArg("-blockmaxsize=<n>",
1108  strprintf("Set maximum block size in bytes (default: %d)",
1111  argsman.AddArg(
1112  "-blockmintxfee=<amt>",
1113  strprintf("Set lowest fee rate (in %s/kB) for transactions to "
1114  "be included in block creation. (default: %s)",
1117 
1118  argsman.AddArg("-blockversion=<n>",
1119  "Override block version to test forking scenarios",
1122 
1123  argsman.AddArg("-server", "Accept command line and JSON-RPC commands",
1125  argsman.AddArg("-rest",
1126  strprintf("Accept public REST requests (default: %d)",
1129  argsman.AddArg(
1130  "-rpcbind=<addr>[:port]",
1131  "Bind to given address to listen for JSON-RPC connections. Do not "
1132  "expose the RPC server to untrusted networks such as the public "
1133  "internet! This option is ignored unless -rpcallowip is also passed. "
1134  "Port is optional and overrides -rpcport. Use [host]:port notation "
1135  "for IPv6. This option can be specified multiple times (default: "
1136  "127.0.0.1 and ::1 i.e., localhost)",
1140  argsman.AddArg(
1141  "-rpccookiefile=<loc>",
1142  "Location of the auth cookie. Relative paths will be prefixed "
1143  "by a net-specific datadir location. (default: data dir)",
1145  argsman.AddArg("-rpcuser=<user>", "Username for JSON-RPC connections",
1148  argsman.AddArg("-rpcpassword=<pw>", "Password for JSON-RPC connections",
1151  argsman.AddArg(
1152  "-rpcwhitelist=<whitelist>",
1153  "Set a whitelist to filter incoming RPC calls for a specific user. The "
1154  "field <whitelist> comes in the format: <USERNAME>:<rpc 1>,<rpc "
1155  "2>,...,<rpc n>. If multiple whitelists are set for a given user, they "
1156  "are set-intersected. See -rpcwhitelistdefault documentation for "
1157  "information on default whitelist behavior.",
1159  argsman.AddArg(
1160  "-rpcwhitelistdefault",
1161  "Sets default behavior for rpc whitelisting. Unless "
1162  "rpcwhitelistdefault is set to 0, if any -rpcwhitelist is set, the rpc "
1163  "server acts as if all rpc users are subject to "
1164  "empty-unless-otherwise-specified whitelists. If rpcwhitelistdefault "
1165  "is set to 1 and no -rpcwhitelist is set, rpc server acts as if all "
1166  "rpc users are subject to empty whitelists.",
1168  argsman.AddArg(
1169  "-rpcauth=<userpw>",
1170  "Username and HMAC-SHA-256 hashed password for JSON-RPC connections. "
1171  "The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A "
1172  "canonical python script is included in share/rpcauth. The client then "
1173  "connects normally using the rpcuser=<USERNAME>/rpcpassword=<PASSWORD> "
1174  "pair of arguments. This option can be specified multiple times",
1176  argsman.AddArg("-rpcport=<port>",
1177  strprintf("Listen for JSON-RPC connections on <port> "
1178  "(default: %u, testnet: %u, regtest: %u)",
1179  defaultBaseParams->RPCPort(),
1180  testnetBaseParams->RPCPort(),
1181  regtestBaseParams->RPCPort()),
1184  argsman.AddArg(
1185  "-rpcallowip=<ip>",
1186  "Allow JSON-RPC connections from specified source. Valid for "
1187  "<ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. "
1188  "1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). "
1189  "This option can be specified multiple times",
1191  argsman.AddArg(
1192  "-rpcthreads=<n>",
1193  strprintf(
1194  "Set the number of threads to service RPC calls (default: %d)",
1197  argsman.AddArg(
1198  "-rpccorsdomain=value",
1199  "Domain from which to accept cross origin requests (browser enforced)",
1201 
1202  argsman.AddArg("-rpcworkqueue=<n>",
1203  strprintf("Set the depth of the work queue to service RPC "
1204  "calls (default: %d)",
1208  argsman.AddArg("-rpcservertimeout=<n>",
1209  strprintf("Timeout during HTTP requests (default: %d)",
1213 
1214 #if HAVE_DECL_DAEMON
1215  argsman.AddArg("-daemon",
1216  "Run in the background as a daemon and accept commands",
1218 #else
1219  hidden_args.emplace_back("-daemon");
1220 #endif
1221 
1222  // Avalanche options.
1223  argsman.AddArg(
1224  "-enableavalanche",
1225  strprintf("Enable avalanche (default: %u)", AVALANCHE_DEFAULT_ENABLED),
1227  argsman.AddArg(
1228  "-avacooldown",
1229  strprintf("Mandatory cooldown between two avapoll (default: %u)",
1232  argsman.AddArg("-avaproof",
1233  "Avalanche proof to be used by this node (default: none)",
1235  argsman.AddArg("-avamasterkey",
1236  "Master key associated with the proof. If a proof is "
1237  "required, this is mandatory.",
1239  argsman.AddArg("-avasessionkey", "Avalanche session key (default: random)",
1241 
1242  // Add the hidden options
1243  argsman.AddHiddenArgs(hidden_args);
1244 }
1245 
1246 std::string LicenseInfo() {
1247  const std::string URL_SOURCE_CODE =
1248  "<https://github.com/Bitcoin-ABC/bitcoin-abc>";
1249  const std::string URL_WEBSITE = "<https://www.bitcoinabc.org>";
1250 
1251  return CopyrightHolders(strprintf(_("Copyright (C) %i-%i").translated, 2009,
1252  COPYRIGHT_YEAR) +
1253  " ") +
1254  "\n" + "\n" +
1255  strprintf(_("Please contribute if you find %s useful. "
1256  "Visit %s for further information about the software.")
1257  .translated,
1258  PACKAGE_NAME, URL_WEBSITE) +
1259  "\n" +
1260  strprintf(_("The source code is available from %s.").translated,
1261  URL_SOURCE_CODE) +
1262  "\n" + "\n" + _("This is experimental software.").translated + "\n" +
1263  strprintf(_("Distributed under the MIT software license, see the "
1264  "accompanying file %s or %s")
1265  .translated,
1266  "COPYING", "<https://opensource.org/licenses/MIT>") +
1267  "\n" + "\n" +
1268  strprintf(_("This product includes software developed by the "
1269  "OpenSSL Project for use in the OpenSSL Toolkit %s and "
1270  "cryptographic software written by Eric Young and UPnP "
1271  "software written by Thomas Bernard.")
1272  .translated,
1273  "<https://www.openssl.org>") +
1274  "\n";
1275 }
1276 
1277 static bool fHaveGenesis = false;
1279 static std::condition_variable g_genesis_wait_cv;
1280 
1281 static void BlockNotifyGenesisWait(const CBlockIndex *pBlockIndex) {
1282  if (pBlockIndex != nullptr) {
1283  {
1284  LOCK(g_genesis_wait_mutex);
1285  fHaveGenesis = true;
1286  }
1287  g_genesis_wait_cv.notify_all();
1288  }
1289 }
1290 
1293  assert(fImporting == false);
1294  fImporting = true;
1295  }
1296 
1298  assert(fImporting == true);
1299  fImporting = false;
1300  }
1301 };
1302 
1303 // If we're using -prune with -reindex, then delete block files that will be
1304 // ignored by the reindex. Since reindexing works by starting at block file 0
1305 // and looping until a blockfile is missing, do the same here to delete any
1306 // later block files after a gap. Also delete all rev files since they'll be
1307 // rewritten by the reindex anyway. This ensures that vinfoBlockFile is in sync
1308 // with what's actually on disk by the time we start downloading, so that
1309 // pruning works correctly.
1310 static void CleanupBlockRevFiles() {
1311  std::map<std::string, fs::path> mapBlockFiles;
1312 
1313  // Glob all blk?????.dat and rev?????.dat files from the blocks directory.
1314  // Remove the rev files immediately and insert the blk file paths into an
1315  // ordered map keyed by block file index.
1316  LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for "
1317  "-reindex with -prune\n");
1318  const auto directoryIterator = fs::directory_iterator{GetBlocksDir()};
1319  for (const auto &file : directoryIterator) {
1320  const auto fileName = file.path().filename().string();
1321  if (fs::is_regular_file(file) && fileName.length() == 12 &&
1322  fileName.substr(8, 4) == ".dat") {
1323  if (fileName.substr(0, 3) == "blk") {
1324  mapBlockFiles[fileName.substr(3, 5)] = file.path();
1325  } else if (fileName.substr(0, 3) == "rev") {
1326  remove(file.path());
1327  }
1328  }
1329  }
1330 
1331  // Remove all block files that aren't part of a contiguous set starting at
1332  // zero by walking the ordered map (keys are block file indices) by keeping
1333  // a separate counter. Once we hit a gap (or if 0 doesn't exist) start
1334  // removing block files.
1335  int contiguousCounter = 0;
1336  for (const auto &item : mapBlockFiles) {
1337  if (atoi(item.first) == contiguousCounter) {
1338  contiguousCounter++;
1339  continue;
1340  }
1341  remove(item.second);
1342  }
1343 }
1344 
1345 static void ThreadImport(const Config &config, ChainstateManager &chainman,
1346  std::vector<fs::path> vImportFiles,
1347  const ArgsManager &args) {
1348  util::ThreadRename("loadblk");
1350 
1351  {
1352  const CChainParams &chainParams = config.GetChainParams();
1353 
1354  CImportingNow imp;
1355 
1356  // -reindex
1357  if (fReindex) {
1358  int nFile = 0;
1359  while (true) {
1360  FlatFilePos pos(nFile, 0);
1361  if (!fs::exists(GetBlockPosFilename(pos))) {
1362  // No block files left to reindex
1363  break;
1364  }
1365  FILE *file = OpenBlockFile(pos, true);
1366  if (!file) {
1367  // This error is logged in OpenBlockFile
1368  break;
1369  }
1370  LogPrintf("Reindexing block file blk%05u.dat...\n",
1371  (unsigned int)nFile);
1372  LoadExternalBlockFile(config, file, &pos);
1373  nFile++;
1374  }
1375  pblocktree->WriteReindexing(false);
1376  fReindex = false;
1377  LogPrintf("Reindexing finished\n");
1378  // To avoid ending up in a situation without genesis block, re-try
1379  // initializing (no-op if reindexing worked):
1380  LoadGenesisBlock(chainParams);
1381  }
1382 
1383  // -loadblock=
1384  for (const fs::path &path : vImportFiles) {
1385  FILE *file = fsbridge::fopen(path, "rb");
1386  if (file) {
1387  LogPrintf("Importing blocks file %s...\n", path.string());
1388  LoadExternalBlockFile(config, file);
1389  } else {
1390  LogPrintf("Warning: Could not open blocks file %s\n",
1391  path.string());
1392  }
1393  }
1394 
1395  // Reconsider blocks we know are valid. They may have been marked
1396  // invalid by, for instance, running an outdated version of the node
1397  // software.
1398  const MapCheckpoints &checkpoints =
1399  chainParams.Checkpoints().mapCheckpoints;
1400  for (const MapCheckpoints::value_type &i : checkpoints) {
1401  const BlockHash &hash = i.second;
1402 
1403  LOCK(cs_main);
1404  CBlockIndex *pblockindex = LookupBlockIndex(hash);
1405  if (pblockindex && !pblockindex->nStatus.isValid()) {
1406  LogPrintf("Reconsidering checkpointed block %s ...\n",
1407  hash.GetHex());
1408  ResetBlockFailureFlags(pblockindex);
1409  }
1410  }
1411 
1412  // scan for better chains in the block chain database, that are not yet
1413  // connected in the active best chain
1414 
1415  // We can't hold cs_main during ActivateBestChain even though we're
1416  // accessing the chainman unique_ptrs since ABC requires us not to be
1417  // holding cs_main, so retrieve the relevant pointers before the ABC
1418  // call.
1419  for (CChainState *chainstate :
1420  WITH_LOCK(::cs_main, return chainman.GetAll())) {
1421  BlockValidationState state;
1422  if (!chainstate->ActivateBestChain(config, state, nullptr)) {
1423  LogPrintf("Failed to connect best block (%s)\n",
1424  state.ToString());
1425  StartShutdown();
1426  return;
1427  }
1428  }
1429 
1430  if (args.GetBoolArg("-stopafterblockimport",
1432  LogPrintf("Stopping after block import\n");
1433  StartShutdown();
1434  return;
1435  }
1436  } // End scope of CImportingNow
1437  if (args.GetArg("-persistmempool", DEFAULT_PERSIST_MEMPOOL)) {
1438  LoadMempool(config, ::g_mempool);
1439  }
1441 }
1442 
1447 static bool InitSanityCheck() {
1448  if (!ECC_InitSanityCheck()) {
1449  return InitError(Untranslated(
1450  "Elliptic curve cryptography sanity check failure. Aborting."));
1451  }
1452 
1453  if (!glibcxx_sanity_test()) {
1454  return false;
1455  }
1456 
1457  if (!Random_SanityCheck()) {
1458  return InitError(Untranslated(
1459  "OS cryptographic RNG sanity check failure. Aborting."));
1460  }
1461 
1462  return true;
1463 }
1464 
1465 static bool AppInitServers(Config &config,
1466  HTTPRPCRequestProcessor &httpRPCRequestProcessor,
1467  NodeContext &node) {
1468  const ArgsManager &args = *Assert(node.args);
1471  if (!InitHTTPServer(config)) {
1472  return false;
1473  }
1474 
1475  StartRPC();
1477 
1478  if (!StartHTTPRPC(httpRPCRequestProcessor)) {
1479  return false;
1480  }
1481  if (args.GetBoolArg("-rest", DEFAULT_REST_ENABLE)) {
1482  StartREST(httpRPCRequestProcessor.context);
1483  }
1484 
1485  StartHTTPServer();
1486  return true;
1487 }
1488 
1489 // Parameter interaction based on rules
1491  // when specifying an explicit binding address, you want to listen on it
1492  // even when -connect or -proxy is specified.
1493  if (args.IsArgSet("-bind")) {
1494  if (args.SoftSetBoolArg("-listen", true)) {
1495  LogPrintf(
1496  "%s: parameter interaction: -bind set -> setting -listen=1\n",
1497  __func__);
1498  }
1499  }
1500  if (args.IsArgSet("-whitebind")) {
1501  if (args.SoftSetBoolArg("-listen", true)) {
1502  LogPrintf("%s: parameter interaction: -whitebind set -> setting "
1503  "-listen=1\n",
1504  __func__);
1505  }
1506  }
1507 
1508  if (args.IsArgSet("-connect")) {
1509  // when only connecting to trusted nodes, do not seed via DNS, or listen
1510  // by default.
1511  if (args.SoftSetBoolArg("-dnsseed", false)) {
1512  LogPrintf("%s: parameter interaction: -connect set -> setting "
1513  "-dnsseed=0\n",
1514  __func__);
1515  }
1516  if (args.SoftSetBoolArg("-listen", false)) {
1517  LogPrintf("%s: parameter interaction: -connect set -> setting "
1518  "-listen=0\n",
1519  __func__);
1520  }
1521  }
1522 
1523  if (args.IsArgSet("-proxy")) {
1524  // to protect privacy, do not listen by default if a default proxy
1525  // server is specified.
1526  if (args.SoftSetBoolArg("-listen", false)) {
1527  LogPrintf(
1528  "%s: parameter interaction: -proxy set -> setting -listen=0\n",
1529  __func__);
1530  }
1531  // to protect privacy, do not use UPNP when a proxy is set. The user may
1532  // still specify -listen=1 to listen locally, so don't rely on this
1533  // happening through -listen below.
1534  if (args.SoftSetBoolArg("-upnp", false)) {
1535  LogPrintf(
1536  "%s: parameter interaction: -proxy set -> setting -upnp=0\n",
1537  __func__);
1538  }
1539  // to protect privacy, do not discover addresses by default
1540  if (args.SoftSetBoolArg("-discover", false)) {
1541  LogPrintf("%s: parameter interaction: -proxy set -> setting "
1542  "-discover=0\n",
1543  __func__);
1544  }
1545  }
1546 
1547  if (!args.GetBoolArg("-listen", DEFAULT_LISTEN)) {
1548  // do not map ports or try to retrieve public IP when not listening
1549  // (pointless)
1550  if (args.SoftSetBoolArg("-upnp", false)) {
1551  LogPrintf(
1552  "%s: parameter interaction: -listen=0 -> setting -upnp=0\n",
1553  __func__);
1554  }
1555  if (args.SoftSetBoolArg("-discover", false)) {
1556  LogPrintf(
1557  "%s: parameter interaction: -listen=0 -> setting -discover=0\n",
1558  __func__);
1559  }
1560  if (args.SoftSetBoolArg("-listenonion", false)) {
1561  LogPrintf("%s: parameter interaction: -listen=0 -> setting "
1562  "-listenonion=0\n",
1563  __func__);
1564  }
1565  }
1566 
1567  if (args.IsArgSet("-externalip")) {
1568  // if an explicit public IP is specified, do not try to find others
1569  if (args.SoftSetBoolArg("-discover", false)) {
1570  LogPrintf("%s: parameter interaction: -externalip set -> setting "
1571  "-discover=0\n",
1572  __func__);
1573  }
1574  }
1575 
1576  // disable whitelistrelay in blocksonly mode
1577  if (args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY)) {
1578  if (args.SoftSetBoolArg("-whitelistrelay", false)) {
1579  LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting "
1580  "-whitelistrelay=0\n",
1581  __func__);
1582  }
1583  }
1584 
1585  // Forcing relay from whitelisted hosts implies we will accept relays from
1586  // them in the first place.
1587  if (args.GetBoolArg("-whitelistforcerelay", DEFAULT_WHITELISTFORCERELAY)) {
1588  if (args.SoftSetBoolArg("-whitelistrelay", true)) {
1589  LogPrintf("%s: parameter interaction: -whitelistforcerelay=1 -> "
1590  "setting -whitelistrelay=1\n",
1591  __func__);
1592  }
1593  }
1594 }
1595 
1602 void InitLogging(const ArgsManager &args) {
1603  LogInstance().m_print_to_file = !args.IsArgNegated("-debuglogfile");
1605  AbsPathForConfigVal(args.GetArg("-debuglogfile", DEFAULT_DEBUGLOGFILE));
1606 
1608  args.GetBoolArg("-printtoconsole", !args.GetBoolArg("-daemon", false));
1610  args.GetBoolArg("-logtimestamps", DEFAULT_LOGTIMESTAMPS);
1612  args.GetBoolArg("-logtimemicros", DEFAULT_LOGTIMEMICROS);
1614  args.GetBoolArg("-logthreadnames", DEFAULT_LOGTHREADNAMES);
1615 
1616  fLogIPs = args.GetBoolArg("-logips", DEFAULT_LOGIPS);
1617 
1618  std::string version_string = FormatFullVersion();
1619 #ifdef DEBUG
1620  version_string += " (debug build)";
1621 #else
1622  version_string += " (release build)";
1623 #endif
1624  LogPrintf("%s version %s\n", CLIENT_NAME, version_string);
1625 }
1626 
1627 namespace { // Variables internal to initialization process only
1628 
1629 int nMaxConnections;
1630 int nUserMaxConnections;
1631 int nFD;
1633 int64_t peer_connect_timeout;
1634 std::set<BlockFilterType> g_enabled_filter_types;
1635 
1636 } // namespace
1637 
1638 [[noreturn]] static void new_handler_terminate() {
1639  // Rather than throwing std::bad-alloc if allocation fails, terminate
1640  // immediately to (try to) avoid chain corruption. Since LogPrintf may
1641  // itself allocate memory, set the handler directly to terminate first.
1642  std::set_new_handler(std::terminate);
1643  LogPrintf("Error: Out of memory. Terminating.\n");
1644 
1645  // The log was successful, terminate now.
1646  std::terminate();
1647 };
1648 
1650 // Step 1: setup
1651 #ifdef _MSC_VER
1652  // Turn off Microsoft heap dump noise
1653  _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
1654  _CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, nullptr,
1655  OPEN_EXISTING, 0, 0));
1656  // Disable confusing "helpful" text message on abort, Ctrl-C
1657  _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
1658 #endif
1659 #ifdef WIN32
1660  // Enable Data Execution Prevention (DEP)
1661  SetProcessDEPPolicy(PROCESS_DEP_ENABLE);
1662 #endif
1663 
1664  if (!SetupNetworking()) {
1665  return InitError(Untranslated("Initializing networking failed"));
1666  }
1667 
1668 #ifndef WIN32
1669  if (!args.GetBoolArg("-sysperms", false)) {
1670  umask(077);
1671  }
1672 
1673  // Clean shutdown on SIGTERM
1676 
1677  // Reopen debug.log on SIGHUP
1679 
1680  // Ignore SIGPIPE, otherwise it will bring the daemon down if the client
1681  // closes unexpectedly
1682  signal(SIGPIPE, SIG_IGN);
1683 #else
1684  SetConsoleCtrlHandler(consoleCtrlHandler, true);
1685 #endif
1686 
1687  std::set_new_handler(new_handler_terminate);
1688 
1689  return true;
1690 }
1691 
1692 bool AppInitParameterInteraction(Config &config, const ArgsManager &args) {
1693  const CChainParams &chainparams = config.GetChainParams();
1694  // Step 2: parameter interactions
1695 
1696  // also see: InitParameterInteraction()
1697 
1698  // Error if network-specific options (-addnode, -connect, etc) are
1699  // specified in default section of config file, but not overridden
1700  // on the command line or in this network's section of the config file.
1701  std::string network = args.GetChainName();
1702  bilingual_str errors;
1703  for (const auto &arg : args.GetUnsuitableSectionOnlyArgs()) {
1704  errors += strprintf(_("Config setting for %s only applied on %s "
1705  "network when in [%s] section.") +
1706  Untranslated("\n"),
1707  arg, network, network);
1708  }
1709 
1710  if (!errors.empty()) {
1711  return InitError(errors);
1712  }
1713 
1714  // Warn if unrecognized section name are present in the config file.
1715  bilingual_str warnings;
1716  for (const auto &section : args.GetUnrecognizedSections()) {
1717  warnings += strprintf(Untranslated("%s:%i ") +
1718  _("Section [%s] is not recognized.") +
1719  Untranslated("\n"),
1720  section.m_file, section.m_line, section.m_name);
1721  }
1722 
1723  if (!warnings.empty()) {
1724  InitWarning(warnings);
1725  }
1726 
1727  if (!fs::is_directory(GetBlocksDir())) {
1728  return InitError(
1729  strprintf(_("Specified blocks directory \"%s\" does not exist."),
1730  args.GetArg("-blocksdir", "")));
1731  }
1732 
1733  // parse and validate enabled filter types
1734  std::string blockfilterindex_value =
1735  args.GetArg("-blockfilterindex", DEFAULT_BLOCKFILTERINDEX);
1736  if (blockfilterindex_value == "" || blockfilterindex_value == "1") {
1737  g_enabled_filter_types = AllBlockFilterTypes();
1738  } else if (blockfilterindex_value != "0") {
1739  const std::vector<std::string> names =
1740  args.GetArgs("-blockfilterindex");
1741  for (const auto &name : names) {
1742  BlockFilterType filter_type;
1743  if (!BlockFilterTypeByName(name, filter_type)) {
1744  return InitError(
1745  strprintf(_("Unknown -blockfilterindex value %s."), name));
1746  }
1747  g_enabled_filter_types.insert(filter_type);
1748  }
1749  }
1750 
1751  // Signal NODE_COMPACT_FILTERS if peerblockfilters and basic filters index
1752  // are both enabled.
1753  if (gArgs.GetBoolArg("-peerblockfilters", DEFAULT_PEERBLOCKFILTERS)) {
1754  if (g_enabled_filter_types.count(BlockFilterType::BASIC) != 1) {
1755  return InitError(
1756  _("Cannot set -peerblockfilters without -blockfilterindex."));
1757  }
1758 
1759  nLocalServices = ServiceFlags(nLocalServices | NODE_COMPACT_FILTERS);
1760  }
1761 
1762  // if using block pruning, then disallow txindex
1763  if (args.GetArg("-prune", 0)) {
1764  if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
1765  return InitError(_("Prune mode is incompatible with -txindex."));
1766  }
1767  if (!g_enabled_filter_types.empty()) {
1768  return InitError(
1769  _("Prune mode is incompatible with -blockfilterindex."));
1770  }
1771  }
1772 
1773  // -bind and -whitebind can't be set when not listening
1774  size_t nUserBind =
1775  args.GetArgs("-bind").size() + args.GetArgs("-whitebind").size();
1776  if (nUserBind != 0 && !args.GetBoolArg("-listen", DEFAULT_LISTEN)) {
1777  return InitError(Untranslated(
1778  "Cannot set -bind or -whitebind together with -listen=0"));
1779  }
1780 
1781  // Make sure enough file descriptors are available
1782  int nBind = std::max(nUserBind, size_t(1));
1783  nUserMaxConnections =
1784  args.GetArg("-maxconnections", DEFAULT_MAX_PEER_CONNECTIONS);
1785  nMaxConnections = std::max(nUserMaxConnections, 0);
1786 
1787  // Trim requested connection counts, to fit into system limitations
1788  // <int> in std::min<int>(...) to work around FreeBSD compilation issue
1789  // described in #2695
1790  nFD = RaiseFileDescriptorLimit(nMaxConnections + nBind +
1793 #ifdef USE_POLL
1794  int fd_max = nFD;
1795 #else
1796  int fd_max = FD_SETSIZE;
1797 #endif
1798  nMaxConnections =
1799  std::max(std::min<int>(nMaxConnections, fd_max - nBind -
1802  0);
1803  if (nFD < MIN_CORE_FILEDESCRIPTORS) {
1804  return InitError(_("Not enough file descriptors available."));
1805  }
1806  nMaxConnections =
1808  nMaxConnections);
1809 
1810  if (nMaxConnections < nUserMaxConnections) {
1811  // Not categorizing as "Warning" because this is the normal behavior for
1812  // platforms using the select() interface for which FD_SETSIZE is
1813  // usually 1024.
1814  LogPrintf("Reducing -maxconnections from %d to %d, because of system "
1815  "limitations.\n",
1816  nUserMaxConnections, nMaxConnections);
1817  }
1818 
1819  // Step 3: parameter-to-internal-flags
1820  if (args.IsArgSet("-debug")) {
1821  // Special-case: if -debug=0/-nodebug is set, turn off debugging
1822  // messages
1823  const std::vector<std::string> &categories = args.GetArgs("-debug");
1824  if (std::none_of(
1825  categories.begin(), categories.end(),
1826  [](std::string cat) { return cat == "0" || cat == "none"; })) {
1827  for (const auto &cat : categories) {
1828  if (!LogInstance().EnableCategory(cat)) {
1829  InitWarning(
1830  strprintf(_("Unsupported logging category %s=%s."),
1831  "-debug", cat));
1832  }
1833  }
1834  }
1835  }
1836 
1837  // Now remove the logging categories which were explicitly excluded
1838  for (const std::string &cat : args.GetArgs("-debugexclude")) {
1839  if (!LogInstance().DisableCategory(cat)) {
1840  InitWarning(strprintf(_("Unsupported logging category %s=%s."),
1841  "-debugexclude", cat));
1842  }
1843  }
1844 
1845  // Checkmempool and checkblockindex default to true in regtest mode
1846  int ratio = std::min<int>(
1847  std::max<int>(
1848  args.GetArg("-checkmempool",
1849  chainparams.DefaultConsistencyChecks() ? 1 : 0),
1850  0),
1851  1000000);
1852  if (ratio != 0) {
1853  g_mempool.setSanityCheck(1.0 / ratio);
1854  }
1855  fCheckBlockIndex = args.GetBoolArg("-checkblockindex",
1856  chainparams.DefaultConsistencyChecks());
1858  args.GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED);
1859  if (fCheckpointsEnabled) {
1860  LogPrintf("Checkpoints will be verified.\n");
1861  } else {
1862  LogPrintf("Skipping checkpoint verification.\n");
1863  }
1864 
1866  args.GetArg("-assumevalid",
1867  chainparams.GetConsensus().defaultAssumeValid.GetHex()));
1868  if (!hashAssumeValid.IsNull()) {
1869  LogPrintf("Assuming ancestors of block %s have valid signatures.\n",
1871  } else {
1872  LogPrintf("Validating signatures for all blocks.\n");
1873  }
1874 
1875  if (args.IsArgSet("-minimumchainwork")) {
1876  const std::string minChainWorkStr =
1877  args.GetArg("-minimumchainwork", "");
1878  if (!IsHexNumber(minChainWorkStr)) {
1879  return InitError(strprintf(
1880  Untranslated(
1881  "Invalid non-hex (%s) minimum chain work value specified"),
1882  minChainWorkStr));
1883  }
1884  nMinimumChainWork = UintToArith256(uint256S(minChainWorkStr));
1885  } else {
1888  }
1889  LogPrintf("Setting nMinimumChainWork=%s\n", nMinimumChainWork.GetHex());
1890  if (nMinimumChainWork <
1892  LogPrintf("Warning: nMinimumChainWork set below default value of %s\n",
1893  chainparams.GetConsensus().nMinimumChainWork.GetHex());
1894  }
1895 
1896  // mempool limits
1897  int64_t nMempoolSizeMax =
1898  args.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
1899  int64_t nMempoolSizeMin =
1900  args.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT) *
1901  1000 * 40;
1902  if (nMempoolSizeMax < 0 || nMempoolSizeMax < nMempoolSizeMin) {
1903  return InitError(strprintf(_("-maxmempool must be at least %d MB"),
1904  std::ceil(nMempoolSizeMin / 1000000.0)));
1905  }
1906 
1907  // Configure excessive block size.
1908  const uint64_t nProposedExcessiveBlockSize =
1909  args.GetArg("-excessiveblocksize", DEFAULT_MAX_BLOCK_SIZE);
1910  if (!config.SetMaxBlockSize(nProposedExcessiveBlockSize)) {
1911  return InitError(
1912  _("Excessive block size must be > 1,000,000 bytes (1MB)"));
1913  }
1914 
1915  // Check blockmaxsize does not exceed maximum accepted block size.
1916  const uint64_t nProposedMaxGeneratedBlockSize =
1917  args.GetArg("-blockmaxsize", DEFAULT_MAX_GENERATED_BLOCK_SIZE);
1918  if (nProposedMaxGeneratedBlockSize > config.GetMaxBlockSize()) {
1919  auto msg = _("Max generated block size (blockmaxsize) cannot exceed "
1920  "the excessive block size (excessiveblocksize)");
1921  return InitError(msg);
1922  }
1923 
1924  // block pruning; get the amount of disk space (in MiB) to allot for block &
1925  // undo files
1926  int64_t nPruneArg = args.GetArg("-prune", 0);
1927  if (nPruneArg < 0) {
1928  return InitError(
1929  _("Prune cannot be configured with a negative value."));
1930  }
1931  nPruneTarget = (uint64_t)nPruneArg * 1024 * 1024;
1932  if (nPruneArg == 1) {
1933  // manual pruning: -prune=1
1934  LogPrintf("Block pruning enabled. Use RPC call "
1935  "pruneblockchain(height) to manually prune block and undo "
1936  "files.\n");
1937  nPruneTarget = std::numeric_limits<uint64_t>::max();
1938  fPruneMode = true;
1939  } else if (nPruneTarget) {
1941  return InitError(
1942  strprintf(_("Prune configured below the minimum of %d MiB. "
1943  "Please use a higher number."),
1944  MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024));
1945  }
1946  LogPrintf("Prune configured to target %u MiB on disk for block and "
1947  "undo files.\n",
1948  nPruneTarget / 1024 / 1024);
1949  fPruneMode = true;
1950  }
1951 
1952  nConnectTimeout = args.GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT);
1953  if (nConnectTimeout <= 0) {
1955  }
1956 
1957  peer_connect_timeout =
1958  args.GetArg("-peertimeout", DEFAULT_PEER_CONNECT_TIMEOUT);
1959  if (peer_connect_timeout <= 0) {
1960  return InitError(Untranslated(
1961  "peertimeout cannot be configured with a negative value."));
1962  }
1963 
1964  // Obtain the amount to charge excess UTXO
1965  if (args.IsArgSet("-excessutxocharge")) {
1966  Amount n = Amount::zero();
1967  auto parsed = ParseMoney(args.GetArg("-excessutxocharge", ""), n);
1968  if (!parsed || Amount::zero() > n) {
1969  return InitError(AmountErrMsg(
1970  "excessutxocharge", args.GetArg("-excessutxocharge", "")));
1971  }
1972  config.SetExcessUTXOCharge(n);
1973  } else {
1975  }
1976 
1977  if (args.IsArgSet("-minrelaytxfee")) {
1978  Amount n = Amount::zero();
1979  auto parsed = ParseMoney(args.GetArg("-minrelaytxfee", ""), n);
1980  if (!parsed || n == Amount::zero()) {
1981  return InitError(AmountErrMsg("minrelaytxfee",
1982  args.GetArg("-minrelaytxfee", "")));
1983  }
1984  // High fee check is done afterward in CWallet::CreateWalletFromFile()
1986  }
1987 
1988  // Sanity check argument for min fee for including tx in block
1989  // TODO: Harmonize which arguments need sanity checking and where that
1990  // happens.
1991  if (args.IsArgSet("-blockmintxfee")) {
1992  Amount n = Amount::zero();
1993  if (!ParseMoney(args.GetArg("-blockmintxfee", ""), n)) {
1994  return InitError(AmountErrMsg("blockmintxfee",
1995  args.GetArg("-blockmintxfee", "")));
1996  }
1997  }
1998 
1999  // Feerate used to define dust. Shouldn't be changed lightly as old
2000  // implementations may inadvertently create non-standard transactions.
2001  if (args.IsArgSet("-dustrelayfee")) {
2002  Amount n = Amount::zero();
2003  auto parsed = ParseMoney(args.GetArg("-dustrelayfee", ""), n);
2004  if (!parsed || Amount::zero() == n) {
2005  return InitError(
2006  AmountErrMsg("dustrelayfee", args.GetArg("-dustrelayfee", "")));
2007  }
2008  dustRelayFee = CFeeRate(n);
2009  }
2010 
2012  !args.GetBoolArg("-acceptnonstdtxn", !chainparams.RequireStandard());
2013  if (!chainparams.IsTestChain() && !fRequireStandard) {
2014  return InitError(strprintf(
2015  Untranslated(
2016  "acceptnonstdtxn is not currently supported for %s chain"),
2017  chainparams.NetworkIDString()));
2018  }
2019  nBytesPerSigOp = args.GetArg("-bytespersigop", nBytesPerSigOp);
2020 
2022  return false;
2023  }
2024 
2026  args.GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG);
2028  args.GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER);
2029 
2030  // Option to startup with mocktime set (used for regression testing):
2031  SetMockTime(args.GetArg("-mocktime", 0)); // SetMockTime(0) is a no-op
2032 
2033  if (args.GetBoolArg("-peerbloomfilters", DEFAULT_PEERBLOOMFILTERS)) {
2034  nLocalServices = ServiceFlags(nLocalServices | NODE_BLOOM);
2035  }
2036 
2037  nMaxTipAge = args.GetArg("-maxtipage", DEFAULT_MAX_TIP_AGE);
2038 
2039  return true;
2040 }
2041 
2042 static bool LockDataDirectory(bool probeOnly) {
2043  // Make sure only a single Bitcoin process is using the data directory.
2044  fs::path datadir = GetDataDir();
2045  if (!DirIsWritable(datadir)) {
2046  return InitError(strprintf(
2047  _("Cannot write to data directory '%s'; check permissions."),
2048  datadir.string()));
2049  }
2050  if (!LockDirectory(datadir, ".lock", probeOnly)) {
2051  return InitError(strprintf(_("Cannot obtain a lock on data directory "
2052  "%s. %s is probably already running."),
2053  datadir.string(), PACKAGE_NAME));
2054  }
2055  return true;
2056 }
2057 
2059  // Step 4: sanity checks
2060 
2061  // Initialize elliptic curve code
2062  std::string sha256_algo = SHA256AutoDetect();
2063  LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo);
2064  RandomInit();
2065  ECC_Start();
2066  globalVerifyHandle.reset(new ECCVerifyHandle());
2067 
2068  // Sanity check
2069  if (!InitSanityCheck()) {
2070  return InitError(strprintf(
2071  _("Initialization sanity check failed. %s is shutting down."),
2072  PACKAGE_NAME));
2073  }
2074 
2075  // Probe the data directory lock to give an early error message, if possible
2076  // We cannot hold the data directory lock here, as the forking for daemon()
2077  // hasn't yet happened, and a fork will cause weird behavior to it.
2078  return LockDataDirectory(true);
2079 }
2080 
2082  // After daemonization get the data directory lock again and hold on to it
2083  // until exit. This creates a slight window for a race condition to happen,
2084  // however this condition is harmless: it will at most make us exit without
2085  // printing a message to console.
2086  if (!LockDataDirectory(false)) {
2087  // Detailed error printed inside LockDataDirectory
2088  return false;
2089  }
2090  return true;
2091 }
2092 
2093 bool AppInitMain(Config &config, RPCServer &rpcServer,
2094  HTTPRPCRequestProcessor &httpRPCRequestProcessor,
2095  NodeContext &node) {
2096  // Step 4a: application initialization
2097  const ArgsManager &args = *Assert(node.args);
2098  const CChainParams &chainparams = config.GetChainParams();
2099 
2100  if (!CreatePidFile(args)) {
2101  // Detailed error printed inside CreatePidFile().
2102  return false;
2103  }
2104 
2105  BCLog::Logger &logger = LogInstance();
2106  if (logger.m_print_to_file) {
2107  if (args.GetBoolArg("-shrinkdebugfile",
2108  logger.DefaultShrinkDebugFile())) {
2109  // Do this first since it both loads a bunch of debug.log into
2110  // memory, and because this needs to happen before any other
2111  // debug.log printing.
2112  logger.ShrinkDebugFile();
2113  }
2114  }
2115 
2116  if (!logger.StartLogging()) {
2117  return InitError(
2118  strprintf(Untranslated("Could not open debug log file %s"),
2119  logger.m_file_path.string()));
2120  }
2121 
2122  if (!logger.m_log_timestamps) {
2123  LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime()));
2124  }
2125  LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
2126  LogPrintf("Using data directory %s\n", GetDataDir().string());
2127 
2128  // Only log conf file usage message if conf file actually exists.
2129  fs::path config_file_path =
2130  GetConfigFile(args.GetArg("-conf", BITCOIN_CONF_FILENAME));
2131  if (fs::exists(config_file_path)) {
2132  LogPrintf("Config file: %s\n", config_file_path.string());
2133  } else if (args.IsArgSet("-conf")) {
2134  // Warn if no conf file exists at path provided by user
2135  InitWarning(
2136  strprintf(_("The specified config file %s does not exist\n"),
2137  config_file_path.string()));
2138  } else {
2139  // Not categorizing as "Warning" because it's the default behavior
2140  LogPrintf("Config file: %s (not found, skipping)\n",
2141  config_file_path.string());
2142  }
2143 
2144  // Log the config arguments to debug.log
2145  args.LogArgs();
2146 
2147  LogPrintf("Using at most %i automatic connections (%i file descriptors "
2148  "available)\n",
2149  nMaxConnections, nFD);
2150 
2151  // Warn about relative -datadir path.
2152  if (args.IsArgSet("-datadir") &&
2153  !fs::path(args.GetArg("-datadir", "")).is_absolute()) {
2154  LogPrintf("Warning: relative datadir option '%s' specified, which will "
2155  "be interpreted relative to the current working directory "
2156  "'%s'. This is fragile, because if bitcoin is started in the "
2157  "future from a different location, it will be unable to "
2158  "locate the current data files. There could also be data "
2159  "loss if bitcoin is started while in a temporary "
2160  "directory.\n",
2161  args.GetArg("-datadir", ""), fs::current_path().string());
2162  }
2163 
2166 
2167  int script_threads = args.GetArg("-par", DEFAULT_SCRIPTCHECK_THREADS);
2168  if (script_threads <= 0) {
2169  // -par=0 means autodetect (number of cores - 1 script threads)
2170  // -par=-n means "leave n cores free" (number of cores - n - 1 script
2171  // threads)
2172  script_threads += GetNumCores();
2173  }
2174 
2175  // Subtract 1 because the main thread counts towards the par threads
2176  script_threads = std::max(script_threads - 1, 0);
2177 
2178  // Number of script-checking threads <= MAX_SCRIPTCHECK_THREADS
2179  script_threads = std::min(script_threads, MAX_SCRIPTCHECK_THREADS);
2180 
2181  LogPrintf("Script verification uses %d additional threads\n",
2182  script_threads);
2183  if (script_threads >= 1) {
2184  for (int i = 0; i < script_threads; ++i) {
2185  threadGroup.create_thread([i]() { return ThreadScriptCheck(i); });
2186  }
2187  }
2188 
2189  assert(!node.scheduler);
2190  node.scheduler = std::make_unique<CScheduler>();
2191 
2192  // Start the lightweight task scheduler thread
2193  CScheduler::Function serviceLoop = [&node] {
2194  node.scheduler->serviceQueue();
2195  };
2196  threadGroup.create_thread(std::bind(&TraceThread<CScheduler::Function>,
2197  "scheduler", serviceLoop));
2198 
2199  // Gather some entropy once per minute.
2200  node.scheduler->scheduleEvery(
2201  [] {
2202  RandAddPeriodic();
2203  return true;
2204  },
2205  std::chrono::minutes{1});
2206 
2208 
2209  // Create client interfaces for wallets that are supposed to be loaded
2210  // according to -wallet and -disablewallet options. This only constructs
2211  // the interfaces, it doesn't load wallet data. Wallets actually get loaded
2212  // when load() and start() interface methods are called below.
2214 
2219  RegisterAllRPCCommands(config, rpcServer, tableRPC);
2220  for (const auto &client : node.chain_clients) {
2221  client->registerRpcs();
2222  }
2223 #if ENABLE_ZMQ
2225 #endif
2226 
2233  if (args.GetBoolArg("-server", false)) {
2234  uiInterface.InitMessage_connect(SetRPCWarmupStatus);
2235  if (!AppInitServers(config, httpRPCRequestProcessor, node)) {
2236  return InitError(
2237  _("Unable to start HTTP server. See debug log for details."));
2238  }
2239  }
2240 
2241  // Step 5: verify wallet database integrity
2242  for (const auto &client : node.chain_clients) {
2243  if (!client->verify(chainparams)) {
2244  return false;
2245  }
2246  }
2247 
2248  // Step 6: network initialization
2249 
2250  // Note that we absolutely cannot open any actual connections
2251  // until the very end ("start node") as the UTXO/block state
2252  // is not yet setup and may end up being set up twice if we
2253  // need to reindex later.
2254 
2255  assert(!node.banman);
2256  node.banman = std::make_unique<BanMan>(
2257  GetDataDir() / "banlist.dat", config.GetChainParams(), &uiInterface,
2258  args.GetArg("-bantime", DEFAULT_MISBEHAVING_BANTIME));
2259  assert(!node.connman);
2260  node.connman = std::make_unique<CConnman>(
2261  config, GetRand(std::numeric_limits<uint64_t>::max()),
2262  GetRand(std::numeric_limits<uint64_t>::max()));
2263 
2264  // Make mempool generally available in the node context. For example the
2265  // connection manager, wallet, or RPC threads, which are all started after
2266  // this, may use it from the node context.
2267  assert(!node.mempool);
2268  node.mempool = &::g_mempool;
2269 
2270  assert(!node.chainman);
2271  node.chainman = &g_chainman;
2272  ChainstateManager &chainman = *Assert(node.chainman);
2273 
2274  node.peer_logic.reset(
2275  new PeerLogicValidation(*node.connman, node.banman.get(),
2276  *node.scheduler, chainman, *node.mempool));
2278 
2279  // sanitize comments per BIP-0014, format user agent and check total size
2280  std::vector<std::string> uacomments;
2281  for (const std::string &cmt : args.GetArgs("-uacomment")) {
2282  if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) {
2283  return InitError(strprintf(
2284  _("User Agent comment (%s) contains unsafe characters."), cmt));
2285  }
2286  uacomments.push_back(cmt);
2287  }
2288  const std::string strSubVersion =
2290  if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) {
2291  return InitError(strprintf(
2292  _("Total length of network version string (%i) exceeds maximum "
2293  "length (%i). Reduce the number or size of uacomments."),
2294  strSubVersion.size(), MAX_SUBVERSION_LENGTH));
2295  }
2296 
2297  if (args.IsArgSet("-onlynet")) {
2298  std::set<enum Network> nets;
2299  for (const std::string &snet : args.GetArgs("-onlynet")) {
2300  enum Network net = ParseNetwork(snet);
2301  if (net == NET_UNROUTABLE) {
2302  return InitError(strprintf(
2303  _("Unknown network specified in -onlynet: '%s'"), snet));
2304  }
2305  nets.insert(net);
2306  }
2307  for (int n = 0; n < NET_MAX; n++) {
2308  enum Network net = (enum Network)n;
2309  if (!nets.count(net)) {
2310  SetReachable(net, false);
2311  }
2312  }
2313  }
2314 
2315  // Check for host lookup allowed before parsing any network related
2316  // parameters
2317  fNameLookup = args.GetBoolArg("-dns", DEFAULT_NAME_LOOKUP);
2318 
2319  bool proxyRandomize =
2320  args.GetBoolArg("-proxyrandomize", DEFAULT_PROXYRANDOMIZE);
2321  // -proxy sets a proxy for all outgoing network traffic
2322  // -noproxy (or -proxy=0) as well as the empty string can be used to not set
2323  // a proxy, this is the default
2324  std::string proxyArg = args.GetArg("-proxy", "");
2325  SetReachable(NET_ONION, false);
2326  if (proxyArg != "" && proxyArg != "0") {
2327  CService proxyAddr;
2328  if (!Lookup(proxyArg, proxyAddr, 9050, fNameLookup)) {
2329  return InitError(strprintf(
2330  _("Invalid -proxy address or hostname: '%s'"), proxyArg));
2331  }
2332 
2333  proxyType addrProxy = proxyType(proxyAddr, proxyRandomize);
2334  if (!addrProxy.IsValid()) {
2335  return InitError(strprintf(
2336  _("Invalid -proxy address or hostname: '%s'"), proxyArg));
2337  }
2338 
2339  SetProxy(NET_IPV4, addrProxy);
2340  SetProxy(NET_IPV6, addrProxy);
2341  SetProxy(NET_ONION, addrProxy);
2342  SetNameProxy(addrProxy);
2343  // by default, -proxy sets onion as reachable, unless -noonion later
2344  SetReachable(NET_ONION, true);
2345  }
2346 
2347  // -onion can be used to set only a proxy for .onion, or override normal
2348  // proxy for .onion addresses.
2349  // -noonion (or -onion=0) disables connecting to .onion entirely. An empty
2350  // string is used to not override the onion proxy (in which case it defaults
2351  // to -proxy set above, or none)
2352  std::string onionArg = args.GetArg("-onion", "");
2353  if (onionArg != "") {
2354  if (onionArg == "0") {
2355  // Handle -noonion/-onion=0
2356  SetReachable(NET_ONION, false);
2357  } else {
2358  CService onionProxy;
2359  if (!Lookup(onionArg, onionProxy, 9050, fNameLookup)) {
2360  return InitError(strprintf(
2361  _("Invalid -onion address or hostname: '%s'"), onionArg));
2362  }
2363  proxyType addrOnion = proxyType(onionProxy, proxyRandomize);
2364  if (!addrOnion.IsValid()) {
2365  return InitError(strprintf(
2366  _("Invalid -onion address or hostname: '%s'"), onionArg));
2367  }
2368  SetProxy(NET_ONION, addrOnion);
2369  SetReachable(NET_ONION, true);
2370  }
2371  }
2372 
2373  // see Step 2: parameter interactions for more information about these
2374  fListen = args.GetBoolArg("-listen", DEFAULT_LISTEN);
2375  fDiscover = args.GetBoolArg("-discover", true);
2376  g_relay_txes = !args.GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY);
2377 
2378  for (const std::string &strAddr : args.GetArgs("-externalip")) {
2379  CService addrLocal;
2380  if (Lookup(strAddr, addrLocal, GetListenPort(), fNameLookup) &&
2381  addrLocal.IsValid()) {
2382  AddLocal(addrLocal, LOCAL_MANUAL);
2383  } else {
2384  return InitError(ResolveErrMsg("externalip", strAddr));
2385  }
2386  }
2387 
2388  // Read asmap file if configured
2389  if (args.IsArgSet("-asmap")) {
2390  fs::path asmap_path = fs::path(args.GetArg("-asmap", ""));
2391  if (asmap_path.empty()) {
2392  asmap_path = DEFAULT_ASMAP_FILENAME;
2393  }
2394  if (!asmap_path.is_absolute()) {
2395  asmap_path = GetDataDir() / asmap_path;
2396  }
2397  if (!fs::exists(asmap_path)) {
2398  InitError(strprintf(_("Could not find asmap file %s"), asmap_path));
2399  return false;
2400  }
2401  std::vector<bool> asmap = CAddrMan::DecodeAsmap(asmap_path);
2402  if (asmap.size() == 0) {
2403  InitError(
2404  strprintf(_("Could not parse asmap file %s"), asmap_path));
2405  return false;
2406  }
2407  const uint256 asmap_version = SerializeHash(asmap);
2408  node.connman->SetAsmap(std::move(asmap));
2409  LogPrintf("Using asmap version %s for IP bucketing\n",
2410  asmap_version.ToString());
2411  } else {
2412  LogPrintf("Using /16 prefix for IP bucketing\n");
2413  }
2414 
2415 #if ENABLE_ZMQ
2417 
2420  }
2421 #endif
2422  // unlimited unless -maxuploadtarget is set
2423  uint64_t nMaxOutboundLimit = 0;
2424  uint64_t nMaxOutboundTimeframe = MAX_UPLOAD_TIMEFRAME;
2425 
2426  if (args.IsArgSet("-maxuploadtarget")) {
2427  nMaxOutboundLimit =
2428  args.GetArg("-maxuploadtarget", DEFAULT_MAX_UPLOAD_TARGET) * 1024 *
2429  1024;
2430  }
2431 
2432  // Step 6.5 (I guess ?): Initialize Avalanche.
2433  g_avalanche =
2434  std::make_unique<avalanche::Processor>(*node.chain, node.connman.get());
2435 
2436  // Step 7: load block chain
2437 
2438  fReindex = args.GetBoolArg("-reindex", false);
2439  bool fReindexChainState = args.GetBoolArg("-reindex-chainstate", false);
2440 
2441  // cache size calculations
2442  int64_t nTotalCache = (args.GetArg("-dbcache", DEFAULT_DB_CACHE_MB) << 20);
2443  // total cache cannot be less than MIN_DB_CACHE_MB
2444  nTotalCache = std::max(nTotalCache, MIN_DB_CACHE_MB << 20);
2445  // total cache cannot be greater than MAX_DB_CACHE_MB
2446  nTotalCache = std::min(nTotalCache, MAX_DB_CACHE_MB << 20);
2447  int64_t nBlockTreeDBCache =
2448  std::min(nTotalCache / 8, MAX_BLOCK_DB_CACHE_MB << 20);
2449  nTotalCache -= nBlockTreeDBCache;
2450  int64_t nTxIndexCache =
2451  std::min(nTotalCache / 8, args.GetBoolArg("-txindex", DEFAULT_TXINDEX)
2452  ? MAX_TX_INDEX_CACHE_MB << 20
2453  : 0);
2454  nTotalCache -= nTxIndexCache;
2455  int64_t filter_index_cache = 0;
2456  if (!g_enabled_filter_types.empty()) {
2457  size_t n_indexes = g_enabled_filter_types.size();
2458  int64_t max_cache =
2459  std::min(nTotalCache / 8, MAX_FILTER_INDEX_CACHE_MB << 20);
2460  filter_index_cache = max_cache / n_indexes;
2461  nTotalCache -= filter_index_cache * n_indexes;
2462  }
2463  // use 25%-50% of the remainder for disk cache
2464  int64_t nCoinDBCache =
2465  std::min(nTotalCache / 2, (nTotalCache / 4) + (1 << 23));
2466  // cap total coins db cache
2467  nCoinDBCache = std::min(nCoinDBCache, MAX_COINS_DB_CACHE_MB << 20);
2468  nTotalCache -= nCoinDBCache;
2469  // the rest goes to in-memory cache
2470  nCoinCacheUsage = nTotalCache;
2471  int64_t nMempoolSizeMax =
2472  args.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
2473  LogPrintf("Cache configuration:\n");
2474  LogPrintf("* Using %.1f MiB for block index database\n",
2475  nBlockTreeDBCache * (1.0 / 1024 / 1024));
2476  if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
2477  LogPrintf("* Using %.1f MiB for transaction index database\n",
2478  nTxIndexCache * (1.0 / 1024 / 1024));
2479  }
2480  for (BlockFilterType filter_type : g_enabled_filter_types) {
2481  LogPrintf("* Using %.1f MiB for %s block filter index database\n",
2482  filter_index_cache * (1.0 / 1024 / 1024),
2483  BlockFilterTypeName(filter_type));
2484  }
2485  LogPrintf("* Using %.1f MiB for chain state database\n",
2486  nCoinDBCache * (1.0 / 1024 / 1024));
2487  LogPrintf("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of "
2488  "unused mempool space)\n",
2489  nCoinCacheUsage * (1.0 / 1024 / 1024),
2490  nMempoolSizeMax * (1.0 / 1024 / 1024));
2491 
2492  bool fLoaded = false;
2493  while (!fLoaded && !ShutdownRequested()) {
2494  const bool fReset = fReindex;
2495  auto is_coinsview_empty =
2496  [&](CChainState *chainstate) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) {
2497  return fReset || fReindexChainState ||
2498  chainstate->CoinsTip().GetBestBlock().IsNull();
2499  };
2500  bilingual_str strLoadError;
2501 
2502  uiInterface.InitMessage(_("Loading block index...").translated);
2503  do {
2504  bool failed_verification = false;
2505  const int64_t load_block_index_start_time = GetTimeMillis();
2506  try {
2507  LOCK(cs_main);
2508  chainman.InitializeChainstate();
2509  UnloadBlockIndex();
2510 
2511  // new CBlockTreeDB tries to delete the existing file, which
2512  // fails if it's still open from the previous loop. Close it
2513  // first:
2514  pblocktree.reset();
2515  pblocktree.reset(
2516  new CBlockTreeDB(nBlockTreeDBCache, false, fReset));
2517 
2518  if (fReset) {
2519  pblocktree->WriteReindexing(true);
2520  // If we're reindexing in prune mode, wipe away unusable
2521  // block files and all undo data files
2522  if (fPruneMode) {
2524  }
2525  }
2526 
2527  const Consensus::Params &params = chainparams.GetConsensus();
2528 
2529  // If necessary, upgrade from older database format.
2530  // This is a no-op if we cleared the block tree db with -reindex
2531  // or -reindex-chainstate
2532  if (!pblocktree->Upgrade(params)) {
2533  strLoadError = _("Error upgrading block index database");
2534  break;
2535  }
2536 
2537  if (ShutdownRequested()) {
2538  break;
2539  }
2540 
2541  // LoadBlockIndex will load fHavePruned if we've ever removed a
2542  // block file from disk.
2543  // Note that it also sets fReindex based on the disk flag!
2544  // From here on out fReindex and fReset mean something
2545  // different!
2546  if (!chainman.LoadBlockIndex(params)) {
2547  if (ShutdownRequested()) {
2548  break;
2549  }
2550  strLoadError = _("Error loading block database");
2551  break;
2552  }
2553 
2554  // If the loaded chain has a wrong genesis, bail out immediately
2555  // (we're likely using a testnet datadir, or the other way
2556  // around).
2557  if (!::BlockIndex().empty() &&
2559  return InitError(_("Incorrect or no genesis block found. "
2560  "Wrong datadir for network?"));
2561  }
2562 
2563  // Check for changed -prune state. What we are concerned about
2564  // is a user who has pruned blocks in the past, but is now
2565  // trying to run unpruned.
2566  if (fHavePruned && !fPruneMode) {
2567  strLoadError =
2568  _("You need to rebuild the database using -reindex to "
2569  "go back to unpruned mode. This will redownload the "
2570  "entire blockchain");
2571  break;
2572  }
2573 
2574  // At this point blocktree args are consistent with what's on
2575  // disk. If we're not mid-reindex (based on disk + args), add a
2576  // genesis block on disk (otherwise we use the one already on
2577  // disk).
2578  // This is called again in ThreadImport after the reindex
2579  // completes.
2580  if (!fReindex && !LoadGenesisBlock(chainparams)) {
2581  strLoadError = _("Error initializing block database");
2582  break;
2583  }
2584 
2585  // At this point we're either in reindex or we've loaded a
2586  // useful block tree into BlockIndex()!
2587 
2588  bool failed_chainstate_init = false;
2589 
2590  for (CChainState *chainstate : chainman.GetAll()) {
2591  LogPrintf("Initializing chainstate %s\n",
2592  chainstate->ToString());
2593  chainstate->InitCoinsDB(
2594  /* cache_size_bytes */ nCoinDBCache,
2595  /* in_memory */ false,
2596  /* should_wipe */ fReset || fReindexChainState);
2597 
2598  chainstate->CoinsErrorCatcher().AddReadErrCallback([]() {
2599  uiInterface.ThreadSafeMessageBox(
2600  _("Error reading from database, shutting down."),
2602  });
2603 
2604  // If necessary, upgrade from older database format.
2605  // This is a no-op if we cleared the coinsviewdb with
2606  // -reindex or -reindex-chainstate
2607  if (!chainstate->CoinsDB().Upgrade()) {
2608  strLoadError = _("Error upgrading chainstate database");
2609  failed_chainstate_init = true;
2610  break;
2611  }
2612 
2613  // ReplayBlocks is a no-op if we cleared the coinsviewdb
2614  // with -reindex or -reindex-chainstate
2615  if (!chainstate->ReplayBlocks(params)) {
2616  strLoadError = _(
2617  "Unable to replay blocks. You will need to rebuild "
2618  "the database using -reindex-chainstate.");
2619  failed_chainstate_init = true;
2620  break;
2621  }
2622 
2623  // The on-disk coinsdb is now in a good state, create the
2624  // cache
2625  chainstate->InitCoinsCache();
2626  assert(chainstate->CanFlushToDisk());
2627 
2628  if (!is_coinsview_empty(chainstate)) {
2629  // LoadChainTip initializes the chain based on
2630  // CoinsTip()'s best block
2631  if (!chainstate->LoadChainTip(chainparams)) {
2632  strLoadError =
2633  _("Error initializing block database");
2634  failed_chainstate_init = true;
2635  // out of the per-chainstate loop
2636  break;
2637  }
2638  assert(chainstate->m_chain.Tip() != nullptr);
2639  }
2640  }
2641 
2642  if (failed_chainstate_init) {
2643  // out of the chainstate activation do-while
2644  break;
2645  }
2646 
2647  for (CChainState *chainstate : chainman.GetAll()) {
2648  if (!is_coinsview_empty(chainstate)) {
2649  uiInterface.InitMessage(
2650  _("Verifying blocks...").translated);
2651  if (fHavePruned &&
2652  args.GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) >
2654  LogPrintf(
2655  "Prune: pruned datadir may not have more than "
2656  "%d blocks; only checking available blocks\n",
2658  }
2659 
2660  const CBlockIndex *tip = chainstate->m_chain.Tip();
2661  RPCNotifyBlockChange(tip);
2662  if (tip &&
2663  tip->nTime > GetAdjustedTime() + 2 * 60 * 60) {
2664  strLoadError =
2665  _("The block database contains a block which "
2666  "appears to be from the future. "
2667  "This may be due to your computer's date and "
2668  "time being set incorrectly. "
2669  "Only rebuild the block database if you are "
2670  "sure that your computer's date and time are "
2671  "correct");
2672  failed_verification = true;
2673  break;
2674  }
2675 
2676  // Only verify the DB of the active chainstate. This is
2677  // fixed in later work when we allow VerifyDB to be
2678  // parameterized by chainstate.
2679  if (&::ChainstateActive() == chainstate &&
2680  !CVerifyDB().VerifyDB(
2681  config, &chainstate->CoinsDB(),
2682  args.GetArg("-checklevel", DEFAULT_CHECKLEVEL),
2683  args.GetArg("-checkblocks",
2684  DEFAULT_CHECKBLOCKS))) {
2685  strLoadError =
2686  _("Corrupted block database detected");
2687  failed_verification = true;
2688  break;
2689  }
2690  }
2691  }
2692  } catch (const std::exception &e) {
2693  LogPrintf("%s\n", e.what());
2694  strLoadError = _("Error opening block database");
2695  failed_verification = true;
2696  break;
2697  }
2698 
2699  if (!failed_verification) {
2700  fLoaded = true;
2701  LogPrintf(" block index %15dms\n",
2702  GetTimeMillis() - load_block_index_start_time);
2703  }
2704  } while (false);
2705 
2706  if (!fLoaded && !ShutdownRequested()) {
2707  // first suggest a reindex
2708  if (!fReset) {
2709  bool fRet = uiInterface.ThreadSafeQuestion(
2710  strLoadError + Untranslated(".\n\n") +
2711  _("Do you want to rebuild the block database now?"),
2712  strLoadError.original +
2713  ".\nPlease restart with -reindex or "
2714  "-reindex-chainstate to recover.",
2715  "",
2718  if (fRet) {
2719  fReindex = true;
2720  AbortShutdown();
2721  } else {
2722  LogPrintf("Aborted block database rebuild. Exiting.\n");
2723  return false;
2724  }
2725  } else {
2726  return InitError(strLoadError);
2727  }
2728  }
2729  }
2730 
2731  // As LoadBlockIndex can take several minutes, it's possible the user
2732  // requested to kill the GUI during the last operation. If so, exit.
2733  // As the program has not fully started yet, Shutdown() is possibly
2734  // overkill.
2735  if (ShutdownRequested()) {
2736  LogPrintf("Shutdown requested. Exiting.\n");
2737  return false;
2738  }
2739 
2740  // Encoded addresses using cashaddr instead of base58.
2741  // We do this by default to avoid confusion with BTC addresses.
2742  config.SetCashAddrEncoding(args.GetBoolArg("-usecashaddr", true));
2743 
2744  // Step 8: load indexers
2745  if (args.GetBoolArg("-txindex", DEFAULT_TXINDEX)) {
2746  g_txindex = std::make_unique<TxIndex>(nTxIndexCache, false, fReindex);
2747  g_txindex->Start();
2748  }
2749 
2750  for (const auto &filter_type : g_enabled_filter_types) {
2751  InitBlockFilterIndex(filter_type, filter_index_cache, false, fReindex);
2752  GetBlockFilterIndex(filter_type)->Start();
2753  }
2754 
2755  // Step 9: load wallet
2756  for (const auto &client : node.chain_clients) {
2757  if (!client->load(chainparams)) {
2758  return false;
2759  }
2760  }
2761 
2762  // Step 10: data directory maintenance
2763 
2764  // if pruning, unset the service bit and perform the initial blockstore
2765  // prune after any wallet rescanning has taken place.
2766  if (fPruneMode) {
2767  LogPrintf("Unsetting NODE_NETWORK on prune mode\n");
2768  nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK);
2769  if (!fReindex) {
2770  LOCK(cs_main);
2771  for (CChainState *chainstate : chainman.GetAll()) {
2772  uiInterface.InitMessage(_("Pruning blockstore...").translated);
2773  chainstate->PruneAndFlush();
2774  }
2775  }
2776  }
2777 
2778  // Step 11: import blocks
2779  if (!CheckDiskSpace(GetDataDir())) {
2780  InitError(
2781  strprintf(_("Error: Disk space is low for %s"), GetDataDir()));
2782  return false;
2783  }
2784  if (!CheckDiskSpace(GetBlocksDir())) {
2785  InitError(
2786  strprintf(_("Error: Disk space is low for %s"), GetBlocksDir()));
2787  return false;
2788  }
2789 
2790  // Either install a handler to notify us when genesis activates, or set
2791  // fHaveGenesis directly.
2792  // No locking, as this happens before any background thread is started.
2793  boost::signals2::connection block_notify_genesis_wait_connection;
2794  if (::ChainActive().Tip() == nullptr) {
2795  block_notify_genesis_wait_connection =
2796  uiInterface.NotifyBlockTip_connect(
2797  std::bind(BlockNotifyGenesisWait, std::placeholders::_2));
2798  } else {
2799  fHaveGenesis = true;
2800  }
2801 
2802 #if defined(HAVE_SYSTEM)
2803  if (args.IsArgSet("-blocknotify")) {
2804  const std::string block_notify = args.GetArg("-blocknotify", "");
2805  const auto BlockNotifyCallback = [block_notify](
2806  SynchronizationState sync_state,
2807  const CBlockIndex *pBlockIndex) {
2808  if (sync_state != SynchronizationState::POST_INIT || !pBlockIndex) {
2809  return;
2810  }
2811 
2812  std::string strCmd = block_notify;
2813  if (!strCmd.empty()) {
2814  boost::replace_all(strCmd, "%s",
2815  pBlockIndex->GetBlockHash().GetHex());
2816  std::thread t(runCommand, strCmd);
2817  // thread runs free
2818  t.detach();
2819  }
2820  };
2821  uiInterface.NotifyBlockTip_connect(BlockNotifyCallback);
2822  }
2823 #endif
2824 
2825  std::vector<fs::path> vImportFiles;
2826  for (const std::string &strFile : args.GetArgs("-loadblock")) {
2827  vImportFiles.push_back(strFile);
2828  }
2829 
2830  threadGroup.create_thread([=, &config, &chainman, &args] {
2831  ThreadImport(config, chainman, vImportFiles, args);
2832  });
2833 
2834  // Wait for genesis block to be processed
2835  {
2836  WAIT_LOCK(g_genesis_wait_mutex, lock);
2837  // We previously could hang here if StartShutdown() is called prior to
2838  // ThreadImport getting started, so instead we just wait on a timer to
2839  // check ShutdownRequested() regularly.
2840  while (!fHaveGenesis && !ShutdownRequested()) {
2841  g_genesis_wait_cv.wait_for(lock, std::chrono::milliseconds(500));
2842  }
2843  block_notify_genesis_wait_connection.disconnect();
2844  }
2845 
2846  if (ShutdownRequested()) {
2847  return false;
2848  }
2849 
2850  // Step 12: start node
2851 
2852  int chain_active_height;
2853 
2855  {
2856  LOCK(cs_main);
2857  LogPrintf("block tree size = %u\n", ::BlockIndex().size());
2858  chain_active_height = ::ChainActive().Height();
2859  }
2860  LogPrintf("nBestHeight = %d\n", chain_active_height);
2861 
2862  if (args.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION)) {
2863  StartTorControl();
2864  }
2865 
2866  Discover();
2867 
2868  // Map ports with UPnP
2869  if (args.GetBoolArg("-upnp", DEFAULT_UPNP)) {
2870  StartMapPort();
2871  }
2872 
2873  CConnman::Options connOptions;
2874  connOptions.nLocalServices = nLocalServices;
2875  connOptions.nMaxConnections = nMaxConnections;
2876  connOptions.m_max_outbound_full_relay = std::min(
2878  connOptions.m_max_outbound_block_relay = std::min(
2880  connOptions.nMaxConnections - connOptions.m_max_outbound_full_relay);
2881  connOptions.nMaxAddnode = MAX_ADDNODE_CONNECTIONS;
2882  connOptions.nMaxFeeler = 1;
2883  connOptions.nBestHeight = chain_active_height;
2884  connOptions.uiInterface = &uiInterface;
2885  connOptions.m_banman = node.banman.get();
2886  connOptions.m_msgproc = node.peer_logic.get();
2887  connOptions.nSendBufferMaxSize =
2888  1000 * args.GetArg("-maxsendbuffer", DEFAULT_MAXSENDBUFFER);
2889  connOptions.nReceiveFloodSize =
2890  1000 * args.GetArg("-maxreceivebuffer", DEFAULT_MAXRECEIVEBUFFER);
2891  connOptions.m_added_nodes = args.GetArgs("-addnode");
2892 
2893  connOptions.nMaxOutboundTimeframe = nMaxOutboundTimeframe;
2894  connOptions.nMaxOutboundLimit = nMaxOutboundLimit;
2895  connOptions.m_peer_connect_timeout = peer_connect_timeout;
2896 
2897  for (const std::string &strBind : args.GetArgs("-bind")) {
2898  CService addrBind;
2899  if (!Lookup(strBind, addrBind, GetListenPort(), false)) {
2900  return InitError(ResolveErrMsg("bind", strBind));
2901  }
2902  connOptions.vBinds.push_back(addrBind);
2903  }
2904 
2905  for (const std::string &strBind : args.GetArgs("-whitebind")) {
2906  NetWhitebindPermissions whitebind;
2908  if (!NetWhitebindPermissions::TryParse(strBind, whitebind, error)) {
2909  return InitError(error);
2910  }
2911  connOptions.vWhiteBinds.push_back(whitebind);
2912  }
2913 
2914  for (const auto &net : args.GetArgs("-whitelist")) {
2915  NetWhitelistPermissions subnet;
2917  if (!NetWhitelistPermissions::TryParse(net, subnet, error)) {
2918  return InitError(error);
2919  }
2920  connOptions.vWhitelistedRange.push_back(subnet);
2921  }
2922 
2923  connOptions.vSeedNodes = args.GetArgs("-seednode");
2924 
2925  // Initiate outbound connections unless connect=0
2926  connOptions.m_use_addrman_outgoing = !args.IsArgSet("-connect");
2927  if (!connOptions.m_use_addrman_outgoing) {
2928  const auto connect = args.GetArgs("-connect");
2929  if (connect.size() != 1 || connect[0] != "0") {
2930  connOptions.m_specified_outgoing = connect;
2931  }
2932  }
2933  if (!node.connman->Start(*node.scheduler, connOptions)) {
2934  return false;
2935  }
2936 
2937  // Step 13: finished
2938 
2940  uiInterface.InitMessage(_("Done loading").translated);
2941 
2942  for (const auto &client : node.chain_clients) {
2943  client->start(*node.scheduler);
2944  }
2945 
2946  BanMan *banman = node.banman.get();
2947  node.scheduler->scheduleEvery(
2948  [banman] {
2949  banman->DumpBanlist();
2950  return true;
2951  },
2953 
2954  // Start Avalanche's event loop.
2955  g_avalanche->startEventLoop(*node.scheduler);
2956 
2957  return true;
2958 }
std::vector< CService > vBinds
Definition: net.h:205
int m_max_outbound_full_relay
Definition: net.h:189
bool fIsBareMultisigStd
Definition: settings.cpp:10
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
void StartTorControl()
Definition: torcontrol.cpp:872
void RandomInit()
Initialize global RNG state and log any CPU features that are used.
Definition: random.cpp:781
static void BlockNotifyGenesisWait(const CBlockIndex *pBlockIndex)
Definition: init.cpp:1281
static const int DEFAULT_SCRIPTCHECK_THREADS
-par default (number of script-checking threads, 0 = auto)
Definition: validation.h:82
static constexpr bool AVALANCHE_DEFAULT_ENABLED
Is avalanche enabled by default.
Definition: processor.h:36
std::string NetworkIDString() const
Return the BIP70 network string (main, test or regtest)
Definition: chainparams.h:86
static const Amount DEFAULT_UTXO_FEE
Default for -excessutxocharge for transactions transactions.
Definition: validation.h:70
void ECC_Start()
Initialize the elliptic curve support.
Definition: key.cpp:438
std::unique_ptr< CBaseChainParams > CreateBaseChainParams(const std::string &chain)
Creates and returns a std::unique_ptr<CBaseChainParams> of the chosen chain.
BlockFilterIndex is used to store and retrieve block filters, hashes, and headers for a range of bloc...
std::vector< std::unique_ptr< interfaces::ChainClient > > chain_clients
Definition: context.h:46
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:390
bool ShutdownRequested()
Definition: shutdown.cpp:18
uint64_t GetRand(uint64_t nMax) noexcept
Definition: random.cpp:641
bilingual_str ResolveErrMsg(const std::string &optname, const std::string &strBind)
Definition: error.cpp:41
const std::string CURRENCY_UNIT
Definition: network.cpp:8
bool fPruneMode
True if we&#39;re running in -prune mode.
Definition: validation.cpp:99
void SetupChainParamsBaseOptions(ArgsManager &argsman)
Set the arguments for chainparams.
static void CleanupBlockRevFiles()
Definition: init.cpp:1310
static constexpr Amount zero()
Definition: amount.h:35
std::condition_variable g_best_block_cv
Definition: validation.cpp:94
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:1602
SynchronizationState
Current sync state passed to tip changed callbacks.
Definition: validation.h:167
BCLog::Logger & LogInstance()
Definition: logging.cpp:15
Definition: banman.h:58
ServiceFlags
nServices flags.
Definition: protocol.h:320
const char *const BITCOIN_SETTINGS_FILENAME
Definition: system.cpp:74
static const uint64_t MAX_UPLOAD_TIMEFRAME
The default timeframe for -maxuploadtarget.
Definition: net.h:101
BlockHash hashGenesisBlock
Definition: params.h:60
void UnloadBlockIndex()
Unload database information.
bilingual_str AmountErrMsg(const std::string &optname, const std::string &strValue)
Definition: error.cpp:50
#define LogPrint(category,...)
Definition: logging.h:189
bool DirIsWritable(const fs::path &directory)
Definition: system.cpp:127
bool AddLocal(const CService &addr, int nScore)
Definition: net.cpp:229
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:22
int m_max_outbound_block_relay
Definition: net.h:190
fs::path GetDefaultDataDir()
Definition: system.cpp:703
static const int DEFAULT_HTTP_SERVER_TIMEOUT
Definition: httpserver.h:14
void EnableCategory(LogFlags category)
Definition: logging.cpp:312
#define TRY_LOCK(cs, name)
Definition: sync.h:236
static const unsigned int MAX_OP_RETURN_RELAY
Default setting for nMaxDatacarrierBytes.
Definition: standard.h:33
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn&#39;t already have a value.
Definition: system.cpp:515
void Shutdown(NodeContext &node)
Definition: init.cpp:178
static const std::string REGTEST
Bilingual messages:
Definition: translation.h:17
void SetRPCWarmupStatus(const std::string &newStatus)
Set the RPC warmup status.
Definition: server.cpp:368
static constexpr unsigned int DEFAULT_DESCENDANT_LIMIT
Default for -limitdescendantcount, max number of in-mempool descendants.
Definition: mempool.h:22
bool BlockFilterTypeByName(const std::string &name, BlockFilterType &filter_type)
Find a filter type by its human-readable name.
int64_t GetTimeMillis()
Returns the system time (not mockable)
Definition: time.cpp:59
CChain & ChainActive()
Definition: validation.cpp:73
int GetNumCores()
Return the number of cores available on the current system.
Definition: system.cpp:1338
BanMan * m_banman
Definition: net.h:196
static const unsigned int DEFAULT_MAX_SIG_CACHE_SIZE
Definition: sigcache.h:16
fs::path m_file_path
Definition: logging.h:98
static boost::signals2::connection rpc_notify_block_change_connection
Definition: init.cpp:363
std::unique_ptr< BanMan > banman
Definition: context.h:42
static const bool DEFAULT_FORCEDNSSEED
Definition: net.h:107
static const unsigned int DEFAULT_MAX_MEMPOOL_SIZE
Default for -maxmempool, maximum megabytes of mempool memory usage.
Definition: policy.h:48
bool LoadGenesisBlock(const CChainParams &chainparams)
Ensures we have a genesis block in the block tree, possibly writing one to disk.
void InitScriptExecutionCache()
Initializes the script-execution cache.
Definition: scriptcache.cpp:76
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:1069
bool empty() const
Definition: translation.h:27
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1201
static const int DEFAULT_HTTP_WORKQUEUE
Definition: httpserver.h:13
bool fHavePruned
Pruning-related variables and constants.
Definition: validation.cpp:98
static void OnRPCStarted()
Definition: init.cpp:364
static const int64_t DEFAULT_MAX_TIP_AGE
Definition: validation.h:127
void InitWarning(const bilingual_str &str)
Show warning message.
~CImportingNow()
Definition: init.cpp:1297
static constexpr int64_t MIN_DB_CACHE_MB
min. -dbcache (MiB)
Definition: txdb.h:31
static const Amount DEFAULT_BLOCK_MIN_TX_FEE_PER_KB(1000 *SATOSHI)
Default for -blockmintxfee, which sets the minimum feerate for a transaction in blocks created by min...
static void HandleSIGTERM(int)
Signal handlers are very limited in what they are allowed to do.
Definition: init.cpp:338
BlockFilterIndex * GetBlockFilterIndex(BlockFilterType filter_type)
Get a block filter index by type.
std::string ListLogCategories()
Returns a string with the log categories.
Definition: logging.cpp:142
static const bool DEFAULT_ACCEPT_DATACARRIER
Definition: standard.h:16
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:36
BlockStatus nStatus
Verification status of this block. See enum BlockStatus.
Definition: blockindex.h:76
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ChainActive().Tip() will not be pr...
Definition: validation.h:220
unsigned int nReceiveFloodSize
Definition: net.h:198
void AddHiddenArgs(const std::vector< std::string > &args)
Add many hidden arguments.
Definition: system.cpp:568
static const bool DEFAULT_LOGTHREADNAMES
Definition: logging.h:23
static constexpr unsigned int DEFAULT_ANCESTOR_SIZE_LIMIT
Default for -limitancestorsize, maximum kilobytes of tx + all in-mempool ancestors.
Definition: mempool.h:20
CClientUIInterface * uiInterface
Definition: net.h:194
static const unsigned int DEFAULT_DESCENDANT_SIZE_LIMIT
Default for -limitdescendantsize, maximum kilobytes of in-mempool descendants.
Definition: mempool.h:27
fs::path GetBlockPosFilename(const FlatFilePos &pos)
Translation to a filesystem path.
Definition: blockdb.cpp:29
int Height() const
Return the maximal height in the chain.
Definition: chain.h:210
void ForEachBlockFilterIndex(std::function< void(BlockFilterIndex &)> fn)
Iterate over all running block filter indexes, invoking fn on each.
bool fAcceptDatacarrier
A data carrying output is an unspendable output containing data.
Definition: standard.cpp:13
void ThreadRename(std::string &&)
Rename a thread both in terms of an internal (in-memory) name as well as its system thread name...
Definition: threadnames.cpp:48
void StopTorControl()
Definition: torcontrol.cpp:899
BlockHash defaultAssumeValid
Definition: params.h:110
std::unique_ptr< interfaces::Chain > chain
Definition: context.h:45
void StopREST()
Stop HTTP REST subsystem.
Definition: rest.cpp:781
Definition: amount.h:17
static const bool DEFAULT_LISTEN
-listen default
Definition: net.h:85
static const bool DEFAULT_LOGTIMEMICROS
Definition: logging.h:20
std::atomic< bool > m_reopen_file
Definition: logging.h:99
CChainState stores and provides an API to update our local knowledge of the current best chain...
Definition: validation.h:743
std::string CopyrightHolders(const std::string &strPrefix)
Definition: system.cpp:1342
static const int MAX_ADDNODE_CONNECTIONS
Maximum number of addnode outgoing nodes.
Definition: net.h:81
void UnregisterBackgroundSignalScheduler()
Unregister a CScheduler to give callbacks which should run in the background - these callbacks will n...
static void OnRPCStopped()
Definition: init.cpp:369
arith_uint256 nMinimumChainWork
Minimum work we will assume exists on some valid chain.
Definition: validation.cpp:108
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:171
void InterruptRPC()
Definition: server.cpp:345
const std::set< BlockFilterType > & AllBlockFilterTypes()
Get a list of known filter types.
std::string FormatISO8601DateTime(int64_t nTime)
ISO 8601 formatting is preferred.
Definition: time.cpp:79
bool m_print_to_console
Definition: logging.h:91
bool fDiscover
Definition: net.cpp:109
bool DefaultConsistencyChecks() const
Default value for -checkmempool and -checkblockindex argument.
Definition: chainparams.h:66
void Discover()
Definition: net.cpp:2437
int nMaxConnections
Definition: net.h:188
static std::unique_ptr< ECCVerifyHandle > globalVerifyHandle
Definition: init.cpp:153
const fs::path & GetBlocksDir()
Definition: system.cpp:734
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
Definition: chainparams.h:47
void UnregisterAllValidationInterfaces()
Unregister all wallets from core.
std::string translated
Definition: translation.h:19
std::function< void()> Function
Definition: scheduler.h:46
int RaiseFileDescriptorLimit(int nMinFD)
This function tries to raise the file descriptor limit to the requested number.
Definition: system.cpp:1169
uint32_t nTime
Definition: blockindex.h:81
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:498
unsigned short GetListenPort()
Definition: net.cpp:121
void UnregisterValidationInterface(CValidationInterface *pwalletIn)
Unregister a wallet from core.
std::string SHA256AutoDetect()
Autodetect the best available SHA256 implementation.
Definition: sha256.cpp:746
void RandAddPeriodic() noexcept
Gather entropy from various expensive sources, and feed them to the PRNG state.
Definition: random.cpp:631
bool InitBlockFilterIndex(BlockFilterType filter_type, size_t n_cache_size, bool f_memory, bool f_wipe)
Initialize a block filter index for the given type if one does not already exist. ...
virtual void Construct(NodeContext &node) const =0
Add wallets that should be opened to list of chain clients.
void InterruptHTTPRPC()
Interrupt HTTP RPC subsystem.
Definition: httprpc.cpp:475
static void HandleSIGHUP(int)
Definition: init.cpp:342
fs::ofstream ofstream
Definition: fs.h:99
static const bool DEFAULT_PERMIT_BAREMULTISIG
Default for -permitbaremultisig.
Definition: policy.h:59
static boost::thread_group threadGroup
Definition: init.cpp:155
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes)
Definition: system.cpp:141
void DisableCategory(LogFlags category)
Definition: logging.cpp:325
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:73
bool SetupNetworking()
Definition: system.cpp:1325
std::string LicenseInfo()
Returns licensing information (for -version)
Definition: init.cpp:1246
const CCheckpointData & Checkpoints() const
Definition: chainparams.h:94
void InterruptHTTPServer()
Interrupt HTTP server threads.
Definition: httpserver.cpp:478
void SetupServerArgs(NodeContext &node)
Register all arguments with the ArgsManager.
Definition: init.cpp:376
uint64_t nPruneTarget
Number of MiB of block files that we&#39;re trying to stay below.
Definition: validation.cpp:104
bool SetNameProxy(const proxyType &addrProxy)
Set the name proxy to use for all connections to nodes specified by a hostname.
Definition: netbase.cpp:808
void ThreadScriptCheck(int worker_num)
Run an instance of the script checking thread.
static const Amount DUST_RELAY_TX_FEE(1000 *SATOSHI)
Min feerate for defining dust.
bool DumpMempool(const CTxMemPool &pool)
Dump the mempool to disk.
void SetReachable(enum Network net, bool reachable)
Mark a network as reachable or unreachable (no automatic connects to it)
Definition: net.cpp:267
bool IsNull() const
Definition: uint256.h:26
bool IsLoaded() const
Definition: txmempool.cpp:1272
virtual const CChainParams & GetChainParams() const =0
static const bool DEFAULT_STOPAFTERBLOCKIMPORT
Definition: init.cpp:91
void RPCNotifyBlockChange(const CBlockIndex *pindex)
Callback for when block tip changed.
Definition: blockchain.cpp:246
void Stop()
Stops the instance from staying in sync with blockchain updates.
Definition: base.cpp:321
static const int MAX_BLOCKS_ONLY_CONNECTIONS
Maximum number of block-relay-only outgoing connections.
Definition: net.h:83
arith_uint256 UintToArith256(const uint256 &a)
bool m_print_to_file
Definition: logging.h:92
CChainState & ChainstateActive()
Definition: validation.cpp:67
static const int64_t DEFAULT_MIN_FINALIZATION_DELAY
Default for -finalizationdelay This is the minimum time between a block header reception and the bloc...
Definition: validation.h:164
std::function< void()> rpc_interruption_point
Definition: context.h:48
static const std::string MAIN
BIP70 chain name strings (main, test or regtest)
static const bool DEFAULT_PEERBLOCKFILTERS
bool IsValid() const
Definition: netaddress.cpp:244
bool Lookup(const std::string &name, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Resolve a service string to its corresponding service.
Definition: netbase.cpp:219
static const Amount DEFAULT_MIN_RELAY_TX_FEE_PER_KB(1000 *SATOSHI)
Default for -minrelaytxfee, minimum relay fee for transactions.
void SetMockTime(int64_t nMockTimeIn)
For testing.
Definition: time.cpp:50
void SetRPCWarmupFinished()
Mark warmup as done.
Definition: server.cpp:373
void OnStarted(std::function< void()> slot)
Definition: server.cpp:106
static constexpr int64_t MAX_TX_INDEX_CACHE_MB
Max memory allocated to block tree DB specific cache, if -txindex (MiB)
Definition: txdb.h:44
uint256 SerializeHash(const T &obj, int nType=SER_GETHASH, int nVersion=PROTOCOL_VERSION)
Compute the 256-bit hash of an object&#39;s serialization.
Definition: hash.h:196
static const size_t DEFAULT_MAXRECEIVEBUFFER
Definition: net.h:108
BlockFilterType
Definition: blockfilter.h:88
bool LockDirectory(const fs::path &directory, const std::string lockfile_name, bool probe_only)
Definition: system.cpp:88
static const bool DEFAULT_PERSIST_MEMPOOL
Default for -persistmempool.
Definition: validation.h:139
#define LOCK2(cs1, cs2)
Definition: sync.h:233
void StopMapPort()
Definition: net.cpp:1738
CRPCTable tableRPC
Definition: server.cpp:563
void setSanityCheck(double dFrequency=1.0)
Definition: txmempool.h:600
void Interrupt()
Definition: base.cpp:304
Users of this module must hold an ECCVerifyHandle.
Definition: pubkey.h:223
bool fCheckpointsEnabled
Definition: validation.cpp:102
static const bool DEFAULT_PEERBLOOMFILTERS
Definition: validation.h:152
bool AppInitSanityChecks()
Initialization sanity checks: ecc init, sanity checks, dir lock.
Definition: init.cpp:2058
static constexpr int64_t MAX_DB_CACHE_MB
max. -dbcache (MiB)
Definition: txdb.h:33
ChainstateManager * chainman
Definition: context.h:41
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: system.cpp:475
const std::string & ListBlockFilterTypes()
Get a comma-separated list of known filter type names.
virtual uint64_t GetMaxBlockSize() const =0
static CZMQNotificationInterface * Create()
Definition: config.h:19
void ResetBlockFailureFlags(CBlockIndex *pindex)
Remove invalidity status from a block and its descendants.
NodeContext struct containing references to chain state and connection state.
Definition: context.h:35
const std::string DEFAULT_TOR_CONTROL
Default control port.
Definition: torcontrol.cpp:32
std::unique_ptr< CConnman > connman
Definition: context.h:36
static constexpr int64_t DEFAULT_DB_BATCH_SIZE
-dbbatchsize default (bytes)
Definition: txdb.h:37
Access to the block database (blocks/index/)
Definition: txdb.h:98
bool m_log_threadnames
Definition: logging.h:96
void StopHTTPServer()
Stop HTTP server.
Definition: httpserver.cpp:489
static std::condition_variable g_genesis_wait_cv
Definition: init.cpp:1279
void Interrupt(NodeContext &node)
Interrupt threads.
Definition: init.cpp:157
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
Definition: validation.cpp:110
std::unique_ptr< CChainParams > CreateChainParams(const std::string &chain)
Creates and returns a std::unique_ptr<CChainParams> of the chosen chain.
bool m_log_time_micros
Definition: logging.h:95
#define NODISCARD
Definition: attributes.h:18
#define LOCK(cs)
Definition: sync.h:230
const char * name
Definition: rest.cpp:43
void ECC_Stop()
Deinitialize the elliptic curve support.
Definition: key.cpp:455
std::unique_ptr< TxIndex > g_txindex
The global transaction index, used in GetTransaction. May be null.
Definition: txindex.cpp:21
std::string ToString() const
Definition: validation.h:122
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:55
NetEventsInterface * m_msgproc
Definition: net.h:195
static void RegisterAllRPCCommands(const Config &config, RPCServer &rpcServer, CRPCTable &rpcTable)
Register all context-sensitive RPC commands.
Definition: register.h:43
int atoi(const std::string &str)
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netaddress.h:179
void format(std::ostream &out, const char *fmt, const Args &... args)
Format list of arguments to the stream according to given format string.
Definition: tinyformat.h:1111
bool g_relay_txes
Definition: net.cpp:111
std::vector< std::string > vSeedNodes
Definition: net.h:202
std::unique_ptr< avalanche::Processor > g_avalanche
Global avalanche instance.
Definition: processor.cpp:28
const util::Ref & context
Definition: httprpc.h:25
uint256 uint256S(const char *str)
uint256 from const char *.
Definition: uint256.h:131
std::vector< std::string > m_specified_outgoing
Definition: net.h:207
void DestroyAllBlockFilterIndexes()
Destroy all open block filter indexes.
bool LoadMempool(const Config &config, CTxMemPool &pool)
Load the mempool from disk.
RAII wrapper for VerifyDB: Verify consistency of the block and coin databases.
Definition: validation.h:596
CTxMemPool g_mempool
Definition: validation.cpp:112
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:546
const fs::path & GetDataDir(bool fNetSpecific)
Definition: system.cpp:760
static constexpr int64_t DEFAULT_DB_CACHE_MB
-dbcache default (MiB)
Definition: txdb.h:35
static BlockHash fromHex(const std::string &str)
Definition: blockhash.h:17
static const unsigned int DEFAULT_MEMPOOL_EXPIRY
Default for -mempoolexpiry, expiration time for mempool transactions in hours.
Definition: validation.h:75
FILE * OpenBlockFile(const FlatFilePos &pos, bool fReadOnly)
Open a block file (blk?????.dat).
Definition: blockdb.cpp:20
static const int DEFAULT_STOPATHEIGHT
Default for -stopatheight.
Definition: validation.h:155
void InitSignatureCache()
Definition: sigcache.cpp:71
RecursiveMutex cs_main
Global state.
Definition: validation.cpp:90
static constexpr std::chrono::minutes DUMP_BANS_INTERVAL
Definition: banman.h:22
int nMaxFeeler
Definition: net.h:192
CMainSignals & GetMainSignals()
Network
Definition: netaddress.h:19
void Start()
Start initializes the sync state and registers the instance as a ValidationInterface so that it stays...
Definition: base.cpp:308
static const bool DEFAULT_FEEFILTER
Default for using fee filter.
Definition: validation.h:141
Class for registering and managing all RPC calls.
Definition: server.h:41
bool InitError(const bilingual_str &str)
Show error message.
static const unsigned int DEFAULT_MAX_PEER_CONNECTIONS
The maximum number of peer connections to maintain.
Definition: net.h:97
ChainstateManager g_chainman
Definition: validation.cpp:65
#define WAIT_LOCK(cs, name)
Definition: sync.h:238
std::atomic_bool fImporting
std::string ToString() const
Definition: uint256.h:74
static const unsigned int DEFAULT_MAX_SCRIPT_CACHE_SIZE
Definition: scriptcache.h:40
void StartRPC()
Definition: server.cpp:339
static fs::path GetPidFile(const ArgsManager &args)
Definition: init.cpp:108
Parameters that influence chain consensus.
Definition: params.h:59
const std::string CLIENT_NAME
virtual void SetExcessUTXOCharge(Amount amt)=0
static const int DEFAULT_NAME_LOOKUP
-dns default
Definition: netbase.h:26
void AddTransactionsUpdated(unsigned int n)
Definition: txmempool.cpp:414
fs::path AbsPathForConfigVal(const fs::path &path, bool net_specific)
Most paths passed as configuration arguments are treated as relative to the datadir if they are not a...
Definition: system.cpp:1352
RecursiveMutex g_cs_orphans
uint32_t nBytesPerSigOp
Definition: settings.cpp:12
static const char *const DEFAULT_BLOCKFILTERINDEX
Definition: validation.h:136
static constexpr size_t AVALANCHE_DEFAULT_COOLDOWN
Avalanche default cooldown in milliseconds.
Definition: processor.h:50
int nConnectTimeout
Definition: netbase.cpp:32
static const int DEFAULT_ZMQ_SNDHWM
bool LoadBlockIndex(const Consensus::Params &params) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the block tree and coins database from disk, initializing state if we&#39;re running with -reindex...
static NODISCARD bool CreatePidFile(const ArgsManager &args)
Definition: init.cpp:113
static const bool DEFAULT_PROXYRANDOMIZE
Definition: init.cpp:89
bool IsHexNumber(const std::string &str)
Return true if the string is a hex number, optionally prefixed with "0x".
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:261
int64_t nMaxTipAge
If the tip is older than this (in seconds), the node is considered to be in initial block download...
Definition: validation.cpp:105
void DumpBanlist()
Definition: banman.cpp:49
std::string FormatFullVersion()
virtual void AddWalletOptions(ArgsManager &argsman) const =0
Get wallet help string.
bool SetProxy(enum Network net, const proxyType &addrProxy)
Definition: netbase.cpp:772
void StopHTTPRPC()
Stop HTTP RPC subsystem.
Definition: httprpc.cpp:479
bool StartLogging()
Start logging (and flush all buffered messages)
Definition: logging.cpp:39
enum Network ParseNetwork(const std::string &net_in)
Definition: netbase.cpp:40
void StartREST(const util::Ref &context)
Start HTTP REST subsystem.
Definition: rest.cpp:769
bool StartHTTPRPC(HTTPRPCRequestProcessor &httpRPCRequestProcessor)
Start HTTP RPC subsystem.
Definition: httprpc.cpp:454
bool(* handler)(Config &config, const util::Ref &context, HTTPRequest *req, const std::string &strReq)
Definition: rest.cpp:755
uint64_t nMaxOutboundTimeframe
Definition: net.h:199
std::atomic_bool fReindex
void RegisterBackgroundSignalScheduler(CScheduler &scheduler)
Register a CScheduler to give callbacks which should run in the background (may only be called once) ...
std::string get_filesystem_error_message(const fs::filesystem_error &e)
Definition: fs.cpp:129
bool glibcxx_sanity_test()
256-bit opaque blob.
Definition: uint256.h:120
bool fCheckBlockIndex
Definition: validation.cpp:101
std::vector< NetWhitelistPermissions > vWhitelistedRange
Definition: net.h:203
ArgsManager * args
Definition: context.h:44
void RegisterZMQRPCCommands(CRPCTable &t)
Definition: zmqrpc.cpp:68
uint256 nMinimumChainWork
Definition: params.h:109
bool RequireStandard() const
Policy: Filter transactions that do not match well-defined patterns.
Definition: chainparams.h:68
static const bool DEFAULT_CHECKPOINTS_ENABLED
Definition: validation.h:134
const WalletInitInterface & g_wallet_init_interface
Definition: init.cpp:38
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56
static constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME
Definition: banman.h:20
static const bool DEFAULT_WHITELISTFORCERELAY
Default for -whitelistforcerelay.
Definition: net.h:50
static constexpr int64_t MAX_BLOCK_DB_CACHE_MB
Max memory allocated to block tree DB specific cache, if no -txindex (MiB)
Definition: txdb.h:39
bool IsTestChain() const
If this chain is exclusively used for testing.
Definition: chainparams.h:70
void StopRPC()
Definition: server.cpp:351
int nMaxAddnode
Definition: net.h:191
static const unsigned int DEFAULT_BYTES_PER_SIGOP
Default for -bytespersigop .
Definition: policy.h:57
bool IsValid() const
Definition: netbase.h:35
static const char * DEFAULT_ASMAP_FILENAME
Definition: init.cpp:101
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:44
bool fRequireStandard
Definition: validation.cpp:100
static const size_t DEFAULT_MAXSENDBUFFER
Definition: net.h:109
virtual bool ParameterInteraction() const =0
Check wallet parameter interaction.
MapCheckpoints mapCheckpoints
Definition: chainparams.h:25
static constexpr int64_t MAX_FILTER_INDEX_CACHE_MB
Max memory allocated to all block filter index caches combined in MiB.
Definition: txdb.h:46
std::string original
Definition: translation.h:18
static void new_handler_terminate()
Definition: init.cpp:1638
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:812
static const uint64_t DEFAULT_MAX_UPLOAD_TARGET
The default for -maxuploadtarget.
Definition: net.h:99
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: blockindex.h:23
static bool TryParse(const std::string str, NetWhitebindPermissions &output, bilingual_str &error)
void FlushBackgroundCallbacks()
Call any remaining callbacks on the calling thread.
static const signed int DEFAULT_CHECKBLOCKS
Definition: validation.h:224
bool ParseMoney(const std::string &money_string, Amount &nRet)
Parse an amount denoted in full coins.
Definition: moneystr.cpp:34
void RpcInterruptionPoint()
Throw JSONRPCError if RPC is not running.
Definition: server.cpp:362
std::map< int, BlockHash > MapCheckpoints
Definition: chainparams.h:22
static const unsigned int DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN
Default number of orphan+recently-replaced txn to keep around for block reconstruction.
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:479
ServiceFlags nLocalServices
Definition: net.h:187
void InterruptREST()
Interrupt RPC REST subsystem.
Definition: rest.cpp:779
bool fLogIPs
Definition: logging.cpp:12
int64_t GetAdjustedTime()
Definition: timedata.cpp:34
BlockMap & BlockIndex()
Definition: validation.cpp:926
uint64_t nMaxOutboundLimit
Definition: net.h:200
std::vector< std::string > m_added_nodes
Definition: net.h:208
static const int DEFAULT_CONNECT_TIMEOUT
-timeout default
Definition: netbase.h:24
bool AppInitBasicSetup(ArgsManager &args)
Initialize bitcoin: Basic context setup.
Definition: init.cpp:1649
CBlockIndex * LookupBlockIndex(const BlockHash &hash)
Definition: validation.cpp:140
std::string FormatSubVersion(const std::string &name, int nClientVersion, const std::vector< std::string > &comments)
Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip...
CChainState &InitializeChainstate(const BlockHash &snapshot_blockhash=BlockHash()) EXCLUSIVE_LOCKS_REQUIRED(std::vector< CChainState * > GetAll()
Instantiate a new chainstate and assign it based upon whether it is from a snapshot.
Definition: validation.h:1139
std::string GetHex() const
Definition: uint256.cpp:16
void AbortShutdown()
Definition: shutdown.cpp:15
ArgsManager gArgs
Definition: system.cpp:76
bool fListen
Definition: net.cpp:110
void LogArgs() const
Log the config file options and the command line arguments, useful for troubleshooting.
Definition: system.cpp:1079
static Mutex g_genesis_wait_mutex
Definition: init.cpp:1278
Fee rate in satoshis per kilobyte: Amount / kB.
Definition: feerate.h:21
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:657
std::unique_ptr< PeerLogicValidation > peer_logic
Definition: context.h:39
std::unique_ptr< CBlockTreeDB > pblocktree
Global variable that points to the active block tree (protected by cs_main)
Definition: validation.cpp:166
static const int DEFAULT_MAX_REORG_DEPTH
Default for -maxreorgdepth.
Definition: validation.h:157
static const unsigned int MAX_SUBVERSION_LENGTH
Maximum length of the user agent string in version message.
Definition: net.h:74
static bool AppInitServers(Config &config, HTTPRPCRequestProcessor &httpRPCRequestProcessor, NodeContext &node)
Definition: init.cpp:1465
static const bool DEFAULT_UPNP
-upnp default
Definition: net.h:90
static const int64_t DEFAULT_PEER_CONNECT_TIMEOUT
-peertimeout default
Definition: net.h:105
void StartShutdown()
Definition: shutdown.cpp:12
static const bool DEFAULT_BLOCKSONLY
Default for blocks only.
Definition: net.h:103
static constexpr unsigned int DEFAULT_ANCESTOR_LIMIT
Default for -limitancestorcount, max number of in-mempool ancestors.
Definition: mempool.h:15
static const std::string TESTNET
void RegisterValidationInterface(CValidationInterface *callbacks)
Register a wallet to receive updates from core.
bool isValid(enum BlockValidity nUpTo=BlockValidity::TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
Definition: blockstatus.h:94
static std::vector< bool > DecodeAsmap(fs::path path)
Definition: addrman.cpp:742
unsigned int nSendBufferMaxSize
Definition: net.h:197
void StartHTTPServer()
Start HTTP server.
Definition: httpserver.cpp:466
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
Definition: system.cpp:1014
const std::list< SectionInfo > GetUnrecognizedSections() const
Log warnings for unrecognized section names in the config file.
Definition: system.cpp:274
void InterruptTorControl()
Definition: torcontrol.cpp:889
bool m_log_timestamps
Definition: logging.h:94
static const bool DEFAULT_WHITELISTRELAY
Default for -whitelistrelay.
Definition: net.h:48
std::string GetHex() const
bool AppInitLockDataDirectory()
Lock bitcoin data directory.
Definition: init.cpp:2081
static bool InitSanityCheck()
Sanity checks Ensure that Bitcoin is running in a usable environment with all necessary library suppo...
Definition: init.cpp:1447
virtual bool SetMaxBlockSize(uint64_t maxBlockSize)=0
static const int MAX_OUTBOUND_FULL_RELAY_CONNECTIONS
Maximum number of automatic outgoing nodes over which we&#39;ll relay everything (blocks, tx, addrs, etc)
Definition: net.h:79
void ScheduleBatchPriority()
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
Definition: system.cpp:1359
static const bool DEFAULT_LOGIPS
Definition: logging.h:21
static constexpr int64_t MAX_COINS_DB_CACHE_MB
Max memory allocated to coin DB specific cache (MiB)
Definition: txdb.h:48
CClientUIInterface uiInterface
bool ECC_InitSanityCheck()
Check that required EC support is available at runtime.
Definition: key.cpp:431
static const char * BITCOIN_PID_FILENAME
The PID file facilities.
Definition: init.cpp:106
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:59
static const bool DEFAULT_PRINTPRIORITY
Definition: miner.h:27
static void registerSignalHandler(int signal, void(*handler)(int))
Definition: init.cpp:354
static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES
Require that user allocate at least 550 MiB for block & undo files (blk???.dat and rev...
Definition: validation.h:240
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:381
static const uint64_t DEFAULT_MAX_BLOCK_SIZE
Default setting for maximum allowed size for a block, in bytes.
Definition: consensus.h:20
#define MIN_CORE_FILEDESCRIPTORS
Definition: init.cpp:98
int64_t GetTime()
Return system time (or mocked time, if set)
Definition: time.cpp:27
static const unsigned int DEFAULT_MAX_ORPHAN_TRANSACTIONS
Default for -maxorphantx, maximum number of orphan transactions kept in memory.
void SetIsLoaded(bool loaded)
Sets the current loaded state.
Definition: txmempool.cpp:1277
const char *const DEFAULT_DEBUGLOGFILE
Definition: logging.cpp:13
void OnStopped(std::function< void()> slot)
Definition: server.cpp:110
static void Sleep(int nMilliSec)
Definition: util.h:13
static const bool DEFAULT_LISTEN_ONION
Definition: torcontrol.h:14
bool m_use_addrman_outgoing
Definition: net.h:206
bool InitHTTPServer(Config &config)
Initialize HTTP server.
Definition: httpserver.cpp:388
std::vector< NetWhitebindPermissions > vWhiteBinds
Definition: net.h:204
const std::set< std::string > GetUnsuitableSectionOnlyArgs() const
Log warnings for options in m_section_only_args when they are specified in the default section but no...
Definition: system.cpp:250
static const uint64_t DEFAULT_MAX_GENERATED_BLOCK_SIZE
Default for -blockmaxsize, which controls the maximum size of block the mining code will create...
Definition: policy.h:24
bool error(const char *fmt, const Args &... args)
Definition: system.h:47
bool Random_SanityCheck()
Check that OS randomness is available and returning the requested number of bytes.
Definition: random.cpp:701
BIP-0014 subset.
Definition: strencodings.h:26
static const bool DEFAULT_LOGTIMESTAMPS
Definition: logging.h:22
static const bool DEFAULT_TXINDEX
Definition: validation.h:135
CFeeRate dustRelayFee
Definition: settings.cpp:11
static const int DEFAULT_HTTP_THREADS
Definition: httpserver.h:12
static const bool DEFAULT_REST_ENABLE
Definition: init.cpp:90
static bool TryParse(const std::string str, NetWhitelistPermissions &output, bilingual_str &error)
bool fNameLookup
Definition: netbase.cpp:33
void StartMapPort()
Definition: net.cpp:1732
bool LoadExternalBlockFile(const Config &config, FILE *fileIn, FlatFilePos *dbp)
Import blocks from an external file.
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:1490
bool AppInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, NodeContext &node)
Bitcoin main initialization.
Definition: init.cpp:2093
static const int64_t DEFAULT_MAX_TIME_ADJUSTMENT
Definition: timedata.h:13
void InterruptMapPort()
Definition: net.cpp:1735
static const unsigned int DEFAULT_CHECKLEVEL
Definition: validation.h:225
size_t nCoinCacheUsage
Definition: validation.cpp:103
int nBestHeight
Definition: net.h:193
static const int MAX_SCRIPTCHECK_THREADS
Maximum number of dedicated script-checking threads allowed.
Definition: validation.h:80
#define Assert(val)
Identity function.
Definition: check.h:57
void ShrinkDebugFile()
Definition: logging.cpp:273
std::string FormatMoney(const Amount amt)
Money parsing/formatting utilities.
Definition: moneystr.cpp:12
const std::string UNIX_EPOCH_TIME
String used to describe UNIX epoch time in documentation, factored out to a constant for consistency...
Definition: util.cpp:21
CZMQNotificationInterface * g_zmq_notification_interface
static bool LockDataDirectory(bool probeOnly)
Definition: init.cpp:2042
bool AppInitParameterInteraction(Config &config, const ArgsManager &args)
Initialization: parameter interaction.
Definition: init.cpp:1692
const std::string & BlockFilterTypeName(BlockFilterType filter_type)
Get the human-readable name for a filter type.
static void ThreadImport(const Config &config, ChainstateManager &chainman, std::vector< fs::path > vImportFiles, const ArgsManager &args)
Definition: init.cpp:1345
static bool fHaveGenesis
Definition: init.cpp:1277
std::unique_ptr< CScheduler > scheduler
Definition: context.h:47
BlockHash hashAssumeValid
Block hash whose ancestors we will assume to have valid scripts without checking them.
Definition: validation.cpp:107
int64_t m_peer_connect_timeout
Definition: net.h:201
bool DefaultShrinkDebugFile() const
Default for whether ShrinkDebugFile should be run.
Definition: logging.cpp:350
CTxMemPool * mempool
Definition: context.h:38