Bitcoin Core Fuzz Coverage Report

Coverage Report

Created: 2026-03-24 13:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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