Bitcoin ABC  0.24.7
P2P Digital Currency
system.h
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 
10 #ifndef BITCOIN_UTIL_SYSTEM_H
11 #define BITCOIN_UTIL_SYSTEM_H
12 
13 #if defined(HAVE_CONFIG_H)
14 #include <config/bitcoin-config.h>
15 #endif
16 
17 #include <attributes.h>
18 #include <compat.h>
19 #include <compat/assumptions.h>
20 #include <fs.h>
21 #include <logging.h>
22 #include <sync.h>
23 #include <tinyformat.h>
24 #include <util/settings.h>
25 #include <util/threadnames.h>
26 #include <util/time.h>
27 
28 #include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted
29 
30 #include <cstdint>
31 #include <exception>
32 #include <map>
33 #include <optional>
34 #include <set>
35 #include <string>
36 #include <utility>
37 #include <vector>
38 
39 // Application startup time (used for uptime calculation)
40 int64_t GetStartupTime();
41 
42 extern const char *const BITCOIN_CONF_FILENAME;
43 extern const char *const BITCOIN_SETTINGS_FILENAME;
44 
45 void SetupEnvironment();
46 bool SetupNetworking();
47 
48 template <typename... Args> bool error(const char *fmt, const Args &... args) {
49  LogPrintf("ERROR: %s\n", tfm::format(fmt, args...));
50  return false;
51 }
52 
53 void PrintExceptionContinue(const std::exception *pex, const char *pszThread);
54 bool FileCommit(FILE *file);
55 bool TruncateFile(FILE *file, unsigned int length);
56 int RaiseFileDescriptorLimit(int nMinFD);
57 void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length);
58 bool RenameOver(fs::path src, fs::path dest);
59 bool LockDirectory(const fs::path &directory, const std::string lockfile_name,
60  bool probe_only = false);
61 void UnlockDirectory(const fs::path &directory,
62  const std::string &lockfile_name);
63 bool DirIsWritable(const fs::path &directory);
64 bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes = 0);
65 
73 std::streampos
74 GetFileSize(const char *path,
75  std::streamsize max = std::numeric_limits<std::streamsize>::max());
76 
82 
83 bool TryCreateDirectories(const fs::path &p);
84 fs::path GetDefaultDataDir();
85 // The blocks directory is always net specific.
86 const fs::path &GetBlocksDir();
87 const fs::path &GetDataDir(bool fNetSpecific = true);
88 // Return true if -datadir option points to a valid directory or is not
89 // specified.
90 bool CheckDataDirOption();
92 void ClearDatadirCache();
93 fs::path GetConfigFile(const std::string &confPath);
94 #ifdef WIN32
95 fs::path GetSpecialFolderPath(int nFolder, bool fCreate = true);
96 #endif
97 #ifndef WIN32
98 std::string ShellEscape(const std::string &arg);
99 #endif
100 #if defined(HAVE_SYSTEM)
101 void runCommand(const std::string &strCommand);
102 #endif
103 
104 NODISCARD bool ParseKeyValue(std::string &key, std::string &val);
105 
114 fs::path AbsPathForConfigVal(const fs::path &path, bool net_specific = true);
115 
116 inline bool IsSwitchChar(char c) {
117 #ifdef WIN32
118  return c == '-' || c == '/';
119 #else
120  return c == '-';
121 #endif
122 }
123 
124 enum class OptionsCategory {
125  OPTIONS,
126  CONNECTION,
127  WALLET,
129  ZMQ,
130  DEBUG_TEST,
131  CHAINPARAMS,
132  NODE_RELAY,
134  RPC,
135  GUI,
136  COMMANDS,
138 
139  // Always the last option to avoid printing these in the help
140  HIDDEN,
141 
142  // Avalanche is still experimental, so we keep it hidden for now.
143  AVALANCHE,
144 };
145 
146 struct SectionInfo {
147  std::string m_name;
148  std::string m_file;
149  int m_line;
150 };
151 
152 class ArgsManager {
153 public:
154  enum Flags {
155  // Boolean options can accept negation syntax -noOPTION or -noOPTION=1
156  ALLOW_BOOL = 0x01,
157  ALLOW_INT = 0x02,
158  ALLOW_STRING = 0x04,
160  DEBUG_ONLY = 0x100,
161  /* Some options would cause cross-contamination if values for
162  * mainnet were used while running on regtest/testnet (or vice-versa).
163  * Setting them as NETWORK_ONLY ensures that sharing a config file
164  * between mainnet and regtest/testnet won't cause problems due to these
165  * parameters by accident. */
166  NETWORK_ONLY = 0x200,
167  // This argument's value is sensitive (such as a password).
168  SENSITIVE = 0x400,
169  };
170 
171 protected:
172  struct Arg {
173  std::string m_help_param;
174  std::string m_help_text;
175  unsigned int m_flags;
176  };
177 
179  util::Settings m_settings GUARDED_BY(cs_args);
180  std::string m_network GUARDED_BY(cs_args);
181  std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
182  std::map<OptionsCategory, std::map<std::string, Arg>>
183  m_available_args GUARDED_BY(cs_args);
184  std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
185 
186  NODISCARD bool ReadConfigStream(std::istream &stream,
187  const std::string &filepath,
188  std::string &error,
189  bool ignore_invalid_keys = false);
190 
196  bool UseDefaultSection(const std::string &arg) const
198 
206  util::SettingsValue GetSetting(const std::string &arg) const;
207 
211  std::vector<util::SettingsValue>
212  GetSettingsList(const std::string &arg) const;
213 
214 public:
215  ArgsManager();
216  ~ArgsManager();
217 
221  void SelectConfigNetwork(const std::string &network);
222 
223  NODISCARD bool ParseParameters(int argc, const char *const argv[],
224  std::string &error);
225  NODISCARD bool ReadConfigFiles(std::string &error,
226  bool ignore_invalid_keys = false);
227 
233  const std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
234 
238  const std::list<SectionInfo> GetUnrecognizedSections() const;
239 
246  std::vector<std::string> GetArgs(const std::string &strArg) const;
247 
254  bool IsArgSet(const std::string &strArg) const;
255 
263  bool IsArgNegated(const std::string &strArg) const;
264 
272  std::string GetArg(const std::string &strArg,
273  const std::string &strDefault) const;
274 
282  int64_t GetArg(const std::string &strArg, int64_t nDefault) const;
283 
291  bool GetBoolArg(const std::string &strArg, bool fDefault) const;
292 
300  bool SoftSetArg(const std::string &strArg, const std::string &strValue);
301 
309  bool SoftSetBoolArg(const std::string &strArg, bool fValue);
310 
311  // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
312  // been set. Also called directly in testing.
313  void ForceSetArg(const std::string &strArg, const std::string &strValue);
314 
315  // Forces a multi arg setting, used only in testing
316  void ForceSetMultiArg(const std::string &strArg,
317  const std::vector<std::string> &values);
318 
325  std::string GetChainName() const;
326 
330  void AddArg(const std::string &name, const std::string &help,
331  unsigned int flags, const OptionsCategory &cat);
332 
336  void ClearForcedArg(const std::string &strArg);
337 
341  void AddHiddenArgs(const std::vector<std::string> &args);
342 
346  void ClearArgs() {
347  LOCK(cs_args);
348  m_available_args.clear();
349  m_network_only_args.clear();
350  }
351 
355  std::string GetHelpMessage() const;
356 
361  std::optional<unsigned int> GetArgFlags(const std::string &name) const;
362 
368  bool InitSettings(std::string &error);
369 
374  bool GetSettingsPath(fs::path *filepath = nullptr, bool temp = false) const;
375 
379  bool ReadSettingsFile(std::vector<std::string> *errors = nullptr);
380 
384  bool WriteSettingsFile(std::vector<std::string> *errors = nullptr) const;
385 
389  template <typename Fn> void LockSettings(Fn &&fn) {
390  LOCK(cs_args);
391  fn(m_settings);
392  }
393 
398  void LogArgs() const;
399 
400 private:
401  // Helper function for LogArgs().
402  void
403  logArgsPrefix(const std::string &prefix, const std::string &section,
404  const std::map<std::string, std::vector<util::SettingsValue>>
405  &args) const;
406 };
407 
408 extern ArgsManager gArgs;
409 
413 bool HelpRequested(const ArgsManager &args);
414 
416 void SetupHelpOptions(ArgsManager &args);
417 
424 std::string HelpMessageGroup(const std::string &message);
425 
433 std::string HelpMessageOpt(const std::string &option,
434  const std::string &message);
435 
441 int GetNumCores();
442 
446 template <typename Callable> void TraceThread(const char *name, Callable func) {
448  try {
449  LogPrintf("%s thread start\n", name);
450  func();
451  LogPrintf("%s thread exit\n", name);
452  } catch (const boost::thread_interrupted &) {
453  LogPrintf("%s thread interrupt\n", name);
454  throw;
455  } catch (const std::exception &e) {
457  throw;
458  } catch (...) {
459  PrintExceptionContinue(nullptr, name);
460  throw;
461  }
462 }
463 
464 std::string CopyrightHolders(const std::string &strPrefix);
465 
471 void ScheduleBatchPriority();
472 
473 namespace util {
474 
476 template <typename Tdst, typename Tsrc>
477 inline void insert(Tdst &dst, const Tsrc &src) {
478  dst.insert(dst.begin(), src.begin(), src.end());
479 }
480 template <typename TsetT, typename Tsrc>
481 inline void insert(std::set<TsetT> &dst, const Tsrc &src) {
482  dst.insert(src.begin(), src.end());
483 }
484 
485 #ifdef WIN32
486 class WinCmdLineArgs {
487 public:
488  WinCmdLineArgs();
489  ~WinCmdLineArgs();
490  std::pair<int, char **> get();
491 
492 private:
493  int argc;
494  char **argv;
495  std::vector<std::string> args;
496 };
497 #endif
498 
499 } // namespace util
500 
501 #endif // BITCOIN_UTIL_SYSTEM_H
RenameOver
bool RenameOver(fs::path src, fs::path dest)
Definition: system.cpp:1110
ArgsManager::LogArgs
void LogArgs() const
Log the config file options and the command line arguments, useful for troubleshooting.
Definition: system.cpp:1098
SetupEnvironment
void SetupEnvironment()
Definition: system.cpp:1306
ArgsManager::GetBoolArg
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:517
ArgsManager::AddHiddenArgs
void AddHiddenArgs(const std::vector< std::string > &args)
Add many hidden arguments.
Definition: system.cpp:587
LockDirectory
bool LockDirectory(const fs::path &directory, const std::string lockfile_name, bool probe_only=false)
Definition: system.cpp:87
HelpRequested
bool HelpRequested(const ArgsManager &args)
Definition: system.cpp:671
ArgsManager::ALLOW_STRING
@ ALLOW_STRING
Definition: system.h:158
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
ArgsManager::GetArgFlags
std::optional< unsigned int > GetArgFlags(const std::string &name) const
Return Flags for known arg.
Definition: system.cpp:380
util::Settings
Stored settings.
Definition: settings.h:31
fs.h
OptionsCategory::RPC
@ RPC
GetFileSize
std::streampos GetFileSize(const char *path, std::streamsize max=std::numeric_limits< std::streamsize >::max())
Get the size of a file by scanning it.
Definition: system.cpp:148
flags
int flags
Definition: bitcoin-tx.cpp:532
ArgsManager::GetSetting
util::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
Definition: system.cpp:1067
ArgsManager::UseDefaultSection
bool UseDefaultSection(const std::string &arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args)
Returns true if settings values from the default section should be used, depending on the current net...
Definition: system.cpp:1062
OptionsCategory::AVALANCHE
@ AVALANCHE
ArgsManager::ALLOW_ANY
@ ALLOW_ANY
Definition: system.h:159
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
help
static RPCHelpMan help()
Definition: server.cpp:177
GetDataDir
const fs::path & GetDataDir(bool fNetSpecific=true)
Definition: system.cpp:779
BITCOIN_SETTINGS_FILENAME
const char *const BITCOIN_SETTINGS_FILENAME
Definition: system.cpp:73
sync.h
ArgsManager::GetHelpMessage
std::string GetHelpMessage() const
Get the help string.
Definition: system.cpp:598
gArgs
ArgsManager gArgs
Definition: system.cpp:75
ArgsManager::Flags
Flags
Definition: system.h:154
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
HelpMessageGroup
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: system.cpp:686
ClearDatadirCache
void ClearDatadirCache()
Tests only.
Definition: system.cpp:823
NODISCARD
#define NODISCARD
Definition: attributes.h:18
AllocateFileRange
void AllocateFileRange(FILE *file, unsigned int offset, unsigned int length)
This function tries to make a particular range of a file allocated (corresponding to disk space) it i...
Definition: system.cpp:1214
AnnotatedMixin< std::recursive_mutex >
ArgsManager::InitSettings
bool InitSettings(std::string &error)
Read and update settings file with saved settings.
Definition: system.cpp:404
OptionsCategory::CONNECTION
@ CONNECTION
SectionInfo::m_file
std::string m_file
Definition: system.h:148
TryCreateDirectories
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by Boost's create_directories if the requested directory exists.
Definition: system.cpp:1125
CheckDataDirOption
bool CheckDataDirOption()
Definition: system.cpp:818
UniValue
Definition: univalue.h:23
FileCommit
bool FileCommit(FILE *file)
Definition: system.cpp:1139
tinyformat.h
ArgsManager::~ArgsManager
~ArgsManager()
Definition: system.cpp:247
UnlockDirectory
void UnlockDirectory(const fs::path &directory, const std::string &lockfile_name)
Definition: system.cpp:115
ArgsManager::Arg
Definition: system.h:172
prefix
const char * prefix
Definition: rest.cpp:772
ArgsManager::ALLOW_INT
@ ALLOW_INT
Definition: system.h:157
ArgsManager::Arg::m_flags
unsigned int m_flags
Definition: system.h:175
GetDefaultDataDir
fs::path GetDefaultDataDir()
Definition: system.cpp:722
ArgsManager::cs_args
RecursiveMutex cs_args
Definition: system.h:178
AbsPathForConfigVal
fs::path AbsPathForConfigVal(const fs::path &path, bool net_specific=true)
Most paths passed as configuration arguments are treated as relative to the datadir if they are not a...
Definition: system.cpp:1371
settings.h
TraceThread
void TraceThread(const char *name, Callable func)
Definition: system.h:446
ArgsManager::GetSettingsPath
bool GetSettingsPath(fs::path *filepath=nullptr, bool temp=false) const
Get settings file path, or return false if read-write settings were disabled with -nosettings.
Definition: system.cpp:423
CheckDiskSpace
bool CheckDiskSpace(const fs::path &dir, uint64_t additional_bytes=0)
Definition: system.cpp:140
GetConfigFile
fs::path GetConfigFile(const std::string &confPath)
Definition: system.cpp:831
OptionsCategory::HIDDEN
@ HIDDEN
OptionsCategory::NODE_RELAY
@ NODE_RELAY
ArgsManager::ClearForcedArg
void ClearForcedArg(const std::string &strArg)
Remove a forced arg setting, used only in testing.
Definition: system.cpp:593
ArgsManager::ALLOW_BOOL
@ ALLOW_BOOL
Definition: system.h:156
ArgsManager::SENSITIVE
@ SENSITIVE
Definition: system.h:168
RaiseFileDescriptorLimit
int RaiseFileDescriptorLimit(int nMinFD)
This function tries to raise the file descriptor limit to the requested number.
Definition: system.cpp:1188
ArgsManager::SoftSetArg
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: system.cpp:524
ArgsManager::DEBUG_ONLY
@ DEBUG_ONLY
Definition: system.h:160
compat.h
ArgsManager::AddArg
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: system.cpp:565
util::ThreadRename
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
HelpMessageOpt
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
Definition: system.cpp:690
ArgsManager::WriteSettingsFile
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr) const
Write settings file.
Definition: system.cpp:471
IsSwitchChar
bool IsSwitchChar(char c)
Definition: system.h:116
time.h
DirIsWritable
bool DirIsWritable(const fs::path &directory)
Definition: system.cpp:126
ArgsManager::GetUnsuitableSectionOnlyArgs
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:249
ArgsManager::ForceSetArg
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: system.cpp:542
ArgsManager::GetArg
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:498
OptionsCategory::OPTIONS
@ OPTIONS
ArgsManager::ArgsManager
ArgsManager()
Definition: system.cpp:246
ArgsManager::Arg::m_help_param
std::string m_help_param
Definition: system.h:173
ArgsManager::ParseParameters
NODISCARD bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: system.cpp:317
ArgsManager::GUARDED_BY
util::Settings m_settings GUARDED_BY(cs_args)
ArgsManager::ReadConfigFiles
NODISCARD bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:930
ScheduleBatchPriority
void ScheduleBatchPriority()
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
Definition: system.cpp:1378
CopyrightHolders
std::string CopyrightHolders(const std::string &strPrefix)
Definition: system.cpp:1361
ArgsManager::ReadConfigStream
NODISCARD bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false)
Definition: system.cpp:895
SectionInfo::m_name
std::string m_name
Definition: system.h:147
GetBlocksDir
const fs::path & GetBlocksDir()
Definition: system.cpp:753
OptionsCategory
OptionsCategory
Definition: system.h:124
assumptions.h
OptionsCategory::ZMQ
@ ZMQ
attributes.h
SetupHelpOptions
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: system.cpp:676
name
const char * name
Definition: rest.cpp:43
OptionsCategory::BLOCK_CREATION
@ BLOCK_CREATION
ArgsManager::ReadSettingsFile
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
Definition: system.cpp:446
ArgsManager::SelectConfigNetwork
void SelectConfigNetwork(const std::string &network)
Select the network in use.
Definition: system.cpp:288
ArgsManager::LockSettings
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: system.h:389
ArgsManager::GetSettingsList
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: system.cpp:1075
ArgsManager::IsArgNegated
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: system.cpp:494
SectionInfo
Definition: system.h:146
ArgsManager
Definition: system.h:152
OptionsCategory::WALLET_DEBUG_TEST
@ WALLET_DEBUG_TEST
EXCLUSIVE_LOCKS_REQUIRED
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56
LOCK
#define LOCK(cs)
Definition: sync.h:241
ArgsManager::ForceSetMultiArg
void ForceSetMultiArg(const std::string &strArg, const std::vector< std::string > &values)
This function is only used for testing purpose so so we should not worry about element uniqueness and...
Definition: system.cpp:553
GetStartupTime
int64_t GetStartupTime()
Server/client environment: argument handling, config file parsing, thread wrappers,...
Definition: system.cpp:1367
ArgsManager::logArgsPrefix
void logArgsPrefix(const std::string &prefix, const std::string &section, const std::map< std::string, std::vector< util::SettingsValue >> &args) const
Definition: system.cpp:1081
OptionsCategory::WALLET
@ WALLET
util::insert
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
Definition: system.h:477
logging.h
ArgsManager::GetUnrecognizedSections
const std::list< SectionInfo > GetUnrecognizedSections() const
Log warnings for unrecognized section names in the config file.
Definition: system.cpp:273
SetupNetworking
bool SetupNetworking()
Definition: system.cpp:1344
ArgsManager::ClearArgs
void ClearArgs()
Clear available arguments.
Definition: system.h:346
SectionInfo::m_line
int m_line
Definition: system.h:149
OptionsCategory::DEBUG_TEST
@ DEBUG_TEST
ParseKeyValue
NODISCARD bool ParseKeyValue(std::string &key, std::string &val)
Definition: system.cpp:293
OptionsCategory::COMMANDS
@ COMMANDS
ArgsManager::Arg::m_help_text
std::string m_help_text
Definition: system.h:174
OptionsCategory::REGISTER_COMMANDS
@ REGISTER_COMMANDS
ArgsManager::GetArgs
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: system.cpp:391
ReleaseDirectoryLocks
void ReleaseDirectoryLocks()
Release all directory locks.
Definition: system.cpp:121
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:48
ArgsManager::NETWORK_ONLY
@ NETWORK_ONLY
Definition: system.h:166
OptionsCategory::CHAINPARAMS
@ CHAINPARAMS
BITCOIN_CONF_FILENAME
const char *const BITCOIN_CONF_FILENAME
Definition: system.cpp:72
OptionsCategory::GUI
@ GUI
threadnames.h
TruncateFile
bool TruncateFile(FILE *file, unsigned int length)
Definition: system.cpp:1175
util
Definition: httprpc.h:13
LogPrintf
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:175
ShellEscape
std::string ShellEscape(const std::string &arg)
Definition: system.cpp:1279
GetNumCores
int GetNumCores()
Return the number of cores available on the current system.
Definition: system.cpp:1357
PrintExceptionContinue
void PrintExceptionContinue(const std::exception *pex, const char *pszThread)
Definition: system.cpp:716