diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -157,6 +157,11 @@ /** Verifies the environment and database file */ bool Verify(bilingual_str &error); + /** Return path to main database filename */ + std::string Filename() override { + return (env->Directory() / strFile).string(); + } + /** * Pointer to shared database environment. * diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -390,7 +390,6 @@ "BerkeleyDatabase: Error %d, can't open database %s", ret, strFile)); } - m_file_path = (env->Directory() / strFile).string(); // Call CheckUniqueFileid on the containing BDB environment to // avoid BDB data consistency bugs that happen when different data diff --git a/src/wallet/db.h b/src/wallet/db.h --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -17,11 +17,6 @@ struct bilingual_str; -/** - * Given a wallet directory path or legacy file path, return path to main data - * file in the wallet database. - */ -fs::path WalletDataFilePath(const fs::path &wallet_path); void SplitWalletPath(const fs::path &wallet_path, fs::path &env_directory, std::string &database_filename); @@ -155,13 +150,14 @@ virtual void ReloadDbEnv() = 0; + /** Return path to main database file for logs and error messages. */ + virtual std::string Filename() = 0; + std::atomic nUpdateCounter; unsigned int nLastSeen; unsigned int nLastFlushed; int64_t nLastWalletUpdate; - std::string m_file_path; - /** Make a DatabaseBatch connected to this database */ virtual std::unique_ptr MakeBatch(const char *mode = "r+", bool flush_on_close = true) = 0; @@ -211,6 +207,7 @@ bool PeriodicFlush() override { return true; } void IncrementUpdateCounter() override { ++nUpdateCounter; } void ReloadDbEnv() override {} + std::string Filename() override { return "dummy"; } std::unique_ptr MakeBatch(const char *mode = "r+", bool flush_on_close = true) override { return std::make_unique(); diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -23,10 +23,3 @@ database_filename = "wallet.dat"; } } - -fs::path WalletDataFilePath(const fs::path &wallet_path) { - fs::path env_directory; - std::string database_filename; - SplitWalletPath(wallet_path, env_directory, database_filename); - return env_directory / database_filename; -} diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp --- a/src/wallet/load.cpp +++ b/src/wallet/load.cpp @@ -78,11 +78,21 @@ bool LoadWallets(interfaces::Chain &chain, const std::vector &wallet_files) { try { - for (const std::string &walletFile : wallet_files) { + for (const std::string &name : wallet_files) { + DatabaseOptions options; + DatabaseStatus status; + // No need to verify, assuming verified earlier in VerifyWallets() + options.verify = false; bilingual_str error; std::vector warnings; - std::shared_ptr pwallet = CWallet::CreateWalletFromFile( - chain, walletFile, error, warnings); + std::unique_ptr database = + MakeWalletDatabase(name, options, status, error); + std::shared_ptr pwallet = + database + ? CWallet::Create(chain, name, std::move(database), + options.create_flags, error, warnings) + : nullptr; + if (!warnings.empty()) { chain.initWarning(Join(warnings, Untranslated("\n"))); } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -32,9 +32,13 @@ BOOST_FIXTURE_TEST_SUITE(wallet_tests, WalletTestingSetup) static std::shared_ptr TestLoadWallet(interfaces::Chain &chain) { + DatabaseOptions options; + DatabaseStatus status; bilingual_str error; std::vector warnings; - auto wallet = CWallet::CreateWalletFromFile(chain, "", error, warnings); + auto database = MakeWalletDatabase("", options, status, error); + auto wallet = CWallet::Create(chain, "", std::move(database), + options.create_flags, error, warnings); wallet->postInitProcess(); return wallet; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1386,10 +1386,10 @@ * in case of an error. */ static std::shared_ptr - CreateWalletFromFile(interfaces::Chain &chain, const std::string &name, - bilingual_str &error, - std::vector &warnings, - uint64_t wallet_creation_flags = 0); + Create(interfaces::Chain &chain, const std::string &name, + std::unique_ptr database, + uint64_t wallet_creation_flags, bilingual_str &error, + std::vector &warnings); /** * Wallet post-init setup diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -227,14 +227,17 @@ const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error, std::vector &warnings) { try { - if (!MakeWalletDatabase(name, options, status, error)) { + std::unique_ptr database = + MakeWalletDatabase(name, options, status, error); + if (!database) { error = Untranslated("Wallet file verification failed.") + Untranslated(" ") + error; return nullptr; } std::shared_ptr wallet = - CWallet::CreateWalletFromFile(chain, name, error, warnings); + CWallet::Create(chain, name, std::move(database), + options.create_flags, error, warnings); if (!wallet) { error = Untranslated("Wallet loading failed.") + Untranslated(" ") + error; @@ -299,7 +302,9 @@ // Wallet::Verify will check if we're trying to create a wallet with a // duplicate name. - if (!MakeWalletDatabase(name, options, status, error)) { + std::unique_ptr database = + MakeWalletDatabase(name, options, status, error); + if (!database) { error = Untranslated("Wallet file verification failed.") + Untranslated(" ") + error; status = DatabaseStatus::FAILED_VERIFY; @@ -318,8 +323,9 @@ } // Make the wallet - std::shared_ptr wallet = CWallet::CreateWalletFromFile( - chain, name, error, warnings, wallet_creation_flags); + std::shared_ptr wallet = + CWallet::Create(chain, name, std::move(database), wallet_creation_flags, + error, warnings); if (!wallet) { error = Untranslated("Wallet creation failed.") + Untranslated(" ") + error; @@ -4243,11 +4249,12 @@ return MakeDatabase(wallet_path, options, status, error_string); } -std::shared_ptr CWallet::CreateWalletFromFile( - interfaces::Chain &chain, const std::string &name, bilingual_str &error, - std::vector &warnings, uint64_t wallet_creation_flags) { - fs::path path = fs::absolute(name, GetWalletDir()); - const std::string walletFile = WalletDataFilePath(path).string(); +std::shared_ptr +CWallet::Create(interfaces::Chain &chain, const std::string &name, + std::unique_ptr database, + uint64_t wallet_creation_flags, bilingual_str &error, + std::vector &warnings) { + const std::string &walletFile = database->Filename(); chain.initMessage(_("Loading wallet...").translated); @@ -4256,7 +4263,7 @@ // TODO: Can't use std::make_shared because we need a custom deleter but // should be possible to use std::allocate_shared. std::shared_ptr walletInstance( - new CWallet(&chain, name, CreateWalletDatabase(path)), ReleaseWallet); + new CWallet(&chain, name, std::move(database)), ReleaseWallet); DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); if (nLoadWalletRet != DBErrors::LOAD_OK) { if (nLoadWalletRet == DBErrors::CORRUPT) {