Coverage Report

Created: 2026-08-14 20:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/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 <sync.h>
10
#include <util/chaintype.h>
11
#include <util/fs.h>
12
13
#include <concepts>
14
#include <cstdint>
15
#include <iosfwd>
16
#include <list>
17
#include <map>
18
#include <optional>
19
#include <set>
20
#include <string>
21
#include <string_view>
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
23.0k
{
46
#ifdef WIN32
47
    return c == '-' || c == '/';
48
#else
49
23.0k
    return c == '-';
50
23.0k
#endif
51
23.0k
}
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
    // Specific to one or more commands (OptionsCategory::COMMANDS)
71
    // These are only included in help with their associated commands.
72
    COMMAND_OPTIONS,
73
74
    HIDDEN // Always the last option to avoid printing these in the help
75
};
76
77
struct KeyInfo {
78
    std::string name;
79
    std::string section;
80
    bool negated{false};
81
};
82
83
KeyInfo InterpretKey(std::string key);
84
85
std::optional<common::SettingsValue> InterpretValue(const KeyInfo& key, const std::string* value,
86
                                                         unsigned int flags, std::string& error);
87
88
struct SectionInfo {
89
    std::string m_name;
90
    std::string m_file;
91
    int m_line;
92
};
93
94
std::string SettingToString(const common::SettingsValue&, const std::string&);
95
std::optional<std::string> SettingToString(const common::SettingsValue&);
96
97
template <std::integral Int>
98
Int SettingTo(const common::SettingsValue&, Int);
99
100
template <std::integral Int>
101
std::optional<Int> SettingTo(const common::SettingsValue&);
102
103
bool SettingToBool(const common::SettingsValue&, bool);
104
std::optional<bool> SettingToBool(const common::SettingsValue&);
105
106
class ArgsManager
107
{
108
public:
109
    /**
110
     * Flags controlling how config and command line arguments are validated and
111
     * interpreted.
112
     */
113
    enum Flags : uint32_t {
114
        ALLOW_ANY = 0x01,         //!< disable validation
115
        // ALLOW_BOOL = 0x02,     //!< unimplemented, draft implementation in #16545
116
        // ALLOW_INT = 0x04,      //!< unimplemented, draft implementation in #16545
117
        // ALLOW_STRING = 0x08,   //!< unimplemented, draft implementation in #16545
118
        // ALLOW_LIST = 0x10,     //!< unimplemented, draft implementation in #16545
119
        DISALLOW_NEGATION = 0x20, //!< disallow -nofoo syntax
120
        DISALLOW_ELISION = 0x40,  //!< disallow -foo syntax that doesn't assign any value
121
122
        DEBUG_ONLY = 0x100,
123
        /* Some options would cause cross-contamination if values for
124
         * mainnet were used while running on regtest/testnet (or vice-versa).
125
         * Setting them as NETWORK_ONLY ensures that sharing a config file
126
         * between mainnet and regtest/testnet won't cause problems due to these
127
         * parameters by accident. */
128
        NETWORK_ONLY = 0x200,
129
        // This argument's value is sensitive (such as a password).
130
        SENSITIVE = 0x400,
131
        COMMAND = 0x800,
132
    };
133
134
private:
135
    struct Arg
136
    {
137
        std::string m_help_param;
138
        std::string m_help_text;
139
        unsigned int m_flags;
140
    };
141
142
    mutable Mutex cs_args;
143
    common::Settings m_settings GUARDED_BY(cs_args);
144
    std::vector<std::string> m_command GUARDED_BY(cs_args);
145
    std::string m_network GUARDED_BY(cs_args);
146
    std::set<std::string> m_network_only_args GUARDED_BY(cs_args);
147
    std::map<OptionsCategory, std::map<std::string, Arg>> m_available_args GUARDED_BY(cs_args);
148
    std::optional<unsigned int> m_default_flags GUARDED_BY(cs_args){};
149
    std::map<std::string, std::set<std::string>> m_command_args GUARDED_BY(cs_args);
150
    bool m_accept_any_command GUARDED_BY(cs_args){true};
151
    std::list<SectionInfo> m_config_sections GUARDED_BY(cs_args);
152
    std::optional<fs::path> m_config_path GUARDED_BY(cs_args);
153
    mutable fs::path m_cached_blocks_path GUARDED_BY(cs_args);
154
    mutable fs::path m_cached_datadir_path GUARDED_BY(cs_args);
155
    mutable fs::path m_cached_network_datadir_path GUARDED_BY(cs_args);
156
157
    /**
158
     * Returns true if settings values from the default section should be used,
159
     * depending on the current network and whether the setting is
160
     * network-specific.
161
     */
162
    bool UseDefaultSection(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
163
164
protected:
165
    [[nodiscard]] bool ReadConfigStream(std::istream& stream, const std::string& filepath, std::string& error, bool ignore_invalid_keys = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
166
    [[nodiscard]] bool ReadConfigString(const std::string& str_config) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
167
168
public:
169
    /**
170
     * Get setting value.
171
     *
172
     * Result will be null if setting was unset, true if "-setting" argument was passed
173
     * false if "-nosetting" argument was passed, and a string if a "-setting=value"
174
     * argument was passed.
175
     */
176
    common::SettingsValue GetSetting(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
177
178
    /**
179
     * Get list of setting values.
180
     */
181
    std::vector<common::SettingsValue> GetSettingsList(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
182
183
    ArgsManager();
184
    ~ArgsManager();
185
186
    /**
187
     * Select the network in use
188
     */
189
    void SelectConfigNetwork(const std::string& network) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
190
191
    [[nodiscard]] bool ParseParameters(int argc, const char* const argv[], std::string& error) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
192
193
    /**
194
     * Return config file path (read-only)
195
     */
196
    fs::path GetConfigFilePath() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
197
    void SetConfigFilePath(fs::path) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
198
    [[nodiscard]] bool ReadConfigFiles(std::string& error, bool ignore_invalid_keys = false) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
199
200
    /**
201
     * Log warnings for options in m_section_only_args when
202
     * they are specified in the default section but not overridden
203
     * on the command line or in a network-specific section in the
204
     * config file.
205
     */
206
    std::set<std::string> GetUnsuitableSectionOnlyArgs() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
207
208
    /**
209
     * Log warnings for unrecognized section names in the config file.
210
     */
211
    std::list<SectionInfo> GetUnrecognizedSections() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
212
213
    struct Command {
214
        /** The command (if one has been registered with AddCommand), or empty */
215
        std::string command;
216
        /**
217
         * If command is non-empty: Any args that followed it
218
         * If command is empty: The unregistered command and any args that followed it
219
         */
220
        std::vector<std::string> args;
221
    };
222
    /**
223
     * Get the command and command args (returns std::nullopt if no command provided)
224
     */
225
    std::optional<const Command> GetCommand() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
226
227
    /**
228
     * Check that any command-specific options the user specified are valid
229
     * for the given command.
230
     *
231
     * @param[in] command   The command being run.
232
     * @param[out] errors   If non-null, populated with a message for each invalid option.
233
     * @return false if any command-specific options were specified that are not valid for this command
234
     */
235
    bool CheckCommandOptions(const std::string& command, std::vector<std::string>* errors = nullptr) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
236
237
    /**
238
     * Get blocks directory path
239
     *
240
     * @return Blocks path which is network specific
241
     */
242
    fs::path GetBlocksDirPath() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
243
244
    /**
245
     * Get data directory path
246
     *
247
     * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned
248
     */
249
    fs::path GetDataDirBase() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
250
251
    /**
252
     * Get data directory path with appended network identifier
253
     *
254
     * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned
255
     */
256
    fs::path GetDataDirNet() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
257
258
    /**
259
     * Clear cached directory paths
260
     */
261
    void ClearPathCache() EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
262
263
    /**
264
     * Return a vector of strings of the given argument
265
     *
266
     * @param strArg Argument to get (e.g. "-foo")
267
     * @return command-line arguments
268
     */
269
    std::vector<std::string> GetArgs(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
270
271
    /**
272
     * Return true if the given argument has been manually set
273
     *
274
     * @param strArg Argument to get (e.g. "-foo")
275
     * @return true if the argument has been set
276
     */
277
    bool IsArgSet(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
278
279
    /**
280
     * Return true if the argument was originally passed as a negated option,
281
     * i.e. -nofoo.
282
     *
283
     * @param strArg Argument to get (e.g. "-foo")
284
     * @return true if the argument was passed negated
285
     */
286
    bool IsArgNegated(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
287
288
    /**
289
     * Return string argument or default value
290
     *
291
     * @param strArg Argument to get (e.g. "-foo")
292
     * @param strDefault (e.g. "1")
293
     * @return command-line argument or default value
294
     */
295
    std::string GetArg(const std::string& strArg, const std::string& strDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
296
    std::optional<std::string> GetArg(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
297
298
    /**
299
     * Return path argument or default value
300
     *
301
     * @param arg Argument to get a path from (e.g., "-datadir", "-blocksdir" or "-walletdir")
302
     * @param default_value Optional default value to return instead of the empty path.
303
     * @return normalized path if argument is set, with redundant "." and ".."
304
     * path components and trailing separators removed (see patharg unit test
305
     * for examples or implementation for details). If argument is empty or not
306
     * set, default_value is returned unchanged.
307
     */
308
    fs::path GetPathArg(std::string arg, const fs::path& default_value = {}) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
309
310
    /**
311
     * Return integer argument or default value
312
     *
313
     * @param strArg Argument to get (e.g. "-foo")
314
     * @param nDefault (e.g. 1)
315
     * @return command-line argument (0 if invalid number) or default value
316
     */
317
    template <std::integral Int>
318
    Int GetArg(const std::string& strArg, Int nDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
319
320
    template <std::integral Int>
321
    std::optional<Int> GetArg(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
322
323
96.2k
    int64_t GetIntArg(const std::string& strArg, int64_t nDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args) { return GetArg<int64_t>(strArg, nDefault); }
324
31.9k
    std::optional<int64_t> GetIntArg(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args) { return GetArg<int64_t>(strArg); }
325
326
    /**
327
     * Return boolean argument or default value
328
     *
329
     * @param strArg Argument to get (e.g. "-foo")
330
     * @param fDefault (true or false)
331
     * @return command-line argument or default value
332
     */
333
    bool GetBoolArg(const std::string& strArg, bool fDefault) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
334
    std::optional<bool> GetBoolArg(const std::string& strArg) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
335
336
    /**
337
     * Set an argument if it doesn't already have a value
338
     *
339
     * @param strArg Argument to set (e.g. "-foo")
340
     * @param strValue Value (e.g. "1")
341
     * @return true if argument gets set, false if it already had a value
342
     */
343
    bool SoftSetArg(const std::string& strArg, const std::string& strValue) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
344
345
    /**
346
     * Set a boolean argument if it doesn't already have a value
347
     *
348
     * @param strArg Argument to set (e.g. "-foo")
349
     * @param fValue Value (e.g. false)
350
     * @return true if argument gets set, false if it already had a value
351
     */
352
    bool SoftSetBoolArg(const std::string& strArg, bool fValue) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
353
354
    // Forces an arg setting. Called by SoftSetArg() if the arg hasn't already
355
    // been set. Also called directly in testing.
356
    void ForceSetArg(const std::string& strArg, const std::string& strValue) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
357
358
    /**
359
     * Returns the appropriate chain type from the program arguments.
360
     * @return ChainType::MAIN by default; raises runtime error if an invalid
361
     * combination, or unknown chain is given.
362
     */
363
    ChainType GetChainType() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
364
365
    /**
366
     * Returns the appropriate chain type string from the program arguments.
367
     * @return ChainType::MAIN string by default; raises runtime error if an
368
     * invalid combination is given.
369
     */
370
    std::string GetChainTypeString() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
371
372
    /**
373
     * Add argument
374
     */
375
    void AddArg(const std::string& name, const std::string& help, unsigned int flags, const OptionsCategory& cat) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
376
377
    /**
378
     * Add command
379
     */
380
    void AddCommand(const std::string& cmd, const std::string& help, std::set<std::string> options = {}) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
381
382
    /**
383
     * Add many hidden arguments
384
     */
385
    void AddHiddenArgs(const std::vector<std::string>& args) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
386
387
    /**
388
     * Clear available arguments
389
     */
390
    void ClearArgs() EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
391
392
    /**
393
     * Check CLI command args
394
     *
395
     * @throws std::runtime_error when multiple CLI_COMMAND arguments are specified
396
     */
397
    void CheckMultipleCLIArgs() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
398
399
    /**
400
     * Get the help string
401
     */
402
    std::string GetHelpMessage() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
403
404
    /**
405
     * Return Flags for known arg.
406
     * Return default flags for unknown arg.
407
     */
408
    std::optional<unsigned int> GetArgFlags(const std::string& name) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
409
410
    /**
411
     * Set default flags to return for an unknown arg.
412
     */
413
    void SetDefaultFlags(std::optional<unsigned int>) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
414
415
    /**
416
     * Get settings file path, or return false if read-write settings were
417
     * disabled with -nosettings.
418
     */
419
    bool GetSettingsPath(fs::path* filepath = nullptr, bool temp = false, bool backup = false) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
420
421
    /**
422
     * Read settings file. Push errors to vector, or log them if null.
423
     */
424
    bool ReadSettingsFile(std::vector<std::string>* errors = nullptr) EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
425
426
    /**
427
     * Write settings file or backup settings file. Push errors to vector, or
428
     * log them if null.
429
     */
430
    bool WriteSettingsFile(std::vector<std::string>* errors = nullptr, bool backup = false) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
431
432
    /**
433
     * Get current setting from config file or read/write settings file,
434
     * ignoring nonpersistent command line or forced settings values.
435
     */
436
    common::SettingsValue GetPersistentSetting(const std::string& name) const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
437
438
    /**
439
     * Access settings with lock held.
440
     */
441
    template <typename Fn>
442
    void LockSettings(Fn&& fn) EXCLUSIVE_LOCKS_REQUIRED(!cs_args)
443
229
    {
444
229
        LOCK(cs_args);
445
229
        fn(m_settings);
446
229
    }
argsman_tests.cpp:void ArgsManager::LockSettings<argsman_tests::util_ParseParameters::test_method()::$_0>(argsman_tests::util_ParseParameters::test_method()::$_0&&)
Line
Count
Source
443
1
    {
444
1
        LOCK(cs_args);
445
1
        fn(m_settings);
446
1
    }
argsman_tests.cpp:void ArgsManager::LockSettings<argsman_tests::util_ParseParameters::test_method()::$_1>(argsman_tests::util_ParseParameters::test_method()::$_1&&)
Line
Count
Source
443
1
    {
444
1
        LOCK(cs_args);
445
1
        fn(m_settings);
446
1
    }
argsman_tests.cpp:void ArgsManager::LockSettings<argsman_tests::util_ParseParameters::test_method()::$_2>(argsman_tests::util_ParseParameters::test_method()::$_2&&)
Line
Count
Source
443
1
    {
444
1
        LOCK(cs_args);
445
1
        fn(m_settings);
446
1
    }
argsman_tests.cpp:void ArgsManager::LockSettings<argsman_tests::util_GetBoolArg::test_method()::$_0>(argsman_tests::util_GetBoolArg::test_method()::$_0&&)
Line
Count
Source
443
1
    {
444
1
        LOCK(cs_args);
445
1
        fn(m_settings);
446
1
    }
argsman_tests.cpp:void ArgsManager::LockSettings<argsman_tests::util_ReadConfigStream::test_method()::$_0>(argsman_tests::util_ReadConfigStream::test_method()::$_0&&)
Line
Count
Source
443
1
    {
444
1
        LOCK(cs_args);
445
1
        fn(m_settings);
446
1
    }
argsman_tests.cpp:void ArgsManager::LockSettings<argsman_tests::util_GetArg::test_method()::$_0>(argsman_tests::util_GetArg::test_method()::$_0&&)
Line
Count
Source
443
1
    {
444
1
        LOCK(cs_args);
445
1
        fn(m_settings);
446
1
    }
argsman_tests.cpp:void ArgsManager::LockSettings<argsman_tests::util_ReadWriteSettings::test_method()::$_0>(argsman_tests::util_ReadWriteSettings::test_method()::$_0&&)
Line
Count
Source
443
1
    {
444
1
        LOCK(cs_args);
445
1
        fn(m_settings);
446
1
    }
argsman_tests.cpp:void ArgsManager::LockSettings<argsman_tests::util_ReadWriteSettings::test_method()::$_1>(argsman_tests::util_ReadWriteSettings::test_method()::$_1&&)
Line
Count
Source
443
1
    {
444
1
        LOCK(cs_args);
445
1
        fn(m_settings);
446
1
    }
getarg_tests.cpp:void ArgsManager::LockSettings<getarg_tests::setting_args::test_method()::$_0::operator()(UniValue const&) const::'lambda'(common::Settings&)>(getarg_tests::setting_args::test_method()::$_0::operator()(UniValue const&) const::'lambda'(common::Settings&)&&)
Line
Count
Source
443
13
    {
444
13
        LOCK(cs_args);
445
13
        fn(m_settings);
446
13
    }
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&)&&)
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&)&&)
Line
Count
Source
443
3
    {
444
3
        LOCK(cs_args);
445
3
        fn(m_settings);
446
3
    }
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&)&&)
Line
Count
Source
443
205
    {
444
205
        LOCK(cs_args);
445
205
        fn(m_settings);
446
205
    }
447
448
    /**
449
     * Log the config file options and the command line arguments,
450
     * useful for troubleshooting.
451
     */
452
    void LogArgs() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
453
454
private:
455
    // Internal helpers, for use by callers that already hold `cs_args`.
456
    common::SettingsValue GetSetting_(const std::string& arg) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
457
    std::optional<unsigned int> GetArgFlags_(const std::string& name) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
458
    fs::path GetPathArg_(std::string arg, const fs::path& default_value = {}) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
459
460
    /**
461
     * Get data directory path
462
     *
463
     * @param net_specific Append network identifier to the returned path
464
     * @return Absolute path on success, otherwise an empty path when a non-directory path would be returned
465
     */
466
    fs::path GetDataDir(bool net_specific) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
467
468
    /**
469
     * Return -regtest/-signet/-testnet/-testnet4/-chain= setting as a ChainType enum if a
470
     * recognized chain type was set, or as a string if an unrecognized chain
471
     * name was set. Raise an exception if an invalid combination of flags was
472
     * provided.
473
     */
474
    std::variant<ChainType, std::string> GetChainArg() const EXCLUSIVE_LOCKS_REQUIRED(!cs_args);
475
476
    // Helper function for LogArgs().
477
    void logArgsPrefix(
478
        const std::string& prefix,
479
        const std::string& section,
480
        const std::map<std::string, std::vector<common::SettingsValue>>& args) const EXCLUSIVE_LOCKS_REQUIRED(cs_args);
481
};
482
483
extern ArgsManager gArgs;
484
485
/**
486
 * @return true if help has been requested via a command-line arg
487
 */
488
bool HelpRequested(const ArgsManager& args);
489
490
/** Add help options to the args manager */
491
void SetupHelpOptions(ArgsManager& args);
492
493
extern const std::vector<std::string> TEST_OPTIONS_DOC;
494
495
/** Checks if a particular test option is present in -test command-line arg options */
496
bool HasTestOption(const ArgsManager& args, const std::string& test_option);
497
498
/**
499
 * Format a string to be used as group of options in help messages
500
 *
501
 * @param message Group name (e.g. "RPC server options:")
502
 * @return the formatted string
503
 */
504
std::string HelpMessageGroup(const std::string& message);
505
506
/**
507
 * Format a string to be used as option description in help messages
508
 *
509
 * @param option Option name (e.g. "-rpcuser")
510
 * @param help_param Help parameter (e.g. "=<user>" or "")
511
 * @param message Option description (e.g. "Username for JSON-RPC connections")
512
 * @param subopt True if this is a suboption, instead of a top-level option.
513
 * @return the formatted string
514
 */
515
std::string HelpMessageOpt(std::string_view option, std::string_view help_param, std::string_view message, bool subopt = false);
516
517
#endif // BITCOIN_COMMON_ARGS_H