Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 221 Lines • ▼ Show 20 Lines | |||||
namespace { | namespace { | ||||
std::shared_ptr<CWallet> | std::shared_ptr<CWallet> | ||||
LoadWalletInternal(interfaces::Chain &chain, const std::string &name, | LoadWalletInternal(interfaces::Chain &chain, const std::string &name, | ||||
std::optional<bool> load_on_start, | std::optional<bool> load_on_start, | ||||
const DatabaseOptions &options, DatabaseStatus &status, | const DatabaseOptions &options, DatabaseStatus &status, | ||||
bilingual_str &error, std::vector<bilingual_str> &warnings) { | bilingual_str &error, std::vector<bilingual_str> &warnings) { | ||||
try { | try { | ||||
if (!CWallet::Verify(chain, name, error, warnings)) { | if (!MakeWalletDatabase(name, options, status, error)) { | ||||
error = Untranslated("Wallet file verification failed.") + | error = Untranslated("Wallet file verification failed.") + | ||||
Untranslated(" ") + error; | Untranslated(" ") + error; | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
std::shared_ptr<CWallet> wallet = | std::shared_ptr<CWallet> wallet = | ||||
CWallet::CreateWalletFromFile(chain, name, error, warnings); | CWallet::CreateWalletFromFile(chain, name, error, warnings); | ||||
if (!wallet) { | if (!wallet) { | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | if (fs::symlink_status( | ||||
.type() != fs::file_not_found) { | .type() != fs::file_not_found) { | ||||
error = strprintf(Untranslated("Wallet %s already exists."), name); | error = strprintf(Untranslated("Wallet %s already exists."), name); | ||||
status = DatabaseStatus::FAILED_CREATE; | status = DatabaseStatus::FAILED_CREATE; | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
// Wallet::Verify will check if we're trying to create a wallet with a | // Wallet::Verify will check if we're trying to create a wallet with a | ||||
// duplicate name. | // duplicate name. | ||||
if (!CWallet::Verify(chain, name, error, warnings)) { | if (!MakeWalletDatabase(name, options, status, error)) { | ||||
error = Untranslated("Wallet file verification failed.") + | error = Untranslated("Wallet file verification failed.") + | ||||
Untranslated(" ") + error; | Untranslated(" ") + error; | ||||
status = DatabaseStatus::FAILED_VERIFY; | status = DatabaseStatus::FAILED_VERIFY; | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
// Do not allow a passphrase when private keys are disabled | // Do not allow a passphrase when private keys are disabled | ||||
if (!passphrase.empty() && | if (!passphrase.empty() && | ||||
▲ Show 20 Lines • Show All 3,898 Lines • ▼ Show 20 Lines | for (const auto &address : m_address_book) { | ||||
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(interfaces::Chain &chain, const std::string &name, | std::unique_ptr<WalletDatabase> | ||||
bilingual_str &error_string, | MakeWalletDatabase(const std::string &name, const DatabaseOptions &options, | ||||
std::vector<bilingual_str> &warnings) { | DatabaseStatus &status, bilingual_str &error_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); | |||||
const fs::path &wallet_path = fs::absolute(name, GetWalletDir()); | const fs::path &wallet_path = fs::absolute(name, GetWalletDir()); | ||||
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(name).filename() == name))) { | fs::path(name).filename() == name))) { | ||||
error_string = Untranslated( | error_string = Untranslated( | ||||
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)", | ||||
name, GetWalletDir())); | name, GetWalletDir())); | ||||
return false; | status = DatabaseStatus::FAILED_BAD_PATH; | ||||
} | return nullptr; | ||||
// Make sure that the wallet path doesn't clash with an existing wallet path | |||||
if (IsWalletLoaded(wallet_path)) { | |||||
error_string = Untranslated(strprintf( | |||||
"Error loading wallet %s. Duplicate -wallet filename specified.", | |||||
name)); | |||||
return false; | |||||
} | |||||
// Keep same database environment instance across Verify/Recover calls | |||||
// below. | |||||
std::unique_ptr<WalletDatabase> database = | |||||
CreateWalletDatabase(wallet_path); | |||||
try { | |||||
return database->Verify(error_string); | |||||
} catch (const fs::filesystem_error &e) { | |||||
error_string = | |||||
Untranslated(strprintf("Error loading wallet %s. %s", name, | |||||
fsbridge::get_filesystem_error_message(e))); | |||||
return false; | |||||
} | } | ||||
return MakeDatabase(wallet_path, options, status, error_string); | |||||
} | } | ||||
std::shared_ptr<CWallet> CWallet::CreateWalletFromFile( | std::shared_ptr<CWallet> CWallet::CreateWalletFromFile( | ||||
interfaces::Chain &chain, const std::string &name, bilingual_str &error, | interfaces::Chain &chain, const std::string &name, bilingual_str &error, | ||||
std::vector<bilingual_str> &warnings, uint64_t wallet_creation_flags) { | std::vector<bilingual_str> &warnings, uint64_t wallet_creation_flags) { | ||||
fs::path path = fs::absolute(name, GetWalletDir()); | fs::path path = fs::absolute(name, GetWalletDir()); | ||||
const std::string walletFile = WalletDataFilePath(path).string(); | const std::string walletFile = WalletDataFilePath(path).string(); | ||||
▲ Show 20 Lines • Show All 839 Lines • Show Last 20 Lines |