Bitcoin Core  31.0.0
P2P Digital Currency
args.h
Go to the documentation of this file.
1 // Copyright (c) 2023-present 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 <common/settings.h>
9 #include <compat/compat.h>
10 #include <sync.h>
11 #include <util/chaintype.h>
12 #include <util/fs.h>
13 
14 #include <concepts>
15 #include <cstdint>
16 #include <iosfwd>
17 #include <list>
18 #include <map>
19 #include <optional>
20 #include <set>
21 #include <string>
22 #include <variant>
23 #include <vector>
24 
25 class ArgsManager;
26 
27 extern const char * const BITCOIN_CONF_FILENAME;
28 extern const char * const BITCOIN_SETTINGS_FILENAME;
29 
30 // Return true if -datadir option points to a valid directory or is not specified.
32 
42 fs::path AbsPathForConfigVal(const ArgsManager& args, const fs::path& path, bool net_specific = true);
43 
44 inline bool IsSwitchChar(char c)
45 {
46 #ifdef WIN32
47  return c == '-' || c == '/';
48 #else
49  return c == '-';
50 #endif
51 }
52 
53 enum class OptionsCategory {
54  OPTIONS,
55  CONNECTION,
56  WALLET,
58  ZMQ,
59  DEBUG_TEST,
61  NODE_RELAY,
63  RPC,
64  GUI,
65  COMMANDS,
68  IPC,
69 
70  HIDDEN // Always the last option to avoid printing these in the help
71 };
72 
73 struct KeyInfo {
74  std::string name;
75  std::string section;
76  bool negated{false};
77 };
78 
79 KeyInfo InterpretKey(std::string key);
80 
81 std::optional<common::SettingsValue> InterpretValue(const KeyInfo& key, const std::string* value,
82  unsigned int flags, std::string& error);
83 
84 struct SectionInfo {
85  std::string m_name;
86  std::string m_file;
87  int m_line;
88 };
89 
90 std::string SettingToString(const common::SettingsValue&, const std::string&);
91 std::optional<std::string> SettingToString(const common::SettingsValue&);
92 
93 template <std::integral Int>
94 Int SettingTo(const common::SettingsValue&, Int);
95 
96 template <std::integral Int>
97 std::optional<Int> SettingTo(const common::SettingsValue&);
98 
99 bool SettingToBool(const common::SettingsValue&, bool);
100 std::optional<bool> SettingToBool(const common::SettingsValue&);
101 
103 {
104 public:
109  enum Flags : uint32_t {
110  ALLOW_ANY = 0x01,
111  // ALLOW_BOOL = 0x02, //!< unimplemented, draft implementation in #16545
112  // ALLOW_INT = 0x04, //!< unimplemented, draft implementation in #16545
113  // ALLOW_STRING = 0x08, //!< unimplemented, draft implementation in #16545
114  // ALLOW_LIST = 0x10, //!< unimplemented, draft implementation in #16545
117 
118  DEBUG_ONLY = 0x100,
119  /* Some options would cause cross-contamination if values for
120  * mainnet were used while running on regtest/testnet (or vice-versa).
121  * Setting them as NETWORK_ONLY ensures that sharing a config file
122  * between mainnet and regtest/testnet won't cause problems due to these
123  * parameters by accident. */
124  NETWORK_ONLY = 0x200,
125  // This argument's value is sensitive (such as a password).
126  SENSITIVE = 0x400,
127  COMMAND = 0x800,
128  };
129 
130 protected:
131  struct Arg
132  {
133  std::string m_help_param;
134  std::string m_help_text;
135  unsigned int m_flags;
136  };
137 
139  common::Settings m_settings GUARDED_BY(cs_args);
140  std::vector<std::string> m_command GUARDED_BY(cs_args);
141  std::string m_network GUARDED_BY(cs_args);
142  std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
143  std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
144  std::optional<unsigned int> m_default_flags GUARDED_BY(cs_args){};
145  bool m_accept_any_command GUARDED_BY(cs_args){true};
146  std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
147  std::optional<fs::path> m_config_path GUARDED_BY(cs_args);
148  mutable fs::path m_cached_blocks_path GUARDED_BY(cs_args);
149  mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args);
150  mutable fs::path m_cached_network_datadir_path GUARDED_BY(cs_args);
151 
152  [[nodiscard]] bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false);
153 
159  bool UseDefaultSection(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
160 
161  public:
169  common::SettingsValue GetSetting(const std::string& arg) const;
170 
174  std::vector<common::SettingsValue> GetSettingsList(const std::string& arg) const;
175 
176  ArgsManager();
177  ~ArgsManager();
178 
182  void SelectConfigNetwork(const std::string& network);
183 
184  [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error);
185 
189  fs::path GetConfigFilePath() const;
191  [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false);
192 
199  std::set<std::string> GetUnsuitableSectionOnlyArgs() const;
200 
204  std::list<SectionInfo> GetUnrecognizedSections() const;
205 
206  struct Command {
208  std::string command;
213  std::vector<std::string> args;
214  };
218  std::optional<const Command> GetCommand() const;
219 
225  fs::path GetBlocksDirPath() const;
226 
232  fs::path GetDataDirBase() const { return GetDataDir(false); }
233 
239  fs::path GetDataDirNet() const { return GetDataDir(true); }
240 
244  void ClearPathCache();
245 
252  std::vector<std::string> GetArgs(const std::string& strArg) const;
253 
260  bool IsArgSet(const std::string& strArg) const;
261 
269  bool IsArgNegated(const std::string& strArg) const;
270 
278  std::string GetArg(const std::string& strArg, const std::string& strDefault) const;
279  std::optional<std::string> GetArg(const std::string& strArg) const;
280 
291  fs::path GetPathArg(std::string arg, const fs::path& default_value = {}) const;
292 
300  template <std::integral Int>
301  Int GetArg(const std::string& strArg, Int nDefault) const;
302 
303  template <std::integral Int>
304  std::optional<Int> GetArg(const std::string& strArg) const;
305 
306  int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const { return GetArg<int64_t>(strArg, nDefault); }
307  std::optional<int64_t> GetIntArg(const std::string& strArg) const { return GetArg<int64_t>(strArg); }
308 
316  bool GetBoolArg(const std::string& strArg, bool fDefault) const;
317  std::optional<bool> GetBoolArg(const std::string& strArg) const;
318 
326  bool SoftSetArg(const std::string& strArg, const std::string& strValue);
327 
335  bool SoftSetBoolArg(const std::string& strArg, bool fValue);
336 
337  // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
338  // been set. Also called directly in testing.
339  void ForceSetArg(const std::string& strArg, const std::string& strValue);
340 
346  ChainType GetChainType() const;
347 
353  std::string GetChainTypeString() const;
354 
358  void AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat);
359 
363  void AddCommand(const std::string& cmd, const std::string& help);
364 
368  void AddHiddenArgs(const std::vector<std::string>& args);
369 
373  void ClearArgs();
374 
380  void CheckMultipleCLIArgs() const;
381 
385  std::string GetHelpMessage() const;
386 
391  std::optional<unsigned int> GetArgFlags(const std::string& name) const;
392 
396  void SetDefaultFlags(std::optional<unsigned int>);
397 
402  bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false, bool backup = false) const;
403 
407  bool ReadSettingsFile(std::vector<std::string>* errors = nullptr);
408 
413  bool WriteSettingsFile(std::vector<std::string>* errors = nullptr, bool backup = false) const;
414 
419  common::SettingsValue GetPersistentSetting(const std::string& name) const;
420 
424  template <typename Fn>
425  void LockSettings(Fn&& fn)
426  {
427  LOCK(cs_args);
428  fn(m_settings);
429  }
430 
435  void LogArgs() const;
436 
437 private:
444  fs::path GetDataDir(bool net_specific) const;
445 
452  std::variant<ChainType, std::string> GetChainArg() const;
453 
454  // Helper function for LogArgs().
455  void logArgsPrefix(
456  const std::string& prefix,
457  const std::string& section,
458  const std::map<std::string, std::vector<common::SettingsValue>>& args) const;
459 };
460 
461 extern ArgsManager gArgs;
462 
466 bool HelpRequested(const ArgsManager& args);
467 
470 
471 extern const std::vector<std::string> TEST_OPTIONS_DOC;
472 
474 bool HasTestOption(const ArgsManager& args, const std::string& test_option);
475 
482 std::string HelpMessageGroup(const std::string& message);
483 
491 std::string HelpMessageOpt(const std::string& option, const std::string& message);
492 
493 #endif // BITCOIN_COMMON_ARGS_H
bool ReadConfigFiles(std::string &error, bool ignore_invalid_keys=false)
Definition: config.cpp:122
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:226
std::string section
Definition: args.h:75
fs::path GetPathArg(std::string arg, const fs::path &default_value={}) const
Return path argument or default value.
Definition: args.cpp:276
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: args.cpp:375
OptionsCategory
Definition: args.h:53
fs::path GetConfigFilePath() const
Return config file path (read-only)
Definition: args.cpp:795
std::string SettingToString(const common::SettingsValue &, const std::string &)
Definition: args.cpp:481
std::variant< ChainType, std::string > GetChainArg() const
Return -regtest/-signet/-testnet/-testnet4/-chain= setting as a ChainType enum if a recognized chain ...
Definition: args.cpp:822
Stored settings.
Definition: settings.h:32
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn&#39;t already have a value.
Definition: args.cpp:563
unsigned int m_flags
Definition: args.h:135
common::SettingsValue GetSetting(const std::string &arg) const
Get setting value.
Definition: args.cpp:859
const std::vector< std::string > TEST_OPTIONS_DOC
Definition: args.cpp:743
const char * prefix
Definition: rest.cpp:1141
void AddHiddenArgs(const std::vector< std::string > &args)
Add many hidden arguments.
Definition: args.cpp:610
int m_line
Definition: args.h:87
disallow -nofoo syntax
Definition: args.h:115
bool HelpRequested(const ArgsManager &args)
Definition: args.cpp:717
void SetDefaultFlags(std::optional< unsigned int >)
Set default flags to return for an unknown arg.
Definition: args.cpp:270
void SelectConfigNetwork(const std::string &network)
Select the network in use.
Definition: args.cpp:171
bool negated
Definition: args.h:76
const auto cmd
bool ReadConfigStream(std::istream &stream, const std::string &filepath, std::string &error, bool ignore_invalid_keys=false)
Definition: config.cpp:93
common::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:449
Flags
Flags controlling how config and command line arguments are validated and interpreted.
Definition: args.h:109
bool ParseParameters(int argc, const char *const argv[], std::string &error)
Definition: args.cpp:177
RecursiveMutex cs_args
Definition: args.h:138
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: args.cpp:515
void ForceSetArg(const std::string &strArg, const std::string &strValue)
Definition: args.cpp:571
ChainType GetChainType() const
Returns the appropriate chain type from the program arguments.
Definition: args.cpp:808
bool SoftSetArg(const std::string &strArg, const std::string &strValue)
Set an argument if it doesn&#39;t already have a value.
Definition: args.cpp:555
void SetConfigFilePath(fs::path)
Definition: args.cpp:801
std::string m_name
Definition: args.h:85
disable validation
Definition: args.h:110
Definition: args.h:73
std::string GetHelpMessage() const
Get the help string.
Definition: args.cpp:642
fs::path GetDataDir(bool net_specific) const
Get data directory path.
Definition: args.cpp:311
fs::path GetDataDirBase() const
Get data directory path.
Definition: args.h:232
CRPCCommand m_command
Definition: interfaces.cpp:541
common::Settings m_settings GUARDED_BY(cs_args)
disallow -foo syntax that doesn&#39;t assign any value
Definition: args.h:116
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:380
bool ReadSettingsFile(std::vector< std::string > *errors=nullptr)
Read settings file.
Definition: args.cpp:406
std::string GetChainTypeString() const
Returns the appropriate chain type string from the program arguments.
Definition: args.cpp:815
KeyInfo InterpretKey(std::string key)
Parse "name", "section.name", "noname", "section.noname" settings keys.
Definition: args.cpp:77
void AddCommand(const std::string &cmd, const std::string &help)
Add subcommand.
Definition: args.cpp:577
bool IsArgNegated(const std::string &strArg) const
Return true if the argument was originally passed as a negated option, i.e.
Definition: args.cpp:456
ChainType
Definition: chaintype.h:11
fs::path GetDataDirNet() const
Get data directory path with appended network identifier.
Definition: args.h:239
ArgsManager & args
Definition: bitcoind.cpp:277
std::vector< common::SettingsValue > GetSettingsList(const std::string &arg) const
Get list of setting values.
Definition: args.cpp:867
#define LOCK(cs)
Definition: sync.h:258
const char * name
Definition: rest.cpp:48
Int SettingTo(const common::SettingsValue &, Int)
Definition: args.cpp:510
fs::path GetBlocksDirPath() const
Get blocks directory path.
Definition: args.cpp:286
std::optional< int64_t > GetIntArg(const std::string &strArg) const
Definition: args.h:307
void AddArg(const std::string &name, const std::string &help, unsigned int flags, const OptionsCategory &cat)
Add argument.
Definition: args.cpp:589
bool SettingToBool(const common::SettingsValue &, bool)
Definition: args.cpp:533
std::list< SectionInfo > GetUnrecognizedSections() const
Log warnings for unrecognized section names in the config file.
Definition: args.cpp:154
std::string m_file
Definition: args.h:86
std::string HelpMessageGroup(const std::string &message)
Format a string to be used as group of options in help messages.
Definition: args.cpp:732
void CheckMultipleCLIArgs() const
Check CLI command args.
Definition: args.cpp:625
void SetupHelpOptions(ArgsManager &args)
Add help options to the args manager.
Definition: args.cpp:722
void ClearArgs()
Clear available arguments.
Definition: args.cpp:617
std::string m_help_text
Definition: args.h:134
std::optional< const Command > GetCommand() const
Get the command and command args (returns std::nullopt if no command provided)
Definition: args.cpp:346
int flags
Definition: bitcoin-tx.cpp:529
std::optional< unsigned int > GetArgFlags(const std::string &name) const
Return Flags for known arg.
Definition: args.cpp:258
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:51
bool WriteSettingsFile(std::vector< std::string > *errors=nullptr, bool backup=false) const
Write settings file or backup settings file.
Definition: args.cpp:429
const char *const BITCOIN_CONF_FILENAME
Definition: args.cpp:37
bool HasTestOption(const ArgsManager &args, const std::string &test_option)
Checks if a particular test option is present in -test command-line arg options.
Definition: args.cpp:749
std::string name
Definition: args.h:74
bool m_accept_any_command GUARDED_BY(cs_args)
Definition: args.h:145
std::string command
The command (if one has been registered with AddCommand), or empty.
Definition: args.h:208
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Definition: args.h:306
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: args.cpp:461
ArgsManager gArgs
Definition: args.cpp:40
void LogArgs() const
Log the config file options and the command line arguments, useful for troubleshooting.
Definition: args.cpp:890
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:736
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:213
const char *const BITCOIN_SETTINGS_FILENAME
Definition: args.cpp:38
void logArgsPrefix(const std::string &prefix, const std::string &section, const std::map< std::string, std::vector< common::SettingsValue >> &args) const
Definition: args.cpp:873
void LockSettings(Fn &&fn)
Access settings with lock held.
Definition: args.h:425
std::string m_help_param
Definition: args.h:133
std::vector< std::string > GetArgs(const std::string &strArg) const
Return a vector of strings of the given argument.
Definition: args.cpp:366
void ClearPathCache()
Clear cached directory paths.
Definition: args.cpp:337
std::optional< unsigned int > m_default_flags GUARDED_BY(cs_args)
Definition: args.h:144
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:33
static RPCHelpMan help()
Definition: server.cpp:119
bool CheckDataDirOption(const ArgsManager &args)
Definition: args.cpp:789
bool IsSwitchChar(char c)
Definition: args.h:44
std::optional< common::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:105
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:854
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:134