diff --git a/src/common/init.cpp b/src/common/init.cpp index 412d73aec7016c..60dbbf90df9c17 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -45,21 +45,11 @@ std::optional InitConfig(ArgsManager& args, SettingsAbortFn setting // Create datadir if it does not exist. const auto base_path{args.GetDataDirBase()}; if (!fs::exists(base_path)) { - // When creating a *new* datadir, also create a "wallets" subdirectory, - // whether or not the wallet is enabled now, so if the wallet is enabled - // in the future, it will use the "wallets" subdirectory for creating - // and listing wallets, rather than the top-level directory where - // wallets could be mixed up with other files. For backwards - // compatibility, wallet code will use the "wallets" subdirectory only - // if it already exists, but never create it itself. There is discussion - // in https://github.com/bitcoin/bitcoin/issues/16220 about ways to - // change wallet code so it would no longer be necessary to create - // "wallets" subdirectories here. - fs::create_directories(base_path / "wallets"); + fs::create_directories(base_path); } const auto net_path{args.GetDataDirNet()}; if (!fs::exists(net_path)) { - fs::create_directories(net_path / "wallets"); + fs::create_directories(net_path); } // Show an error or warning if there is a bitcoin.conf file in the diff --git a/src/init.cpp b/src/init.cpp index 6dd3d5970bf885..49e6291bcb2173 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1141,6 +1141,13 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) g_wallet_init_interface.Construct(node); uiInterface.InitWallet(); + // Initialize wallet directory + bilingual_str error; + g_wallet_init_interface.InitWalletDir(node, error); + if (!error.empty()) { + return InitError(error); + } + /* Register RPC commands regardless of -server setting so they will be * available in the GUI RPC console even if external calls are disabled. */ diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 0d0a8650ac0c92..0d8948b1ebfeb4 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -40,6 +40,9 @@ class WalletInit : public WalletInitInterface //! Add wallets that should be opened to list of chain clients. void Construct(NodeContext& node) const override; + + //! Initialize wallet directory + void InitWalletDir(NodeContext& node, bilingual_str& error) const override; }; void WalletInit::AddWalletOptions(ArgsManager& argsman) const @@ -136,6 +139,30 @@ void WalletInit::Construct(NodeContext& node) const node.wallet_loader = wallet_loader.get(); node.chain_clients.emplace_back(std::move(wallet_loader)); } + +void WalletInit::InitWalletDir(NodeContext& node, bilingual_str& error) const +{ + ArgsManager& args = *Assert(node.args); + + fs::path path; + + if (args.IsArgSet("-walletdir")) { + path = args.GetPathArg("-walletdir"); + if (!fs::is_directory(path)) { + error = strprintf(_("Could not find the -walletdir=%s provided"), fs::PathToString(path)); + } + } else { + path = args.GetDataDirNet(); + if (!fs::is_directory(path / "wallets")) { + std::vector db_paths = ListDatabases(path); + if (db_paths.empty()) { + fs::create_directories(path / "wallets"); + } else { + fs::create_symlink(path, path / "wallets"); + } + } + } +} } // namespace wallet const WalletInitInterface& g_wallet_init_interface = wallet::WalletInit(); diff --git a/src/walletinitinterface.h b/src/walletinitinterface.h index ce8b6cfd6ed7fd..d65b26a99a8632 100644 --- a/src/walletinitinterface.h +++ b/src/walletinitinterface.h @@ -21,6 +21,8 @@ class WalletInitInterface { virtual bool ParameterInteraction() const = 0; /** Add wallets that should be opened to list of chain clients. */ virtual void Construct(node::NodeContext& node) const = 0; + /** Initialize wallet directory */ + virtual void InitWalletDir(node::NodeContext& node, bilingual_str& error) const = 0; virtual ~WalletInitInterface() {} };