[wallet] Add CWallet::Verify function

This allows a single wallet to be verified. Prior to this commit, all
wallets were verified together by the WalletInit::Verify() function at
start-up.

Individual wallet verification will be done when loading wallets
dynamically at runtime.
This commit is contained in:
John Newbery
2018-04-18 13:11:28 -04:00
parent 470316c3bf
commit e0e90db07b
3 changed files with 70 additions and 42 deletions

View File

@@ -27,6 +27,7 @@
#include <txmempool.h>
#include <utilmoneystr.h>
#include <wallet/fees.h>
#include <wallet/walletutil.h>
#include <algorithm>
#include <assert.h>
@@ -3989,6 +3990,61 @@ void CWallet::MarkPreSplitKeys()
}
}
bool CWallet::Verify(std::string wallet_file, bool salvage_wallet)
{
// Do some checking on wallet path. It should be either a:
//
// 1. Path where a directory can be created.
// 2. Path to an existing directory.
// 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());
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))) {
return InitError(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()));
}
// 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) {
return InitError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), wallet_file));
}
}
std::string strError;
if (!WalletBatch::VerifyEnvironment(wallet_path, strError)) {
return InitError(strError);
}
if (salvage_wallet) {
// Recover readable keypairs:
CWallet dummyWallet("dummy", WalletDatabase::CreateDummy());
std::string backup_filename;
if (!WalletBatch::Recover(wallet_path, (void *)&dummyWallet, WalletBatch::RecoverKeysOnlyFilter, backup_filename)) {
return false;
}
}
std::string strWarning;
bool dbV = WalletBatch::VerifyDatabaseFile(wallet_path, strWarning, strError);
if (!strWarning.empty()) {
InitWarning(strWarning);
}
if (!dbV) {
InitError(strError);
return false;
}
return true;
}
CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& path)
{
const std::string& walletFile = name;