diff options
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r-- | src/wallet/wallet.cpp | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 5be9f4a290..74f36e9abe 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -23,11 +23,11 @@ #include <primitives/block.h> #include <primitives/transaction.h> #include <script/script.h> -#include <scheduler.h> #include <timedata.h> #include <txmempool.h> #include <utilmoneystr.h> #include <wallet/fees.h> +#include <wallet/walletutil.h> #include <algorithm> #include <assert.h> @@ -3990,6 +3990,52 @@ void CWallet::MarkPreSplitKeys() } } +bool CWallet::Verify(std::string wallet_file, bool salvage_wallet, std::string& error_string, std::string& warning_string) +{ + // 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))) { + error_string = 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()); + return false; + } + + // 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) { + error_string = strprintf("Error loading wallet %s. Duplicate -wallet filename specified.", wallet_file); + return false; + } + } + + if (!WalletBatch::VerifyEnvironment(wallet_path, error_string)) { + return false; + } + + 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; + } + } + + return WalletBatch::VerifyDatabaseFile(wallet_path, warning_string, error_string); +} + CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& path) { const std::string& walletFile = name; @@ -4012,7 +4058,10 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& int64_t nStart = GetTimeMillis(); bool fFirstRun = true; - CWallet *walletInstance = new CWallet(name, WalletDatabase::Create(path)); + // Make a temporary wallet unique pointer so memory doesn't get leaked if + // wallet creation fails. + auto temp_wallet = MakeUnique<CWallet>(name, WalletDatabase::Create(path)); + CWallet* walletInstance = temp_wallet.get(); DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); if (nLoadWalletRet != DBErrors::LOAD_OK) { @@ -4224,7 +4273,6 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& } walletInstance->m_last_block_processed = chainActive.Tip(); - RegisterValidationInterface(walletInstance); if (chainActive.Tip() && chainActive.Tip() != pindexRescan) { @@ -4290,6 +4338,10 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& } } } + + // Register with the validation interface. It's ok to do this after rescan since we're still holding cs_main. + RegisterValidationInterface(temp_wallet.release()); + walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST)); { @@ -4302,18 +4354,11 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& return walletInstance; } -std::atomic<bool> CWallet::fFlushScheduled(false); - -void CWallet::postInitProcess(CScheduler& scheduler) +void CWallet::postInitProcess() { // Add wallet transactions that aren't already in a block to mempool // Do this here as mempool requires genesis block to be loaded ReacceptWalletTransactions(); - - // Run a thread to flush wallet periodically - if (!CWallet::fFlushScheduled.exchange(true)) { - scheduler.scheduleEvery(MaybeCompactWalletDB, 500); - } } bool CWallet::BackupWallet(const std::string& strDest) |