Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2023-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <common/init.h>7#include <chainparams.h>8#include <common/args.h>9#include <tinyformat.h>10#include <util/fs.h>11#include <util/log.h>12#include <util/translation.h>14#include <exception>15#include <optional>17namespace common {18std::optional<ConfigError> InitConfig(ArgsManager& args, SettingsAbortFn settings_abort_fn)19{20try {21if (!CheckDataDirOption(args)) {22return ConfigError{ConfigStatus::FAILED, strprintf(_("Specified data directory \"%s\" does not exist."), args.GetArg("-datadir", ""))};23}25// Record original datadir and config paths before parsing the config26// file. It is possible for the config file to contain a datadir= line27// that changes the datadir path after it is parsed. This is useful for28// CLI tools to let them use a different data storage location without29// needing to pass it every time on the command line. (It is not30// possible for the config file to cause another configuration to be31// used, though. Specifying a conf= option in the config file causes a32// parse error, and specifying a datadir= location containing another33// bitcoin.conf file just ignores the other file.)34const fs::path orig_datadir_path{args.GetDataDirBase()};35const fs::path orig_config_path{AbsPathForConfigVal(args, args.GetPathArg("-conf", BITCOIN_CONF_FILENAME), /*net_specific=*/false)};37std::string error;38if (!args.ReadConfigFiles(error, true)) {39return ConfigError{ConfigStatus::FAILED, strprintf(_("Error reading configuration file: %s"), error)};40}42// Check for chain settings (Params() calls are only valid after this clause)43SelectParams(args.GetChainType());45// Create datadir if it does not exist.46const auto base_path{args.GetDataDirBase()};47if (!fs::exists(base_path)) {48// When creating a *new* datadir, also create a "wallets" subdirectory,49// whether or not the wallet is enabled now, so if the wallet is enabled50// in the future, it will use the "wallets" subdirectory for creating51// and listing wallets, rather than the top-level directory where52// wallets could be mixed up with other files. For backwards53// compatibility, wallet code will use the "wallets" subdirectory only54// if it already exists, but never create it itself. There is discussion55// in https://github.com/bitcoin/bitcoin/issues/16220 about ways to56// change wallet code so it would no longer be necessary to create57// "wallets" subdirectories here.58fs::create_directories(base_path / "wallets");59}60const auto net_path{args.GetDataDirNet()};61if (!fs::exists(net_path)) {62fs::create_directories(net_path / "wallets");63}65// Show an error or warn/log if there is a bitcoin.conf file in the66// datadir that is being ignored.67const fs::path base_config_path = base_path / BITCOIN_CONF_FILENAME;68if (fs::exists(base_config_path)) {69if (orig_config_path.empty()) {70LogInfo(71"Data directory %s contains a %s file which is explicitly ignored using -noconf.",72fs::quoted(fs::PathToString(base_path)),73fs::quoted(BITCOIN_CONF_FILENAME));74} else if (!fs::equivalent(orig_config_path, base_config_path)) {75const std::string cli_config_path = args.GetArg("-conf", "");76const std::string config_source = cli_config_path.empty()77? strprintf("data directory %s", fs::quoted(fs::PathToString(orig_datadir_path)))78: strprintf("command line argument %s", fs::quoted("-conf=" + cli_config_path));79std::string error = strprintf(80"Data directory %1$s contains a %2$s file which is ignored, because a different configuration file "81"%3$s from %4$s is being used instead. Possible ways to address this would be to:\n"82"- Delete or rename the %2$s file in data directory %1$s.\n"83"- Change datadir= or conf= options to specify one configuration file, not two, and use "84"includeconf= to include any other configuration files.",85fs::quoted(fs::PathToString(base_path)),86fs::quoted(BITCOIN_CONF_FILENAME),87fs::quoted(fs::PathToString(orig_config_path)),88config_source);89if (args.GetBoolArg("-allowignoredconf", false)) {90LogWarning("%s", error);91} else {92error += "\n- Set allowignoredconf=1 option to treat this condition as a warning, not an error.";93return ConfigError{ConfigStatus::FAILED, Untranslated(error)};94}95}96}98// Create settings.json if -nosettings was not specified.99if (args.GetSettingsPath()) {100std::vector<std::string> details;101if (!args.ReadSettingsFile(&details)) {102const bilingual_str& message = _("Settings file could not be read");103if (!settings_abort_fn) {104return ConfigError{ConfigStatus::FAILED, message, details};105} else if (settings_abort_fn(message, details)) {106return ConfigError{ConfigStatus::ABORTED, message, details};107} else {108details.clear(); // User chose to ignore the error and proceed.109}110}111if (!args.WriteSettingsFile(&details)) {112const bilingual_str& message = _("Settings file could not be written");113return ConfigError{ConfigStatus::FAILED_WRITE, message, details};114}115}116} catch (const std::exception& e) {117return ConfigError{ConfigStatus::FAILED, Untranslated(e.what())};118}119return {};120}121} // namespace common
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.