Skip to content
Permalink
Browse files

wallet: Add trailing wallet.dat when detecting duplicate wallet if it…

…'s a directory.

Github-Pull: #14552
Rebased-From: 15c93f0
  • Loading branch information...
ken2812221 authored and promag committed Oct 23, 2018
1 parent 34da2b7 commit caf1146b1345d70fbe4cc5f662d8393a79ac6068
Showing with 28 additions and 7 deletions.
  1. +19 −2 src/wallet/db.cpp
  2. +3 −0 src/wallet/db.h
  3. +3 −5 src/wallet/wallet.cpp
  4. +3 −0 test/functional/wallet_multiwallet.py
@@ -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,
@@ -95,6 +95,9 @@ class BerkeleyEnvironment
}
};

/** 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);

@@ -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 {
@@ -217,6 +217,9 @@ def wallet_file(name):
# 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')

0 comments on commit caf1146

Please sign in to comment.
You can’t perform that action at this time.