aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChun Kuan Lee <ken2812221@gmail.com>2018-10-23 13:26:27 +0800
committerJoão Barbosa <joao.paulo.barbosa@gmail.com>2019-03-11 21:54:44 +0000
commitcaf1146b1345d70fbe4cc5f662d8393a79ac6068 (patch)
tree64e418a24f3c6354c6cbbbec591fc508b61f88db
parent34da2b7c76a023459e46e3a2ca4dc3ecc2b9a438 (diff)
downloadbitcoin-caf1146b1345d70fbe4cc5f662d8393a79ac6068.tar.xz
wallet: Add trailing wallet.dat when detecting duplicate wallet if it's a directory.
Github-Pull: #14552 Rebased-From: 15c93f0
-rw-r--r--src/wallet/db.cpp21
-rw-r--r--src/wallet/db.h3
-rw-r--r--src/wallet/wallet.cpp8
-rwxr-xr-xtest/functional/wallet_multiwallet.py3
4 files changed, 28 insertions, 7 deletions
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index b36a6de2a3..a0f0abd4a6 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -56,9 +56,8 @@ bool WalletDatabaseFileId::operator==(const WalletDatabaseFileId& rhs) const
return memcmp(value, &rhs.value, sizeof(value)) == 0;
}
-BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename)
+static void SplitWalletPath(const fs::path& wallet_path, fs::path& env_directory, std::string& database_filename)
{
- fs::path env_directory;
if (fs::is_regular_file(wallet_path)) {
// Special case for backwards compatibility: if wallet path points to an
// existing file, treat it as the path to a BDB data file in a parent
@@ -71,6 +70,24 @@ BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& data
env_directory = wallet_path;
database_filename = "wallet.dat";
}
+}
+
+bool IsWalletLoaded(const fs::path& wallet_path)
+{
+ fs::path env_directory;
+ std::string database_filename;
+ SplitWalletPath(wallet_path, env_directory, database_filename);
+ LOCK(cs_db);
+ auto env = g_dbenvs.find(env_directory.string());
+ if (env == g_dbenvs.end()) return false;
+ auto db = env->second.m_databases.find(database_filename);
+ return db != env->second.m_databases.end();
+}
+
+BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename)
+{
+ fs::path env_directory;
+ SplitWalletPath(wallet_path, env_directory, database_filename);
LOCK(cs_db);
// Note: An ununsed temporary BerkeleyEnvironment object may be created inside the
// emplace function if the key already exists. This is a little inefficient,
diff --git a/src/wallet/db.h b/src/wallet/db.h
index 68a59607ae..5ced4c59cf 100644
--- a/src/wallet/db.h
+++ b/src/wallet/db.h
@@ -95,6 +95,9 @@ public:
}
};
+/** Return whether a wallet database is currently loaded. */
+bool IsWalletLoaded(const fs::path& wallet_path);
+
/** Get BerkeleyEnvironment and database filename given a wallet path. */
BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename);
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 {
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index 6e0c109e60..bf33d3c628 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -217,6 +217,9 @@ class MultiWalletTest(BitcoinTestFramework):
# Fail to load duplicate wallets
assert_raises_rpc_error(-4, 'Wallet file verification failed: Error loading wallet w1. Duplicate -wallet filename specified.', self.nodes[0].loadwallet, wallet_names[0])
+ # Fail to load duplicate wallets by different ways (directory and filepath)
+ assert_raises_rpc_error(-4, "Wallet file verification failed: Error loading wallet wallet.dat. Duplicate -wallet filename specified.", self.nodes[0].loadwallet, 'wallet.dat')
+
# Fail to load if one wallet is a copy of another
assert_raises_rpc_error(-1, "BerkeleyBatch: Can't open database w8_copy (duplicates fileid", self.nodes[0].loadwallet, 'w8_copy')