Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show All 27 Lines | |||||
#include <ui_interface.h> | #include <ui_interface.h> | ||||
#include <util/moneystr.h> | #include <util/moneystr.h> | ||||
#include <util/system.h> | #include <util/system.h> | ||||
#include <validation.h> | #include <validation.h> | ||||
#include <wallet/coincontrol.h> | #include <wallet/coincontrol.h> | ||||
#include <wallet/coinselection.h> | #include <wallet/coinselection.h> | ||||
#include <wallet/fees.h> | #include <wallet/fees.h> | ||||
#include <wallet/finaltx.h> | #include <wallet/finaltx.h> | ||||
#include <wallet/walletutil.h> | |||||
#include <boost/algorithm/string/replace.hpp> | #include <boost/algorithm/string/replace.hpp> | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <cassert> | #include <cassert> | ||||
#include <future> | #include <future> | ||||
static CCriticalSection cs_wallets; | static CCriticalSection cs_wallets; | ||||
▲ Show 20 Lines • Show All 4,238 Lines • ▼ Show 20 Lines | for (const auto &address : mapAddressBook) { | ||||
if (!data.first.compare(0, prefix.size(), prefix)) { | if (!data.first.compare(0, prefix.size(), prefix)) { | ||||
values.emplace_back(data.second); | values.emplace_back(data.second); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return values; | return values; | ||||
} | } | ||||
bool CWallet::Verify(const CChainParams &chainParams, std::string wallet_file, | bool CWallet::Verify(const CChainParams &chainParams, | ||||
bool salvage_wallet, std::string &error_string, | const WalletLocation &location, bool salvage_wallet, | ||||
std::string &warning_string) { | std::string &error_string, std::string &warning_string) { | ||||
// Do some checking on wallet path. It should be either a: | // Do some checking on wallet path. It should be either a: | ||||
// | // | ||||
// 1. Path where a directory can be created. | // 1. Path where a directory can be created. | ||||
// 2. Path to an existing directory. | // 2. Path to an existing directory. | ||||
// 3. Path to a symlink to a directory. | // 3. Path to a symlink to a directory. | ||||
// 4. For backwards compatibility, the name of a data file in -walletdir. | // 4. For backwards compatibility, the name of a data file in -walletdir. | ||||
LOCK(cs_wallets); | LOCK(cs_wallets); | ||||
fs::path wallet_path = fs::absolute(wallet_file, GetWalletDir()); | const fs::path &wallet_path = location.GetPath(); | ||||
fs::file_type path_type = fs::symlink_status(wallet_path).type(); | fs::file_type path_type = fs::symlink_status(wallet_path).type(); | ||||
if (!(path_type == fs::file_not_found || path_type == fs::directory_file || | 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::symlink_file && fs::is_directory(wallet_path)) || | ||||
(path_type == fs::regular_file && | (path_type == fs::regular_file && | ||||
fs::path(wallet_file).filename() == wallet_file))) { | fs::path(location.GetName()).filename() == location.GetName()))) { | ||||
error_string = | error_string = | ||||
strprintf("Invalid -wallet path '%s'. -wallet path should point to " | strprintf("Invalid -wallet path '%s'. -wallet path should point to " | ||||
"a directory where wallet.dat and " | "a directory where wallet.dat and " | ||||
"database/log.?????????? files can be stored, a location " | "database/log.?????????? files can be stored, a location " | ||||
"where such a directory could be created, " | "where such a directory could be created, " | ||||
"or (for backwards compatibility) the name of an " | "or (for backwards compatibility) the name of an " | ||||
"existing data file in -walletdir (%s)", | "existing data file in -walletdir (%s)", | ||||
wallet_file, GetWalletDir()); | location.GetName(), GetWalletDir()); | ||||
return false; | return false; | ||||
} | } | ||||
// Make sure that the wallet path doesn't clash with an existing wallet path | // Make sure that the wallet path doesn't clash with an existing wallet path | ||||
for (auto wallet : GetWallets()) { | for (auto wallet : GetWallets()) { | ||||
if (fs::absolute(wallet->GetName(), GetWalletDir()) == wallet_path) { | if (wallet->GetLocation().GetPath() == wallet_path) { | ||||
error_string = strprintf("Error loading wallet %s. Duplicate " | error_string = strprintf("Error loading wallet %s. Duplicate " | ||||
"-wallet filename specified.", | "-wallet filename specified.", | ||||
wallet_file); | location.GetName()); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
try { | try { | ||||
if (!WalletBatch::VerifyEnvironment(wallet_path, error_string)) { | if (!WalletBatch::VerifyEnvironment(wallet_path, error_string)) { | ||||
return false; | return false; | ||||
} | } | ||||
} catch (const fs::filesystem_error &e) { | } catch (const fs::filesystem_error &e) { | ||||
error_string = | error_string = strprintf("Error loading wallet %s. %s", | ||||
strprintf("Error loading wallet %s. %s", wallet_file, e.what()); | location.GetName(), e.what()); | ||||
return false; | return false; | ||||
} | } | ||||
if (salvage_wallet) { | if (salvage_wallet) { | ||||
// Recover readable keypairs: | // Recover readable keypairs: | ||||
CWallet dummyWallet(chainParams, "dummy", | CWallet dummyWallet(chainParams, WalletLocation(), | ||||
WalletDatabase::CreateDummy()); | WalletDatabase::CreateDummy()); | ||||
std::string backup_filename; | std::string backup_filename; | ||||
if (!WalletBatch::Recover( | if (!WalletBatch::Recover( | ||||
wallet_path, static_cast<void *>(&dummyWallet), | wallet_path, static_cast<void *>(&dummyWallet), | ||||
WalletBatch::RecoverKeysOnlyFilter, backup_filename)) { | WalletBatch::RecoverKeysOnlyFilter, backup_filename)) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
Show All 19 Lines | for (auto it = setExternalKeyPool.begin(); | ||||
} | } | ||||
set_pre_split_keypool.insert(index); | set_pre_split_keypool.insert(index); | ||||
it = setExternalKeyPool.erase(it); | it = setExternalKeyPool.erase(it); | ||||
} | } | ||||
} | } | ||||
std::shared_ptr<CWallet> | std::shared_ptr<CWallet> | ||||
CWallet::CreateWalletFromFile(const CChainParams &chainParams, | CWallet::CreateWalletFromFile(const CChainParams &chainParams, | ||||
const std::string &name, const fs::path &path, | const WalletLocation &location, | ||||
uint64_t wallet_creation_flags) { | uint64_t wallet_creation_flags) { | ||||
const std::string &walletFile = name; | const std::string &walletFile = location.GetName(); | ||||
// Needed to restore wallet transaction meta data after -zapwallettxes | // Needed to restore wallet transaction meta data after -zapwallettxes | ||||
std::vector<CWalletTx> vWtx; | std::vector<CWalletTx> vWtx; | ||||
if (gArgs.GetBoolArg("-zapwallettxes", false)) { | if (gArgs.GetBoolArg("-zapwallettxes", false)) { | ||||
uiInterface.InitMessage(_("Zapping all transactions from wallet...")); | uiInterface.InitMessage(_("Zapping all transactions from wallet...")); | ||||
std::unique_ptr<CWallet> tempWallet = std::make_unique<CWallet>( | std::unique_ptr<CWallet> tempWallet = std::make_unique<CWallet>( | ||||
chainParams, name, WalletDatabase::Create(path)); | chainParams, location, WalletDatabase::Create(location.GetPath())); | ||||
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); | DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); | ||||
if (nZapWalletRet != DBErrors::LOAD_OK) { | if (nZapWalletRet != DBErrors::LOAD_OK) { | ||||
InitError( | InitError( | ||||
strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); | strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
} | } | ||||
uiInterface.InitMessage(_("Loading wallet...")); | uiInterface.InitMessage(_("Loading wallet...")); | ||||
int64_t nStart = GetTimeMillis(); | int64_t nStart = GetTimeMillis(); | ||||
bool fFirstRun = true; | bool fFirstRun = true; | ||||
// TODO: Can't use std::make_shared because we need a custom deleter but | // TODO: Can't use std::make_shared because we need a custom deleter but | ||||
// should be possible to use std::allocate_shared. | // should be possible to use std::allocate_shared. | ||||
std::shared_ptr<CWallet> walletInstance( | std::shared_ptr<CWallet> walletInstance( | ||||
new CWallet(chainParams, name, WalletDatabase::Create(path)), | new CWallet(chainParams, location, | ||||
WalletDatabase::Create(location.GetPath())), | |||||
ReleaseWallet); | ReleaseWallet); | ||||
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); | DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); | ||||
if (nLoadWalletRet != DBErrors::LOAD_OK) { | if (nLoadWalletRet != DBErrors::LOAD_OK) { | ||||
if (nLoadWalletRet == DBErrors::CORRUPT) { | if (nLoadWalletRet == DBErrors::CORRUPT) { | ||||
InitError( | InitError( | ||||
strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); | strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 487 Lines • Show Last 20 Lines |