wallet: Add trailing wallet.dat when detecting duplicate wallet if it's a directory.

Github-Pull: #14552
Rebased-From: 15c93f0
This commit is contained in:
Chun Kuan Lee 2018-10-23 13:26:27 +08:00 committed by João Barbosa
parent 34da2b7c76
commit caf1146b13
4 changed files with 28 additions and 7 deletions

View file

@ -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,

View file

@ -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);

View file

@ -4032,12 +4032,10 @@ 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) {
if (IsWalletLoaded(wallet_path)) {
error_string = strprintf("Error loading wallet %s. Duplicate -wallet filename specified.", location.GetName());
return false;
}
}
try {
if (!WalletBatch::VerifyEnvironment(wallet_path, error_string)) {

View file

@ -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')