mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
[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:
parent
470316c3bf
commit
e0e90db07b
@ -190,55 +190,24 @@ bool WalletInit::Verify() const
|
||||
|
||||
uiInterface.InitMessage(_("Verifying wallet(s)..."));
|
||||
|
||||
std::vector<std::string> wallet_files = gArgs.GetArgs("-wallet");
|
||||
|
||||
// Parameter interaction code should have thrown an error if -salvagewallet
|
||||
// was enabled with more than wallet file, so the wallet_files size check
|
||||
// here should have no effect.
|
||||
bool salvage_wallet = gArgs.GetBoolArg("-salvagewallet", false) && wallet_files.size() <= 1;
|
||||
|
||||
// Keep track of each wallet absolute path to detect duplicates.
|
||||
std::set<fs::path> wallet_paths;
|
||||
|
||||
for (const std::string& walletFile : gArgs.GetArgs("-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.
|
||||
fs::path wallet_path = fs::absolute(walletFile, 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(walletFile).filename() == walletFile))) {
|
||||
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)"),
|
||||
walletFile, GetWalletDir()));
|
||||
}
|
||||
for (const auto wallet_file : wallet_files) {
|
||||
fs::path wallet_path = fs::absolute(wallet_file, GetWalletDir());
|
||||
|
||||
if (!wallet_paths.insert(wallet_path).second) {
|
||||
return InitError(strprintf(_("Error loading wallet %s. Duplicate -wallet filename specified."), walletFile));
|
||||
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 (gArgs.GetBoolArg("-salvagewallet", false)) {
|
||||
// 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;
|
||||
}
|
||||
if (!CWallet::Verify(wallet_file, salvage_wallet)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -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;
|
||||
|
@ -1118,6 +1118,9 @@ public:
|
||||
/** Mark a transaction as replaced by another transaction (e.g., BIP 125). */
|
||||
bool MarkReplaced(const uint256& originalHash, const uint256& newHash);
|
||||
|
||||
//! Verify wallet naming and perform salvage on the wallet if required
|
||||
static bool Verify(std::string wallet_file, bool salvage_wallet);
|
||||
|
||||
/* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */
|
||||
static CWallet* CreateWalletFromFile(const std::string& name, const fs::path& path);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user