Bitcoin ABC  0.24.7
P2P Digital Currency
bitcoind.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2019 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 <chainparams.h>
11 #include <clientversion.h>
12 #include <compat.h>
13 #include <config.h>
14 #include <httprpc.h>
15 #include <init.h>
16 #include <interfaces/chain.h>
17 #include <network.h>
18 #include <node/context.h>
19 #include <node/ui_interface.h>
20 #include <noui.h>
21 #include <shutdown.h>
22 #include <util/ref.h>
23 #include <util/strencodings.h>
24 #include <util/system.h>
25 #include <util/threadnames.h>
26 #include <util/translation.h>
27 
28 #include <functional>
29 
30 const std::function<std::string(const char *)> G_TRANSLATION_FUN = nullptr;
31 
32 static void WaitForShutdown(NodeContext &node) {
33  while (!ShutdownRequested()) {
34  UninterruptibleSleep(std::chrono::milliseconds{200});
35  }
36  Interrupt(node);
37 }
38 
40 //
41 // Start
42 //
43 static bool AppInit(int argc, char *argv[]) {
44  // FIXME: Ideally, we'd like to build the config here, but that's currently
45  // not possible as the whole application has too many global state. However,
46  // this is a first step.
47  auto &config = const_cast<Config &>(GetConfig());
48 
49  RPCServer rpcServer;
50 
51  NodeContext node;
52  util::Ref context{node};
53 
54  HTTPRPCRequestProcessor httpRPCRequestProcessor(config, rpcServer, context);
55 
56  bool fRet = false;
57 
59 
60  // If Qt is used, parameters/bitcoin.conf are parsed in qt/bitcoin.cpp's
61  // main()
62  SetupServerArgs(node);
63  ArgsManager &args = *Assert(node.args);
64  std::string error;
65  if (!args.ParseParameters(argc, argv, error)) {
66  return InitError(Untranslated(
67  strprintf("Error parsing command line arguments: %s\n", error)));
68  }
69 
70  // Process help and version before taking care about datadir
71  if (HelpRequested(args) || args.IsArgSet("-version")) {
72  std::string strUsage =
73  PACKAGE_NAME " version " + FormatFullVersion() + "\n";
74 
75  if (args.IsArgSet("-version")) {
76  strUsage += FormatParagraph(LicenseInfo()) + "\n";
77  } else {
78  strUsage += "\nUsage: bitcoind [options] "
79  "Start " PACKAGE_NAME "\n";
80  strUsage += "\n" + args.GetHelpMessage();
81  }
82 
83  tfm::format(std::cout, "%s", strUsage);
84  return true;
85  }
86 
87  try {
88  if (!CheckDataDirOption()) {
89  return InitError(Untranslated(
90  strprintf("Specified data directory \"%s\" does not exist.\n",
91  args.GetArg("-datadir", ""))));
92  }
93  if (!args.ReadConfigFiles(error, true)) {
94  return InitError(Untranslated(
95  strprintf("Error reading configuration file: %s\n", error)));
96  }
97  // Check for -chain, -testnet or -regtest parameter (Params() calls are
98  // only valid after this clause)
99  try {
100  SelectParams(args.GetChainName());
101  } catch (const std::exception &e) {
102  return InitError(Untranslated(strprintf("%s\n", e.what())));
103  }
104 
105  // Make sure we create the net-specific data directory early on: if it
106  // is new, this has a side effect of also creating
107  // <datadir>/<net>/wallets/.
108  //
109  // TODO: this should be removed once GetDataDir() no longer creates the
110  // wallets/ subdirectory.
111  // See more info at:
112  // https://reviews.bitcoinabc.org/D3312
113  GetDataDir(true);
114 
115  // Error out when loose non-argument tokens are encountered on command
116  // line
117  for (int i = 1; i < argc; i++) {
118  if (!IsSwitchChar(argv[i][0])) {
119  return InitError(Untranslated(
120  strprintf("Command line contains unexpected token '%s', "
121  "see bitcoind -h for a list of options.\n",
122  argv[i])));
123  }
124  }
125 
126  if (!args.InitSettings(error)) {
128  return false;
129  }
130 
131  // -server defaults to true for bitcoind but not for the GUI so do this
132  // here
133  args.SoftSetBoolArg("-server", true);
134  // Set this early so that parameter interactions go to console
135  InitLogging(args);
137  if (!AppInitBasicSetup(args)) {
138  // InitError will have been called with detailed error, which ends
139  // up on console
140  return false;
141  }
142  if (!AppInitParameterInteraction(config, args)) {
143  // InitError will have been called with detailed error, which ends
144  // up on console
145  return false;
146  }
147  if (!AppInitSanityChecks()) {
148  // InitError will have been called with detailed error, which ends
149  // up on console
150  return false;
151  }
152  if (args.GetBoolArg("-daemon", false)) {
153 #if HAVE_DECL_DAEMON
154 #if defined(MAC_OSX)
155 #pragma GCC diagnostic push
156 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
157 #endif
158  tfm::format(std::cout, PACKAGE_NAME " starting\n");
159 
160  // Daemonize
161  if (daemon(1, 0)) {
162  // don't chdir (1), do close FDs (0)
163  return InitError(Untranslated(
164  strprintf("daemon() failed: %s\n", strerror(errno))));
165  }
166 #if defined(MAC_OSX)
167 #pragma GCC diagnostic pop
168 #endif
169 #else
170  return InitError(Untranslated(
171  "-daemon is not supported on this operating system\n"));
172 #endif // HAVE_DECL_DAEMON
173  }
174 
175  // Lock data directory after daemonization
176  if (!AppInitLockDataDirectory()) {
177  // If locking the data directory failed, exit immediately
178  return false;
179  }
180  fRet = AppInitInterfaces(node) &&
181  AppInitMain(config, rpcServer, httpRPCRequestProcessor, node);
182  } catch (const std::exception &e) {
183  PrintExceptionContinue(&e, "AppInit()");
184  } catch (...) {
185  PrintExceptionContinue(nullptr, "AppInit()");
186  }
187 
188  if (!fRet) {
189  Interrupt(node);
190  } else {
191  WaitForShutdown(node);
192  }
193  Shutdown(node);
194 
195  return fRet;
196 }
197 
198 int main(int argc, char *argv[]) {
199 #ifdef WIN32
200  util::WinCmdLineArgs winArgs;
201  std::tie(argc, argv) = winArgs.get();
202 #endif
204 
205  // Connect bitcoind signal handlers
206  noui_connect();
207 
208  return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
209 }
AppInitInterfaces
bool AppInitInterfaces(NodeContext &node)
Initialize node and wallet interface pointers.
Definition: init.cpp:2166
ShutdownRequested
bool ShutdownRequested()
Definition: shutdown.cpp:18
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:517
ref.h
GetDataDir
const fs::path & GetDataDir(bool fNetSpecific)
Definition: system.cpp:779
G_TRANSLATION_FUN
const std::function< std::string(const char *)> G_TRANSLATION_FUN
Translate string to current locale using Qt.
Definition: bitcoind.cpp:30
tinyformat::format
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
InitParameterInteraction
void InitParameterInteraction(ArgsManager &args)
Parameter interaction: change current parameters depending on various rules.
Definition: init.cpp:1562
NodeContext::args
ArgsManager * args
Definition: context.h:44
CheckDataDirOption
bool CheckDataDirOption()
Definition: system.cpp:818
ArgsManager::SoftSetBoolArg
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: system.cpp:534
InitLogging
void InitLogging(const ArgsManager &args)
Initialize global loggers.
Definition: init.cpp:1674
ArgsManager::GetHelpMessage
std::string GetHelpMessage() const
Get the help string.
Definition: system.cpp:598
SetupEnvironment
void SetupEnvironment()
Definition: system.cpp:1306
ArgsManager::GetChainName
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
Definition: system.cpp:1033
ArgsManager::IsArgSet
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: system.cpp:400
WaitForShutdown
static void WaitForShutdown(NodeContext &node)
Definition: bitcoind.cpp:32
HTTPRPCRequestProcessor
Definition: httprpc.h:17
LicenseInfo
std::string LicenseInfo()
Returns licensing information (for -version)
Definition: init.cpp:1303
clientversion.h
ArgsManager::InitSettings
bool InitSettings(std::string &error)
Read and update settings file with saved settings.
Definition: system.cpp:404
SetupServerArgs
void SetupServerArgs(NodeContext &node)
Register all arguments with the ArgsManager.
Definition: init.cpp:388
chainparams.h
chain.h
context.h
RPCServer
Class for registering and managing all RPC calls.
Definition: server.h:40
Assert
#define Assert(val)
Identity function.
Definition: check.h:56
noui_connect
void noui_connect()
Connect all bitcoind signal handlers.
Definition: noui.cpp:59
AppInitMain
bool AppInitMain(Config &config, RPCServer &rpcServer, HTTPRPCRequestProcessor &httpRPCRequestProcessor, NodeContext &node, interfaces::BlockAndHeaderTipInfo *tip_info)
Bitcoin main initialization.
Definition: init.cpp:2176
shutdown.h
HelpRequested
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:671
strencodings.h
Config
Definition: config.h:17
util::Ref
Type-safe dynamic reference.
Definition: ref.h:21
main
int main(int argc, char *argv[])
Definition: bitcoind.cpp:198
Untranslated
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:36
init.h
compat.h
InitError
bool InitError(const bilingual_str &str)
Show error message.
Definition: ui_interface.cpp:96
IsSwitchChar
bool IsSwitchChar(char c)
Definition: system.h:116
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:498
Interrupt
void Interrupt(NodeContext &node)
Interrupt threads.
Definition: init.cpp:164
SelectParams
void SelectParams(const std::string &network)
Sets the params returned by Params() to those for the given BIP70 chain name.
Definition: chainparams.cpp:528
AppInit
static bool AppInit(int argc, char *argv[])
Definition: bitcoind.cpp:43
ArgsManager::ParseParameters
NODISCARD bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:317
AppInitSanityChecks
bool AppInitSanityChecks()
Initialization sanity checks: ecc init, sanity checks, dir lock.
Definition: init.cpp:2131
ArgsManager::ReadConfigFiles
NODISCARD bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:930
ui_interface.h
UninterruptibleSleep
void UninterruptibleSleep(const std::chrono::microseconds &n)
Definition: time.cpp:20
system.h
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1201
httprpc.h
AppInitLockDataDirectory
bool AppInitLockDataDirectory()
Lock bitcoin data directory.
Definition: init.cpp:2154
AppInitBasicSetup
bool AppInitBasicSetup(ArgsManager &args)
Initialize bitcoin: Basic context setup.
Definition: init.cpp:1723
ArgsManager
Definition: system.h:152
translation.h
network.h
noui.h
AppInitParameterInteraction
bool AppInitParameterInteraction(Config &config, const ArgsManager &args)
Initialization: parameter interaction.
Definition: init.cpp:1766
config.h
FormatFullVersion
std::string FormatFullVersion()
Definition: clientversion.cpp:58
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
NodeContext
NodeContext struct containing references to chain state and connection state.
Definition: context.h:36
threadnames.h
GetConfig
const Config & GetConfig()
Definition: config.cpp:34
util::ThreadSetInternalName
void ThreadSetInternalName(std::string &&)
Set the internal (in-memory) name of the current thread only.
Definition: threadnames.cpp:53
Shutdown
void Shutdown(NodeContext &node)
Definition: init.cpp:185
PrintExceptionContinue
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:716
FormatParagraph
std::string FormatParagraph(const std::string &in, size_t width, size_t indent)
Format a paragraph of text to a fixed width, adding spaces for indentation to any added line.
Definition: strencodings.cpp:429