/root/bitcoin/src/common/args.h
Line | Count | Source |
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. |
31 | | bool CheckDataDirOption(const ArgsManager& args); |
32 | | |
33 | | /** |
34 | | * Most paths passed as configuration arguments are treated as relative to |
35 | | * the datadir if they are not absolute. |
36 | | * |
37 | | * @param args Parsed arguments and settings. |
38 | | * @param path The path to be conditionally prefixed with datadir. |
39 | | * @param net_specific Use network specific datadir variant |
40 | | * @return The normalized path. |
41 | | */ |
42 | | fs::path AbsPathForConfigVal(const ArgsManager& args, const fs::path& path, bool net_specific = true); |
43 | | |
44 | | inline bool IsSwitchChar(char c) |
45 | 0 | { |
46 | | #ifdef WIN32 |
47 | | return c == '-' || c == '/'; |
48 | | #else |
49 | 0 | return c == '-'; |
50 | 0 | #endif |
51 | 0 | } |
52 | | |
53 | | enum class OptionsCategory { |
54 | | OPTIONS, |
55 | | CONNECTION, |
56 | | WALLET, |
57 | | WALLET_DEBUG_TEST, |
58 | | ZMQ, |
59 | | DEBUG_TEST, |
60 | | CHAINPARAMS, |
61 | | NODE_RELAY, |
62 | | BLOCK_CREATION, |
63 | | RPC, |
64 | | GUI, |
65 | | COMMANDS, |
66 | | REGISTER_COMMANDS, |
67 | | CLI_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 | | |
102 | | class ArgsManager |
103 | | { |
104 | | public: |
105 | | /** |
106 | | * Flags controlling how config and command line arguments are validated and |
107 | | * interpreted. |
108 | | */ |
109 | | enum Flags : uint32_t { |
110 | | ALLOW_ANY = 0x01, //!< disable validation |
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 |
115 | | DISALLOW_NEGATION = 0x20, //!< disallow -nofoo syntax |
116 | | DISALLOW_ELISION = 0x40, //!< disallow -foo syntax that doesn't assign any value |
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 | | private: |
131 | | struct Arg |
132 | | { |
133 | | std::string m_help_param; |
134 | | std::string m_help_text; |
135 | | unsigned int m_flags; |
136 | | }; |
137 | | |
138 | | mutable Mutex cs_args; |
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 | | /** |
153 | | * Returns true if settings values from the default section should be used, |
154 | | * depending on the current network and whether the setting is |
155 | | * network-specific. |
156 | | */ |
157 | | bool UseDefaultSection(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args); |
158 | | |
159 | | protected: |
160 | | [[nodiscard]] bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
161 | | [[nodiscard]] bool ReadConfigString(const std::string& str_config) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
162 | | |
163 | | public: |
164 | | /** |
165 | | * Get setting value. |
166 | | * |
167 | | * Result will be null if setting was unset, true if "-setting" argument was passed |
168 | | * false if "-nosetting" argument was passed, and a string if a "-setting=value" |
169 | | * argument was passed. |
170 | | */ |
171 | | common::SettingsValue GetSetting(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
172 | | |
173 | | /** |
174 | | * Get list of setting values. |
175 | | */ |
176 | | std::vector<common::SettingsValue> GetSettingsList(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
177 | | |
178 | | ArgsManager(); |
179 | | ~ArgsManager(); |
180 | | |
181 | | /** |
182 | | * Select the network in use |
183 | | */ |
184 | | void SelectConfigNetwork(const std::string& network) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
185 | | |
186 | | [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
187 | | |
188 | | /** |
189 | | * Return config file path (read-only) |
190 | | */ |
191 | | fs::path GetConfigFilePath() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
192 | | void SetConfigFilePath(fs::path) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
193 | | [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
194 | | |
195 | | /** |
196 | | * Log warnings for options in m_section_only_args when |
197 | | * they are specified in the default section but not overridden |
198 | | * on the command line or in a network-specific section in the |
199 | | * config file. |
200 | | */ |
201 | | std::set<std::string> GetUnsuitableSectionOnlyArgs() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
202 | | |
203 | | /** |
204 | | * Log warnings for unrecognized section names in the config file. |
205 | | */ |
206 | | std::list<SectionInfo> GetUnrecognizedSections() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
207 | | |
208 | | struct Command { |
209 | | /** The command (if one has been registered with AddCommand), or empty */ |
210 | | std::string command; |
211 | | /** |
212 | | * If command is non-empty: Any args that followed it |
213 | | * If command is empty: The unregistered command and any args that followed it |
214 | | */ |
215 | | std::vector<std::string> args; |
216 | | }; |
217 | | /** |
218 | | * Get the command and command args (returns std::nullopt if no command provided) |
219 | | */ |
220 | | std::optional<const Command> GetCommand() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
221 | | |
222 | | /** |
223 | | * Get blocks directory path |
224 | | * |
225 | | * @return Blocks path which is network specific |
226 | | */ |
227 | | fs::path GetBlocksDirPath() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
228 | | |
229 | | /** |
230 | | * Get data directory path |
231 | | * |
232 | | * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned |
233 | | */ |
234 | | fs::path GetDataDirBase() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
235 | | |
236 | | /** |
237 | | * Get data directory path with appended network identifier |
238 | | * |
239 | | * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned |
240 | | */ |
241 | | fs::path GetDataDirNet() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
242 | | |
243 | | /** |
244 | | * Clear cached directory paths |
245 | | */ |
246 | | void ClearPathCache() EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
247 | | |
248 | | /** |
249 | | * Return a vector of strings of the given argument |
250 | | * |
251 | | * @param strArg Argument to get (e.g. "-foo") |
252 | | * @return command-line arguments |
253 | | */ |
254 | | std::vector<std::string> GetArgs(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
255 | | |
256 | | /** |
257 | | * Return true if the given argument has been manually set |
258 | | * |
259 | | * @param strArg Argument to get (e.g. "-foo") |
260 | | * @return true if the argument has been set |
261 | | */ |
262 | | bool IsArgSet(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
263 | | |
264 | | /** |
265 | | * Return true if the argument was originally passed as a negated option, |
266 | | * i.e. -nofoo. |
267 | | * |
268 | | * @param strArg Argument to get (e.g. "-foo") |
269 | | * @return true if the argument was passed negated |
270 | | */ |
271 | | bool IsArgNegated(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
272 | | |
273 | | /** |
274 | | * Return string argument or default value |
275 | | * |
276 | | * @param strArg Argument to get (e.g. "-foo") |
277 | | * @param strDefault (e.g. "1") |
278 | | * @return command-line argument or default value |
279 | | */ |
280 | | std::string GetArg(const std::string& strArg, const std::string& strDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
281 | | std::optional<std::string> GetArg(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
282 | | |
283 | | /** |
284 | | * Return path argument or default value |
285 | | * |
286 | | * @param arg Argument to get a path from (e.g., "-datadir", "-blocksdir" or "-walletdir") |
287 | | * @param default_value Optional default value to return instead of the empty path. |
288 | | * @return normalized path if argument is set, with redundant "." and ".." |
289 | | * path components and trailing separators removed (see patharg unit test |
290 | | * for examples or implementation for details). If argument is empty or not |
291 | | * set, default_value is returned unchanged. |
292 | | */ |
293 | | fs::path GetPathArg(std::string arg, const fs::path& default_value = {}) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
294 | | |
295 | | /** |
296 | | * Return integer argument or default value |
297 | | * |
298 | | * @param strArg Argument to get (e.g. "-foo") |
299 | | * @param nDefault (e.g. 1) |
300 | | * @return command-line argument (0 if invalid number) or default value |
301 | | */ |
302 | | template <std::integral Int> |
303 | | Int GetArg(const std::string& strArg, Int nDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
304 | | |
305 | | template <std::integral Int> |
306 | | std::optional<Int> GetArg(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
307 | | |
308 | 0 | int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args) { return GetArg<int64_t>(strArg, nDefault); } |
309 | 0 | std::optional<int64_t> GetIntArg(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args) { return GetArg<int64_t>(strArg); } |
310 | | |
311 | | /** |
312 | | * Return boolean argument or default value |
313 | | * |
314 | | * @param strArg Argument to get (e.g. "-foo") |
315 | | * @param fDefault (true or false) |
316 | | * @return command-line argument or default value |
317 | | */ |
318 | | bool GetBoolArg(const std::string& strArg, bool fDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
319 | | std::optional<bool> GetBoolArg(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
320 | | |
321 | | /** |
322 | | * Set an argument if it doesn't already have a value |
323 | | * |
324 | | * @param strArg Argument to set (e.g. "-foo") |
325 | | * @param strValue Value (e.g. "1") |
326 | | * @return true if argument gets set, false if it already had a value |
327 | | */ |
328 | | bool SoftSetArg(const std::string& strArg, const std::string& strValue) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
329 | | |
330 | | /** |
331 | | * Set a boolean argument if it doesn't already have a value |
332 | | * |
333 | | * @param strArg Argument to set (e.g. "-foo") |
334 | | * @param fValue Value (e.g. false) |
335 | | * @return true if argument gets set, false if it already had a value |
336 | | */ |
337 | | bool SoftSetBoolArg(const std::string& strArg, bool fValue) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
338 | | |
339 | | // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already |
340 | | // been set. Also called directly in testing. |
341 | | void ForceSetArg(const std::string& strArg, const std::string& strValue) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
342 | | |
343 | | /** |
344 | | * Returns the appropriate chain type from the program arguments. |
345 | | * @return ChainType::MAIN by default; raises runtime error if an invalid |
346 | | * combination, or unknown chain is given. |
347 | | */ |
348 | | ChainType GetChainType() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
349 | | |
350 | | /** |
351 | | * Returns the appropriate chain type string from the program arguments. |
352 | | * @return ChainType::MAIN string by default; raises runtime error if an |
353 | | * invalid combination is given. |
354 | | */ |
355 | | std::string GetChainTypeString() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
356 | | |
357 | | /** |
358 | | * Add argument |
359 | | */ |
360 | | void AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
361 | | |
362 | | /** |
363 | | * Add subcommand |
364 | | */ |
365 | | void AddCommand(const std::string& cmd, const std::string& help) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
366 | | |
367 | | /** |
368 | | * Add many hidden arguments |
369 | | */ |
370 | | void AddHiddenArgs(const std::vector<std::string>& args) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
371 | | |
372 | | /** |
373 | | * Clear available arguments |
374 | | */ |
375 | | void ClearArgs() EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
376 | | |
377 | | /** |
378 | | * Check CLI command args |
379 | | * |
380 | | * @throws std::runtime_error when multiple CLI_COMMAND arguments are specified |
381 | | */ |
382 | | void CheckMultipleCLIArgs() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
383 | | |
384 | | /** |
385 | | * Get the help string |
386 | | */ |
387 | | std::string GetHelpMessage() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
388 | | |
389 | | /** |
390 | | * Return Flags for known arg. |
391 | | * Return default flags for unknown arg. |
392 | | */ |
393 | | std::optional<unsigned int> GetArgFlags(const std::string& name) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
394 | | |
395 | | /** |
396 | | * Set default flags to return for an unknown arg. |
397 | | */ |
398 | | void SetDefaultFlags(std::optional<unsigned int>) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
399 | | |
400 | | /** |
401 | | * Get settings file path, or return false if read-write settings were |
402 | | * disabled with -nosettings. |
403 | | */ |
404 | | bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false, bool backup = false) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
405 | | |
406 | | /** |
407 | | * Read settings file. Push errors to vector, or log them if null. |
408 | | */ |
409 | | bool ReadSettingsFile(std::vector<std::string>* errors = nullptr) EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
410 | | |
411 | | /** |
412 | | * Write settings file or backup settings file. Push errors to vector, or |
413 | | * log them if null. |
414 | | */ |
415 | | bool WriteSettingsFile(std::vector<std::string>* errors = nullptr, bool backup = false) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
416 | | |
417 | | /** |
418 | | * Get current setting from config file or read/write settings file, |
419 | | * ignoring nonpersistent command line or forced settings values. |
420 | | */ |
421 | | common::SettingsValue GetPersistentSetting(const std::string& name) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
422 | | |
423 | | /** |
424 | | * Access settings with lock held. |
425 | | */ |
426 | | template <typename Fn> |
427 | | void LockSettings(Fn&& fn) EXCLUSIVE_LOCKS_REQUIRED(!cs_args) |
428 | 0 | { |
429 | 0 | LOCK(cs_args); Line | Count | Source | 266 | 0 | #define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) Line | Count | Source | 11 | 0 | #define UNIQUE_NAME(name) PASTE2(name, __COUNTER__) Line | Count | Source | 9 | 0 | #define PASTE2(x, y) PASTE(x, y) Line | Count | Source | 8 | 0 | #define PASTE(x, y) x ## y |
|
|
|
| LOCK(cs_args); Line | Count | Source | 266 | 0 | #define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) Line | Count | Source | 11 | 0 | #define UNIQUE_NAME(name) PASTE2(name, __COUNTER__) Line | Count | Source | 9 | 0 | #define PASTE2(x, y) PASTE(x, y) Line | Count | Source | 8 | 0 | #define PASTE(x, y) x ## y |
|
|
|
| LOCK(cs_args); Line | Count | Source | 266 | 0 | #define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) Line | Count | Source | 11 | 0 | #define UNIQUE_NAME(name) PASTE2(name, __COUNTER__) Line | Count | Source | 9 | 0 | #define PASTE2(x, y) PASTE(x, y) Line | Count | Source | 8 | 0 | #define PASTE(x, y) x ## y |
|
|
|
| LOCK(cs_args); Line | Count | Source | 266 | 0 | #define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) Line | Count | Source | 11 | 0 | #define UNIQUE_NAME(name) PASTE2(name, __COUNTER__) Line | Count | Source | 9 | 0 | #define PASTE2(x, y) PASTE(x, y) Line | Count | Source | 8 | 0 | #define PASTE(x, y) x ## y |
|
|
|
| LOCK(cs_args); Line | Count | Source | 266 | 0 | #define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) Line | Count | Source | 11 | 0 | #define UNIQUE_NAME(name) PASTE2(name, __COUNTER__) Line | Count | Source | 9 | 0 | #define PASTE2(x, y) PASTE(x, y) Line | Count | Source | 8 | 0 | #define PASTE(x, y) x ## y |
|
|
|
| LOCK(cs_args); Line | Count | Source | 266 | 0 | #define LOCK(cs) UniqueLock UNIQUE_NAME(criticalblock)(MaybeCheckNotHeld(cs), #cs, __FILE__, __LINE__) Line | Count | Source | 11 | 0 | #define UNIQUE_NAME(name) PASTE2(name, __COUNTER__) Line | Count | Source | 9 | 0 | #define PASTE2(x, y) PASTE(x, y) Line | Count | Source | 8 | 0 | #define PASTE(x, y) x ## y |
|
|
|
|
430 | 0 | fn(m_settings); |
431 | 0 | } Unexecuted instantiation: interfaces.cpp:void ArgsManager::LockSettings<node::(anonymous namespace)::NodeImpl::isSettingIgnored(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::'lambda'(common::Settings&)>(node::(anonymous namespace)::NodeImpl::isSettingIgnored(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::'lambda'(common::Settings&)&&) Unexecuted instantiation: interfaces.cpp:void ArgsManager::LockSettings<node::(anonymous namespace)::NodeImpl::updateRwSetting(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, UniValue const&)::'lambda'(common::Settings&)>(node::(anonymous namespace)::NodeImpl::updateRwSetting(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, UniValue const&)::'lambda'(common::Settings&)&&) Unexecuted instantiation: interfaces.cpp:void ArgsManager::LockSettings<node::(anonymous namespace)::NodeImpl::forceSetting(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, UniValue const&)::'lambda'(common::Settings&)>(node::(anonymous namespace)::NodeImpl::forceSetting(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, UniValue const&)::'lambda'(common::Settings&)&&) Unexecuted instantiation: interfaces.cpp:void ArgsManager::LockSettings<node::(anonymous namespace)::NodeImpl::resetSettings()::'lambda'(common::Settings&)>(node::(anonymous namespace)::NodeImpl::resetSettings()::'lambda'(common::Settings&)&&) Unexecuted instantiation: interfaces.cpp:void ArgsManager::LockSettings<node::(anonymous namespace)::ChainImpl::getRwSetting(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::'lambda'(common::Settings const&)>(node::(anonymous namespace)::ChainImpl::getRwSetting(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::'lambda'(common::Settings const&)&&) Unexecuted instantiation: interfaces.cpp:void ArgsManager::LockSettings<node::(anonymous namespace)::ChainImpl::updateRwSetting(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::function<std::optional<interfaces::SettingsAction> (UniValue&)> const&)::'lambda'(common::Settings&)>(node::(anonymous namespace)::ChainImpl::updateRwSetting(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::function<std::optional<interfaces::SettingsAction> (UniValue&)> const&)::'lambda'(common::Settings&)&&) |
432 | | |
433 | | /** |
434 | | * Log the config file options and the command line arguments, |
435 | | * useful for troubleshooting. |
436 | | */ |
437 | | void LogArgs() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
438 | | |
439 | | private: |
440 | | // Internal helpers, for use by callers that already hold `cs_args`. |
441 | | common::SettingsValue GetSetting_(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args); |
442 | | std::optional<unsigned int> GetArgFlags_(const std::string& name) const EXCLUSIVE_LOCKS_REQUIRED(cs_args); |
443 | | fs::path GetPathArg_(std::string arg, const fs::path& default_value = {}) const EXCLUSIVE_LOCKS_REQUIRED(cs_args); |
444 | | |
445 | | /** |
446 | | * Get data directory path |
447 | | * |
448 | | * @param net_specific Append network identifier to the returned path |
449 | | * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned |
450 | | */ |
451 | | fs::path GetDataDir(bool net_specific) const EXCLUSIVE_LOCKS_REQUIRED(cs_args); |
452 | | |
453 | | /** |
454 | | * Return -regtest/-signet/-testnet/-testnet4/-chain= setting as a ChainType enum if a |
455 | | * recognized chain type was set, or as a string if an unrecognized chain |
456 | | * name was set. Raise an exception if an invalid combination of flags was |
457 | | * provided. |
458 | | */ |
459 | | std::variant<ChainType, std::string> GetChainArg() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args); |
460 | | |
461 | | // Helper function for LogArgs(). |
462 | | void logArgsPrefix( |
463 | | const std::string& prefix, |
464 | | const std::string& section, |
465 | | const std::map<std::string, std::vector<common::SettingsValue>>& args) const EXCLUSIVE_LOCKS_REQUIRED(cs_args); |
466 | | }; |
467 | | |
468 | | extern ArgsManager gArgs; |
469 | | |
470 | | /** |
471 | | * @return true if help has been requested via a command-line arg |
472 | | */ |
473 | | bool HelpRequested(const ArgsManager& args); |
474 | | |
475 | | /** Add help options to the args manager */ |
476 | | void SetupHelpOptions(ArgsManager& args); |
477 | | |
478 | | extern const std::vector<std::string> TEST_OPTIONS_DOC; |
479 | | |
480 | | /** Checks if a particular test option is present in -test command-line arg options */ |
481 | | bool HasTestOption(const ArgsManager& args, const std::string& test_option); |
482 | | |
483 | | /** |
484 | | * Format a string to be used as group of options in help messages |
485 | | * |
486 | | * @param message Group name (e.g. "RPC server options:") |
487 | | * @return the formatted string |
488 | | */ |
489 | | std::string HelpMessageGroup(const std::string& message); |
490 | | |
491 | | /** |
492 | | * Format a string to be used as option description in help messages |
493 | | * |
494 | | * @param option Option message (e.g. "-rpcuser=<user>") |
495 | | * @param message Option description (e.g. "Username for JSON-RPC connections") |
496 | | * @return the formatted string |
497 | | */ |
498 | | std::string HelpMessageOpt(const std::string& option, const std::string& message); |
499 | | |
500 | | #endif // BITCOIN_COMMON_ARGS_H |