From 048fda2a66df405cd98706612c87b59c2912c441 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Tue, 20 Feb 2018 16:08:36 -0500 Subject: After encrypting the wallet, reload the database environment Calls ReloadDbEnv after encrypting the wallet so that the database environment is flushed, closed, and reopened to prevent unencrypted keys from being saved on disk. Github-Pull: #12493 Rebased-From: d7637c5 --- src/wallet/wallet.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/wallet/wallet.cpp') diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e86aa04d18..4bf2ec1e4e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -760,6 +760,11 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) // bits of the unencrypted private key in slack space in the database file. database->Rewrite(); + // BDB seems to have a bad habit of writing old data into + // slack space in .dat files; that is bad if the old data is + // unencrypted private keys. So: + database->ReloadDbEnv(); + } NotifyStatusChanged(this); -- cgit v1.2.3 From 16e57594556ac481a32f5d5ed1a988b2772ba804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Fri, 28 Sep 2018 16:50:18 +0100 Subject: wallet: Refactor to use WalletLocation Github-Pull: #14350 Rebased-From: 65f3672 --- src/wallet/wallet.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src/wallet/wallet.cpp') diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4bf2ec1e4e..fefa1ae02b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -4010,7 +4009,7 @@ void CWallet::MarkPreSplitKeys() } } -bool CWallet::Verify(std::string wallet_file, bool salvage_wallet, std::string& error_string, std::string& warning_string) +bool CWallet::Verify(const WalletLocation& location, bool salvage_wallet, std::string& error_string, std::string& warning_string) { // Do some checking on wallet path. It should be either a: // @@ -4019,23 +4018,23 @@ bool CWallet::Verify(std::string wallet_file, bool salvage_wallet, std::string& // 3. Path to a symlink to a directory. // 4. For backwards compatibility, the name of a data file in -walletdir. LOCK(cs_wallets); - fs::path wallet_path = fs::absolute(wallet_file, GetWalletDir()); + const fs::path& wallet_path = location.GetPath(); fs::file_type path_type = fs::symlink_status(wallet_path).type(); if (!(path_type == fs::file_not_found || path_type == fs::directory_file || (path_type == fs::symlink_file && fs::is_directory(wallet_path)) || - (path_type == fs::regular_file && fs::path(wallet_file).filename() == wallet_file))) { + (path_type == fs::regular_file && fs::path(location.GetName()).filename() == location.GetName()))) { error_string = strprintf( "Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and " "database/log.?????????? files can be stored, a location where such a directory could be created, " "or (for backwards compatibility) the name of an existing data file in -walletdir (%s)", - wallet_file, GetWalletDir()); + location.GetName(), GetWalletDir()); return false; } // Make sure that the wallet path doesn't clash with an existing wallet path for (auto wallet : GetWallets()) { - if (fs::absolute(wallet->GetName(), GetWalletDir()) == wallet_path) { - error_string = strprintf("Error loading wallet %s. Duplicate -wallet filename specified.", wallet_file); + if (wallet->GetLocation().GetPath() == wallet_path) { + error_string = strprintf("Error loading wallet %s. Duplicate -wallet filename specified.", location.GetName()); return false; } } @@ -4045,13 +4044,13 @@ bool CWallet::Verify(std::string wallet_file, bool salvage_wallet, std::string& return false; } } catch (const fs::filesystem_error& e) { - error_string = strprintf("Error loading wallet %s. %s", wallet_file, e.what()); + error_string = strprintf("Error loading wallet %s. %s", location.GetName(), e.what()); return false; } if (salvage_wallet) { // Recover readable keypairs: - CWallet dummyWallet("dummy", WalletDatabase::CreateDummy()); + CWallet dummyWallet(WalletLocation(), WalletDatabase::CreateDummy()); std::string backup_filename; if (!WalletBatch::Recover(wallet_path, (void *)&dummyWallet, WalletBatch::RecoverKeysOnlyFilter, backup_filename)) { return false; @@ -4061,9 +4060,9 @@ bool CWallet::Verify(std::string wallet_file, bool salvage_wallet, std::string& return WalletBatch::VerifyDatabaseFile(wallet_path, warning_string, error_string); } -std::shared_ptr CWallet::CreateWalletFromFile(const std::string& name, const fs::path& path, uint64_t wallet_creation_flags) +std::shared_ptr CWallet::CreateWalletFromFile(const WalletLocation& location, uint64_t wallet_creation_flags) { - const std::string& walletFile = name; + const std::string& walletFile = location.GetName(); // needed to restore wallet transaction meta data after -zapwallettxes std::vector vWtx; @@ -4071,7 +4070,7 @@ std::shared_ptr CWallet::CreateWalletFromFile(const std::string& name, if (gArgs.GetBoolArg("-zapwallettxes", false)) { uiInterface.InitMessage(_("Zapping all transactions from wallet...")); - std::unique_ptr tempWallet = MakeUnique(name, WalletDatabase::Create(path)); + std::unique_ptr tempWallet = MakeUnique(location, WalletDatabase::Create(location.GetPath())); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DBErrors::LOAD_OK) { InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); @@ -4085,7 +4084,7 @@ std::shared_ptr CWallet::CreateWalletFromFile(const std::string& name, bool fFirstRun = true; // 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(name, WalletDatabase::Create(path)), ReleaseWallet); + std::shared_ptr walletInstance(new CWallet(location, WalletDatabase::Create(location.GetPath())), ReleaseWallet); DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); if (nLoadWalletRet != DBErrors::LOAD_OK) { -- cgit v1.2.3 From caf1146b1345d70fbe4cc5f662d8393a79ac6068 Mon Sep 17 00:00:00 2001 From: Chun Kuan Lee Date: Tue, 23 Oct 2018 13:26:27 +0800 Subject: wallet: Add trailing wallet.dat when detecting duplicate wallet if it's a directory. Github-Pull: #14552 Rebased-From: 15c93f0 --- src/wallet/wallet.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/wallet/wallet.cpp') diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index fefa1ae02b..e9fff5443b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4032,11 +4032,9 @@ bool CWallet::Verify(const WalletLocation& location, bool salvage_wallet, std::s } // Make sure that the wallet path doesn't clash with an existing wallet path - for (auto wallet : GetWallets()) { - if (wallet->GetLocation().GetPath() == wallet_path) { - error_string = strprintf("Error loading wallet %s. Duplicate -wallet filename specified.", location.GetName()); - return false; - } + if (IsWalletLoaded(wallet_path)) { + error_string = strprintf("Error loading wallet %s. Duplicate -wallet filename specified.", location.GetName()); + return false; } try { -- cgit v1.2.3 From f22d02f5371efcaa48a8d5d1b8cd31c65d8235f3 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Fri, 18 May 2018 16:28:50 -0400 Subject: Free BerkeleyEnvironment instances when not in use Instead of adding BerkeleyEnvironment objects permanently to the g_dbenvs map, use reference counted shared pointers and remove map entries when the last BerkeleyEnvironment reference goes out of scope. This change was requested by Matt Corallo and makes code that sets up mock databases cleaner. The mock database environment will now go out of scope and be reset on destruction so there is no need to call BerkeleyEnvironment::Reset() during wallet construction to clear out prior state. This change does affect bitcoin behavior slightly. On startup, instead of same wallet environments staying open throughout VerifyWallets() and OpenWallets() calls, VerifyWallets() will open and close an environment once for each wallet, and OpenWallets() will create its own environment(s) later. Github-Pull: #11911 Rebased-From: f1f4bb7 --- src/wallet/wallet.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/wallet/wallet.cpp') diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index e9fff5443b..8d52f7eeca 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4037,6 +4037,9 @@ bool CWallet::Verify(const WalletLocation& location, bool salvage_wallet, std::s return false; } + // Keep same database environment instance across Verify/Recover calls below. + std::unique_ptr database = WalletDatabase::Create(wallet_path); + try { if (!WalletBatch::VerifyEnvironment(wallet_path, error_string)) { return false; -- cgit v1.2.3