Bitcoin Core  25.99.0
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/compat.h>
9 #include <sync.h>
10 #include <util/chaintype.h>
11 #include <util/fs.h>
12 #include <util/settings.h>
13 
14 #include <iosfwd>
15 #include <list>
16 #include <map>
17 #include <optional>
18 #include <set>
19 #include <stdint.h>
20 #include <string>
21 #include <variant>
22 #include <vector>
23 
24 class ArgsManager;
25 
26 extern const char * const BITCOIN_CONF_FILENAME;
27 extern const char * const BITCOIN_SETTINGS_FILENAME;
28 
29 // Return true if -datadir option points to a valid directory or is not specified.
31 
41 fs::path AbsPathForConfigVal(const ArgsManager& args, const fs::path& path, bool net_specific = true);
42 
43 inline bool IsSwitchChar(char c)
44 {
45 #ifdef WIN32
46  return c == '-' || c == '/';
47 #else
48  return c == '-';
49 #endif
50 }
51 
52 enum class OptionsCategory {
53  OPTIONS,
54  CONNECTION,
55  WALLET,
57  ZMQ,
58  DEBUG_TEST,
60  NODE_RELAY,
62  RPC,
63  GUI,
64  COMMANDS,
66 
67  HIDDEN // Always the last option to avoid printing these in the help
68 };
69 
70 struct KeyInfo {
71  std::string name;
72  std::string section;
73  bool negated{false};
74 };
75 
76 KeyInfo InterpretKey(std::string key);
77 
78 std::optional<util::SettingsValue> InterpretValue(const KeyInfo& key, const std::string* value,
79  unsigned int flags, std::string& error);
80 
81 struct SectionInfo {
82  std::string m_name;
83  std::string m_file;
84  int m_line;
85 };
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 
97 {
98 public:
103  enum Flags : uint32_t {
104  ALLOW_ANY = 0x01,
105  // ALLOW_BOOL = 0x02, //!< unimplemented, draft implementation in #16545
106  // ALLOW_INT = 0x04, //!< unimplemented, draft implementation in #16545
107  // ALLOW_STRING = 0x08, //!< unimplemented, draft implementation in #16545
108  // ALLOW_LIST = 0x10, //!< unimplemented, draft implementation in #16545
111 
112  DEBUG_ONLY = 0x100,
113  /* Some options would cause cross-contamination if values for
114  * mainnet were used while running on regtest/testnet (or vice-versa).
115  * Setting them as NETWORK_ONLY ensures that sharing a config file
116  * between mainnet and regtest/testnet won't cause problems due to these
117  * parameters by accident. */
118  NETWORK_ONLY = 0x200,
119  // This argument's value is sensitive (such as a password).
120  SENSITIVE = 0x400,
121  COMMAND = 0x800,
122  };
123 
124 protected:
125  struct Arg
126  {
127  std::string m_help_param;
128  std::string m_help_text;
129  unsigned int m_flags;
130  };
131 
134  std::vector<std::string> m_command GUARDED_BY(cs_args);
135  std::string m_network GUARDED_BY(cs_args);
136  std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
137  std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
138  bool m_accept_any_command GUARDED_BY(cs_args){true};
139  std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
140  std::optional<fs::path> m_config_path GUARDED_BY(cs_args);
141  mutable fs::path m_cached_blocks_path GUARDED_BY(cs_args);
142  mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args);
143  mutable fs::path m_cached_network_datadir_path GUARDED_BY(cs_args);
144 
145  [[nodiscard]] bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false);
146 
152  bool UseDefaultSection(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
153 
154  public:
162  util::SettingsValue GetSetting(const std::string& arg) const;
163 
167  std::vector<util::SettingsValue> GetSettingsList(const std::string& arg) const;
168 
171 
175  void SelectConfigNetwork(const std::string& network);
176 
177  [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error);
178 
182  fs::path GetConfigFilePath() const;
183  [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
184 
191  std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
192 
196  std::list<SectionInfo> GetUnrecognizedSections() const;
197 
198  struct Command {
200  std::string command;
205  std::vector<std::string> args;
206  };
210  std::optional<const Command> GetCommand() const;
211 
217  const fs::path& GetBlocksDirPath() const;
218 
224  const fs::path& GetDataDirBase() const { return GetDataDir(false); }
225 
231  const fs::path& GetDataDirNet() const { return GetDataDir(true); }
232 
236  void ClearPathCache();
237 
244  std::vector<std::string> GetArgs(const std::string& strArg) const;
245 
252  bool IsArgSet(const std::string& strArg) const;
253 
261  bool IsArgNegated(const std::string& strArg) const;
262 
270  std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
271  std::optional<std::string> GetArg(const std::string& strArg) const;
272 
283  fs::path GetPathArg(std::string arg, const fs::path& default_value = {}) const;
284 
292  int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const;
293  std::optional<int64_t> GetIntArg(const std::string& strArg) const;
294 
302  bool GetBoolArg(const std::string& strArg, bool fDefault) const;
303  std::optional<bool> GetBoolArg(const std::string& strArg) const;
304 
312  bool SoftSetArg(const std::string& strArg, const std::string& strValue);
313 
321  bool SoftSetBoolArg(const std::string& strArg, bool fValue);
322 
323  // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
324  // been set. Also called directly in testing.
325  void ForceSetArg(const std::string& strArg, const std::string& strValue);
326 
332  ChainType GetChainType() const;
333 
339  std::string GetChainTypeString() const;
340 
344  void AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat);
345 
349  void AddCommand(const std::string& cmd, const std::string& help);
350 
354  void AddHiddenArgs(const std::vector<std::string>& args);
355 
359  void ClearArgs() {
360  LOCK(cs_args);
361  m_available_args.clear();
362  m_network_only_args.clear();
363  }
364 
368  std::string GetHelpMessage() const;
369 
374  std::optional<unsigned int> GetArgFlags(const std::string& name) const;
375 
380  bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false, bool backup = false) const;
381 
385  bool ReadSettingsFile(std::vector<std::string>* errors = nullptr);
386 
391  bool WriteSettingsFile(std::vector<std::string>* errors = nullptr, bool backup = false) const;
392 
397  util::SettingsValue GetPersistentSetting(const std::string& name) const;
398 
402  template <typename Fn>
403  void LockSettings(Fn&& fn)
404  {
405  LOCK(cs_args);
406  fn(m_settings);
407  }
408 
413  void LogArgs() const;
414 
415 private:
422  const fs::path& GetDataDir(bool net_specific) const;
423 
430  std::variant<ChainType, std::string> GetChainArg() const;
431 
432  // Helper function for LogArgs().
433  void logArgsPrefix(
434  const std::string& prefix,
435  const std::string& section,
436  const std::map<std::string, std::vector<util::SettingsValue>>& args) const;
437 };
438 
439 extern ArgsManager gArgs;
440 
444 bool HelpRequested(const ArgsManager& args);
445 
448 
455 std::string HelpMessageGroup(const std::string& message);
456 
464 std::string HelpMessageOpt(const std::string& option, const std::string& message);
465 
466 namespace common {
467 #ifdef WIN32
468 class WinCmdLineArgs
469 {
470 public:
471  WinCmdLineArgs();
472  ~WinCmdLineArgs();
473  std::pair<int, char**> get();
474 
475 private:
476  int argc;
477  char** argv;
478  std::vector<std::string> args;
479 };
480 #endif
481 } // namespace common
482 
483 #endif // BITCOIN_COMMON_ARGS_H
bool HelpRequested(const ArgsManager &args)
Definition: args.cpp:660
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: args.cpp:665
OptionsCategory
Definition: args.h:52
const char *const BITCOIN_SETTINGS_FILENAME
Definition: args.cpp:40
bool SettingToBool(const util::SettingsValue &, bool)
Definition: args.cpp:524
bool CheckDataDirOption(const ArgsManager &args)
Definition: args.cpp:711
int64_t SettingToInt(const util::SettingsValue &, int64_t)
Definition: args.cpp:501
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: config.cpp:211
ArgsManager gArgs
Definition: args.cpp:42
std::optional< util::SettingsValue > InterpretValue(const KeyInfo &key, const std::string *value, unsigned int flags, std::string &error)
Interpret settings value based on registered flags.
Definition: args.cpp:107
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: args.cpp:675
KeyInfo InterpretKey(std::string key)
Parse "name", "section.name", "noname", "section.noname" settings keys.
Definition: args.cpp:79
const char *const BITCOIN_CONF_FILENAME
Definition: args.cpp:39
bool IsSwitchChar(char c)
Definition: args.h:43
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:679
std::string SettingToString(const util::SettingsValue &, const std::string &)
Definition: args.cpp:476
int flags
Definition: bitcoin-tx.cpp:528
const auto cmd
ChainType
Definition: chaintype.h:11
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:136
std::optional< const Command > GetCommand() const
Get the command and command args (returns std::nullopt if no command provided)
Definition: args.cpp:341
const fs::path & GetBlocksDirPath() const
Get blocks directory path.
Definition: args.cpp:281
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: args.cpp:451
std::list< SectionInfo > GetUnrecognizedSections() const
Log warnings for unrecognized section names in the config file.
Definition: args.cpp:156
Flags
Flags controlling how config and command line arguments are validated and interpreted.
Definition: args.h:103
@ NETWORK_ONLY
Definition: args.h:118
@ ALLOW_ANY
disable validation
Definition: args.h:104
@ DISALLOW_NEGATION
disallow -nofoo syntax
Definition: args.h:109
@ DISALLOW_ELISION
disallow -foo syntax that doesn't assign any value
Definition: args.h:110
@ DEBUG_ONLY
Definition: args.h:112
@ COMMAND
Definition: args.h:121
@ SENSITIVE
Definition: args.h:120
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
Definition: args.cpp:401
ChainType GetChainType() const
Returns the appropriate chain type from the program arguments.
Definition: args.cpp:723
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: args.cpp:545
void logArgsPrefix(const std::string &prefix, const std::string &section, const std::map< std::string, std::vector< util::SettingsValue >> &args) const
Definition: args.cpp:786
fs::path m_cached_datadir_path GUARDED_BY(cs_args)
std::string GetChainTypeString() const
Returns the appropriate chain type string from the program arguments.
Definition: args.cpp:730
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: args.cpp:178
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: args.cpp:361
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:444
std::optional< unsigned int > GetArgFlags(const std::string &name) const
Return Flags for known arg.
Definition: args.cpp:259
const fs::path & GetDataDirBase() const
Get data directory path.
Definition: args.h:224
std::string m_network GUARDED_BY(cs_args)
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:375
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: args.h:403
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn't already have a value.
Definition: args.cpp:529
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:591
void ClearPathCache()
Clear cached directory paths.
Definition: args.cpp:332
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:370
const fs::path & GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: args.h:231
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr, bool backup=false) const
Write settings file or backup settings file.
Definition: args.cpp:424
std::optional< fs::path > m_config_path GUARDED_BY(cs_args)
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: args.cpp:481
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:306
std::vector< std::string > m_command GUARDED_BY(cs_args)
void ClearArgs()
Clear available arguments.
Definition: args.h:359
fs::path GetConfigFilePath() const
Return config file path (read-only)
Definition: args.cpp:717
util::Settings m_settings GUARDED_BY(cs_args)
void AddCommand(const std::string &cmd, const std::string &help)
Add subcommand.
Definition: args.cpp:551
std::vector< util::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: args.cpp:780
std::variant< ChainType, std::string > GetChainArg() const
Return -regtest/-signet/-testnet/-chain= setting as a ChainType enum if a recognized chain type was s...
Definition: args.cpp:737
bool m_accept_any_command GUARDED_BY(cs_args)
Definition: args.h:138
void LogArgs() const
Log the config file options and the command line arguments, useful for troubleshooting.
Definition: args.cpp:803
RecursiveMutex cs_args
Definition: args.h:132
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:767
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: args.cpp:456
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:772
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false)
Definition: config.cpp:89
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: args.cpp:537
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: config.cpp:118
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: args.cpp:506
void AddHiddenArgs(const std::vector< std::string > &args)
Add many hidden arguments.
Definition: args.cpp:584
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: args.cpp:563
fs::path GetPathArg(std::string arg, const fs::path &default_value={}) const
Return path argument or default value.
Definition: args.cpp:271
std::list< SectionInfo > m_config_sections GUARDED_BY(cs_args)
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:31
bool error(const char *fmt, const Args &... args)
Definition: logging.h:261
Definition: args.cpp:815
CRPCCommand m_command
Definition: interfaces.cpp:500
ArgsManager args
const char * prefix
Definition: rest.cpp:1004
const char * name
Definition: rest.cpp:45
static RPCHelpMan help()
Definition: server.cpp:137
std::string m_help_param
Definition: args.h:127
unsigned int m_flags
Definition: args.h:129
std::string m_help_text
Definition: args.h:128
std::vector< std::string > args
If command is non-empty: Any args that followed it If command is empty: The unregistered command and ...
Definition: args.h:205
std::string command
The command (if one has been registered with AddCommand), or empty.
Definition: args.h:200
Definition: args.h:70
std::string name
Definition: args.h:71
bool negated
Definition: args.h:73
std::string section
Definition: args.h:72
int m_line
Definition: args.h:84
std::string m_file
Definition: args.h:83
std::string m_name
Definition: args.h:82
Stored settings.
Definition: settings.h:31
#define LOCK(cs)
Definition: sync.h:258
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49