| 16 | |
| 17 | namespace common { |
| 18 | std::optional<ConfigError> InitConfig(ArgsManager& args, SettingsAbortFn settings_abort_fn) |
| 19 | { |
| 20 | try { |
| 21 | if (!CheckDataDirOption(args)) { |
| 22 | return ConfigError{ConfigStatus::FAILED, strprintf(_("Specified data directory \"%s\" does not exist."), args.GetArg("-datadir", ""))}; |
| 23 | } |
| 24 | |
| 25 | // Record original datadir and config paths before parsing the config |
| 26 | // file. It is possible for the config file to contain a datadir= line |
| 27 | // that changes the datadir path after it is parsed. This is useful for |
| 28 | // CLI tools to let them use a different data storage location without |
| 29 | // needing to pass it every time on the command line. (It is not |
| 30 | // possible for the config file to cause another configuration to be |
| 31 | // used, though. Specifying a conf= option in the config file causes a |
| 32 | // parse error, and specifying a datadir= location containing another |
| 33 | // bitcoin.conf file just ignores the other file.) |
| 34 | const fs::path orig_datadir_path{args.GetDataDirBase()}; |
| 35 | const fs::path orig_config_path{AbsPathForConfigVal(args, args.GetPathArg("-conf", BITCOIN_CONF_FILENAME), /*net_specific=*/false)}; |
| 36 | |
| 37 | std::string error; |
| 38 | if (!args.ReadConfigFiles(error, true)) { |
| 39 | return ConfigError{ConfigStatus::FAILED, strprintf(_("Error reading configuration file: %s"), error)}; |
| 40 | } |
| 41 | |
| 42 | // Check for chain settings (Params() calls are only valid after this clause) |
| 43 | SelectParams(args.GetChainType()); |
| 44 | |
| 45 | // Create datadir if it does not exist. |
| 46 | const auto base_path{args.GetDataDirBase()}; |
| 47 | if (!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 enabled |
| 50 | // in the future, it will use the "wallets" subdirectory for creating |
| 51 | // and listing wallets, rather than the top-level directory where |
| 52 | // wallets could be mixed up with other files. For backwards |
| 53 | // compatibility, wallet code will use the "wallets" subdirectory only |
| 54 | // if it already exists, but never create it itself. There is discussion |
| 55 | // in https://github.com/bitcoin/bitcoin/issues/16220 about ways to |
| 56 | // change wallet code so it would no longer be necessary to create |
| 57 | // "wallets" subdirectories here. |
| 58 | fs::create_directories(base_path / "wallets"); |
| 59 | } |
| 60 | const auto net_path{args.GetDataDirNet()}; |
| 61 | if (!fs::exists(net_path)) { |
| 62 | fs::create_directories(net_path / "wallets"); |
| 63 | } |
| 64 | |
| 65 | // Show an error or warn/log if there is a bitcoin.conf file in the |
| 66 | // datadir that is being ignored. |
| 67 | const fs::path base_config_path = base_path / BITCOIN_CONF_FILENAME; |
| 68 | if (fs::exists(base_config_path)) { |
| 69 | if (orig_config_path.empty()) { |
| 70 | LogInfo( |
| 71 | "Data directory %s contains a %s file which is explicitly ignored using -noconf.", |
| 72 | fs::quoted(fs::PathToString(base_path)), |
| 73 | fs::quoted(BITCOIN_CONF_FILENAME)); |
| 74 | } else if (!fs::equivalent(orig_config_path, base_config_path)) { |
| 75 | const std::string cli_config_path = args.GetArg("-conf", ""); |
no test coverage detected