Bitcoin ABC  0.26.3
P2P Digital Currency
args.h
Go to the documentation of this file.
1 // Copyright (c) 2023 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_COMMON_ARGS_H
6 #define BITCOIN_COMMON_ARGS_H
7 
8 #include <compat.h>
9 #include <sync.h>
10 #include <util/fs.h>
11 #include <util/settings.h>
12 
13 #include <cstdint>
14 #include <iosfwd>
15 #include <list>
16 #include <map>
17 #include <optional>
18 #include <set>
19 #include <string>
20 #include <vector>
21 
22 class ArgsManager;
23 
24 extern const char *const BITCOIN_CONF_FILENAME;
25 extern const char *const BITCOIN_SETTINGS_FILENAME;
26 
27 // Return true if -datadir option points to a valid directory or is not
28 // specified.
29 bool CheckDataDirOption(const ArgsManager &args);
31  const fs::path &configuration_file_path);
32 
33 [[nodiscard]] bool ParseKeyValue(std::string &key, std::string &val);
34 
44 fs::path AbsPathForConfigVal(const ArgsManager &args, const fs::path &path,
45  bool net_specific = true);
46 
47 inline bool IsSwitchChar(char c) {
48 #ifdef WIN32
49  return c == '-' || c == '/';
50 #else
51  return c == '-';
52 #endif
53 }
54 
55 enum class OptionsCategory {
56  OPTIONS,
57  CONNECTION,
58  WALLET,
60  ZMQ,
61  DEBUG_TEST,
63  NODE_RELAY,
65  RPC,
66  GUI,
67  COMMANDS,
69  AVALANCHE,
70  CHRONIK,
71 
72  // Always the last option to avoid printing these in the help
73  HIDDEN,
74 };
75 
76 struct SectionInfo {
77  std::string m_name;
78  std::string m_file;
79  int m_line;
80 };
81 
82 bool CheckValid(const std::string &key, const util::SettingsValue &val,
83  unsigned int flags, std::string &error);
84 util::SettingsValue InterpretOption(std::string &section, std::string &key,
85  const std::string &value);
86 
87 std::string SettingToString(const util::SettingsValue &, const std::string &);
88 std::optional<std::string> SettingToString(const util::SettingsValue &);
89 
90 int64_t SettingToInt(const util::SettingsValue &, int64_t);
91 std::optional<int64_t> SettingToInt(const util::SettingsValue &);
92 
93 bool SettingToBool(const util::SettingsValue &, bool);
94 std::optional<bool> SettingToBool(const util::SettingsValue &);
95 
96 class ArgsManager {
97 public:
98  enum Flags {
99  // Boolean options can accept negation syntax -noOPTION or -noOPTION=1
100  ALLOW_BOOL = 0x01,
101  ALLOW_INT = 0x02,
102  ALLOW_STRING = 0x04,
104  DEBUG_ONLY = 0x100,
105  /* Some options would cause cross-contamination if values for
106  * mainnet were used while running on regtest/testnet (or vice-versa).
107  * Setting them as NETWORK_ONLY ensures that sharing a config file
108  * between mainnet and regtest/testnet won't cause problems due to these
109  * parameters by accident. */
110  NETWORK_ONLY = 0x200,
111  // This argument's value is sensitive (such as a password).
112  SENSITIVE = 0x400,
113  };
114 
115 protected:
116  struct Arg {
117  std::string m_help_param;
118  std::string m_help_text;
119  unsigned int m_flags;
120  };
121 
124  std::string m_network GUARDED_BY(cs_args);
125  std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
126  std::map<OptionsCategory, std::map<std::string, Arg>>
127  m_available_args GUARDED_BY(cs_args);
128  std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
129  mutable fs::path m_cached_blocks_path GUARDED_BY(cs_args);
130  mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args);
131  mutable fs::path m_cached_network_datadir_path GUARDED_BY(cs_args);
132 
133  [[nodiscard]] bool ReadConfigStream(std::istream &stream,
134  const std::string &filepath,
135  std::string &error,
136  bool ignore_invalid_keys = false);
137 
143  bool UseDefaultSection(const std::string &arg) const
145 
146 public:
154  util::SettingsValue GetSetting(const std::string &arg) const;
155 
159  std::vector<util::SettingsValue>
160  GetSettingsList(const std::string &arg) const;
161 
162  ArgsManager();
163  ~ArgsManager();
164 
168  void SelectConfigNetwork(const std::string &network);
169 
170  [[nodiscard]] bool ParseParameters(int argc, const char *const argv[],
171  std::string &error);
175  fs::path GetConfigFilePath() const;
176 
177  [[nodiscard]] bool ReadConfigFiles(std::string &error,
178  bool ignore_invalid_keys = false);
179 
185  const std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
186 
190  const std::list<SectionInfo> GetUnrecognizedSections() const;
191 
197  const fs::path &GetBlocksDirPath() const;
198 
206  const fs::path &GetDataDirBase() const { return GetDataDir(false); }
207 
215  const fs::path &GetDataDirNet() const { return GetDataDir(true); }
216 
220  void ClearPathCache();
221 
228  std::vector<std::string> GetArgs(const std::string &strArg) const;
229 
236  bool IsArgSet(const std::string &strArg) const;
237 
245  bool IsArgNegated(const std::string &strArg) const;
246 
254  std::string GetArg(const std::string &strArg,
255  const std::string &strDefault) const;
256  std::optional<std::string> GetArg(const std::string &strArg) const;
257 
270  fs::path GetPathArg(std::string arg,
271  const fs::path &default_value = {}) const;
272 
280  int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const;
281  std::optional<int64_t> GetIntArg(const std::string &strArg) const;
282 
290  bool GetBoolArg(const std::string &strArg, bool fDefault) const;
291  std::optional<bool> GetBoolArg(const std::string &strArg) 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,
375  bool backup = false) const;
376 
380  bool ReadSettingsFile(std::vector<std::string> *errors = nullptr);
381 
386  bool WriteSettingsFile(std::vector<std::string> *errors = nullptr,
387  bool backup = false) const;
388 
393  util::SettingsValue GetPersistentSetting(const std::string &name) const;
394 
398  template <typename Fn> void LockSettings(Fn &&fn) {
399  LOCK(cs_args);
400  fn(m_settings);
401  }
402 
407  void LogArgs() const;
408 
413  void EnsureDataDir() const;
414 
415 private:
423  const fs::path &GetDataDir(bool net_specific) const;
424 
425  // Helper function for LogArgs().
426  void
427  logArgsPrefix(const std::string &prefix, const std::string &section,
428  const std::map<std::string, std::vector<util::SettingsValue>>
429  &args) const;
430 };
431 
432 extern ArgsManager gArgs;
433 
437 bool HelpRequested(const ArgsManager &args);
438 
440 void SetupHelpOptions(ArgsManager &args);
441 
448 std::string HelpMessageGroup(const std::string &message);
449 
457 std::string HelpMessageOpt(const std::string &option,
458  const std::string &message);
459 
460 namespace common {
461 #ifdef WIN32
462 class WinCmdLineArgs {
463 public:
464  WinCmdLineArgs();
465  ~WinCmdLineArgs();
466  std::pair<int, char **> get();
467 
468 private:
469  int argc;
470  char **argv;
471  std::vector<std::string> args;
472 };
473 #endif
474 } // namespace common
475 
476 #endif // BITCOIN_COMMON_ARGS_H
bool HelpRequested(const ArgsManager &args)
Definition: args.cpp:732
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: args.cpp:737
bool CheckValid(const std::string &key, const util::SettingsValue &val, unsigned int flags, std::string &error)
Check settings value validity according to flags.
Definition: args.cpp:117
OptionsCategory
Definition: args.h:55
const char *const BITCOIN_SETTINGS_FILENAME
Definition: args.cpp:36
bool ParseKeyValue(std::string &key, std::string &val)
Definition: args.cpp:177
bool SettingToBool(const util::SettingsValue &, bool)
Definition: args.cpp:575
bool CheckDataDirOption(const ArgsManager &args)
Definition: args.cpp:784
int64_t SettingToInt(const util::SettingsValue &, int64_t)
Definition: args.cpp:552
fs::path AbsPathForConfigVal(const ArgsManager &args, 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: configfile.cpp:234
ArgsManager gArgs
Definition: args.cpp:38
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: args.cpp:747
const char *const BITCOIN_CONF_FILENAME
Definition: args.cpp:35
bool IsSwitchChar(char c)
Definition: args.h:47
util::SettingsValue InterpretOption(std::string &section, std::string &key, const std::string &value)
Interpret -nofoo as if the user supplied -foo=0.
Definition: args.cpp:87
fs::path GetConfigFile(const ArgsManager &args, const fs::path &configuration_file_path)
Definition: configfile.cpp:29
std::string HelpMessageOpt(const std::string &option, const std::string &message)
Format a string to be used as option description in help messages.
Definition: args.cpp:751
std::string SettingToString(const util::SettingsValue &, const std::string &)
Definition: args.cpp:521
int flags
Definition: bitcoin-tx.cpp:543
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: args.cpp:133
const fs::path & GetBlocksDirPath() const
Get blocks directory path.
Definition: args.cpp:289
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: args.cpp:490
@ NETWORK_ONLY
Definition: args.h:110
@ ALLOW_ANY
Definition: args.h:103
@ DEBUG_ONLY
Definition: args.h:104
@ ALLOW_INT
Definition: args.h:101
@ ALLOW_BOOL
Definition: args.h:100
@ ALLOW_STRING
Definition: args.h:102
@ SENSITIVE
Definition: args.h:112
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
Definition: args.cpp:432
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: args.cpp:597
void logArgsPrefix(const std::string &prefix, const std::string &section, const std::map< std::string, std::vector< util::SettingsValue >> &args) const
Definition: args.cpp:843
bool InitSettings(std::string &error)
Read and update settings file with saved settings.
Definition: args.cpp:385
fs::path m_cached_datadir_path GUARDED_BY(cs_args)
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: args.cpp:201
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: args.cpp:371
util::SettingsValue GetPersistentSetting(const std::string &name) const
Get current setting from config file or read/write settings file, ignoring nonpersistent command line...
Definition: args.cpp:483
ArgsManager()
Definition: args.cpp:130
std::optional< unsigned int > GetArgFlags(const std::string &name) const
Return Flags for known arg.
Definition: args.cpp:264
const fs::path & GetDataDirBase() const
Get data directory path.
Definition: args.h:206
std::string m_network GUARDED_BY(cs_args)
~ArgsManager()
Definition: args.cpp:131
void EnsureDataDir() const
If datadir does not exist, create it along with wallets/ subdirectory(s).
Definition: args.cpp:343
bool GetSettingsPath(fs::path *filepath=nullptr, bool temp=false, bool backup=false) const
Get settings file path, or return false if read-write settings were disabled with -nosettings.
Definition: args.cpp:405
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: args.h:398
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: args.cpp:579
void SelectConfigNetwork(const std::string &network)
Select the network in use.
Definition: args.cpp:172
std::string GetHelpMessage() const
Get the help string.
Definition: args.cpp:653
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: args.cpp:608
void ClearPathCache()
Clear cached directory paths.
Definition: args.cpp:363
fs::path m_cached_blocks_path GUARDED_BY(cs_args)
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: args.cpp:381
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: args.h:215
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr, bool backup=false) const
Write settings file or backup settings file.
Definition: args.cpp:457
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: args.cpp:526
std::map< OptionsCategory, std::map< std::string, Arg > > m_available_args GUARDED_BY(cs_args)
const fs::path & GetDataDir(bool net_specific) const
Get data directory path.
Definition: args.cpp:315
void ClearArgs()
Clear available arguments.
Definition: args.h:346
fs::path GetConfigFilePath() const
Return config file path (read-only)
Definition: args.cpp:789
util::Settings m_settings GUARDED_BY(cs_args)
void ClearForcedArg(const std::string &strArg)
Remove a forced arg setting, used only in testing.
Definition: args.cpp:648
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: args.cpp:837
void LogArgs() const
Log the config file options and the command line arguments, useful for troubleshooting.
Definition: args.cpp:860
RecursiveMutex cs_args
Definition: args.h:122
fs::path m_cached_network_datadir_path GUARDED_BY(cs_args)
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: args.cpp:823
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: args.cpp:494
std::set< std::string > m_network_only_args GUARDED_BY(cs_args)
util::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
Definition: args.cpp:828
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false)
Definition: configfile.cpp:95
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: args.cpp:589
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: configfile.cpp:130
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: args.cpp:556
void AddHiddenArgs(const std::vector< std::string > &args)
Add many hidden arguments.
Definition: args.cpp:642
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: args.cpp:620
fs::path GetPathArg(std::string arg, const fs::path &default_value={}) const
Return path argument or default value.
Definition: args.cpp:275
std::list< SectionInfo > m_config_sections GUARDED_BY(cs_args)
const std::list< SectionInfo > GetUnrecognizedSections() const
Log warnings for unrecognized section names in the config file.
Definition: args.cpp:157
std::string GetChainName() const
Looks for -regtest, -testnet and returns the appropriate BIP70 chain name.
Definition: args.cpp:793
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:30
bool error(const char *fmt, const Args &...args)
Definition: logging.h:226
Definition: args.cpp:872
const char * prefix
Definition: rest.cpp:817
const char * name
Definition: rest.cpp:47
static RPCHelpMan help()
Definition: server.cpp:182
std::string m_help_param
Definition: args.h:117
unsigned int m_flags
Definition: args.h:119
std::string m_help_text
Definition: args.h:118
int m_line
Definition: args.h:79
std::string m_file
Definition: args.h:78
std::string m_name
Definition: args.h:77
Stored settings.
Definition: settings.h:31
#define LOCK(cs)
Definition: sync.h:306
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56