From 0cd60899edccf275517955a56dc4c030cbe292ff Mon Sep 17 00:00:00 2001 From: furszy Date: Thu, 6 May 2021 22:49:37 -0300 Subject: [PATCH 1/7] Wallet: Cleanup AutoBackupWallet [Step 1] --- src/wallet/walletdb.cpp | 67 +++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index c164b5b81fb8..64d21a208a71 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -858,69 +858,56 @@ std::pair GetBackupPath(const CWallet& wallet) bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWarning, std::string& strBackupError) { strBackupWarning = strBackupError = ""; - - int nWalletBackups = gArgs.GetArg("-createwalletbackups", DEFAULT_CREATEWALLETBACKUPS); - nWalletBackups = std::max(0, std::min(10, nWalletBackups)); - + int nWalletBackups = std::max(0, std::min(10, (int)gArgs.GetArg("-createwalletbackups", DEFAULT_CREATEWALLETBACKUPS))); if (nWalletBackups == 0) { LogPrintf("Automatic wallet backups are disabled!\n"); return false; } fs::path backupsDir = GetDataDir() / "backups"; - if (!fs::exists(backupsDir)) { - // Always create backup folder to not confuse the operating system's file browser - LogPrintf("Creating backup folder %s\n", backupsDir.string()); - if(!fs::create_directories(backupsDir)) { - // smth is wrong, we shouldn't continue until it's resolved - strBackupError = strprintf(_("Wasn't able to create wallet backup folder %s!"), backupsDir.string()); - LogPrintf("%s\n", strBackupError); - nWalletBackups = -1; - return false; - } - } - // Create backup of the ... - std::string dateTimeStr = FormatISO8601DateTimeForBackup(GetTime()); + backupsDir.make_preferred(); + TryCreateDirectories(backupsDir); - // ... strWalletFile file + // Copy wallet file fs::path sourceFile = GetDataDir() / strWalletFile; - fs::path backupFile = backupsDir / (strWalletFile + dateTimeStr); + fs::path backupFile = backupsDir / (strWalletFile + FormatISO8601DateTimeForBackup(GetTime())); sourceFile.make_preferred(); backupFile.make_preferred(); if (fs::exists(backupFile)) { - strBackupWarning = _("Failed to create backup, file already exists! This could happen if you restarted wallet in less than 60 seconds. You can continue if you are ok with this."); + LogPrintf("%s\n", _("Failed to create backup, file already exists! This could happen if you restarted wallet in less than 60 seconds. You can continue if you are ok with this.")); + return false; + } + + if (!fs::exists(sourceFile)) { + strBackupWarning = _("Failed to create backup, wallet file not found"); LogPrintf("%s\n", strBackupWarning); return false; } - if(fs::exists(sourceFile)) { + #if BOOST_VERSION >= 105800 - try { - fs::copy_file(sourceFile, backupFile); - LogPrintf("Creating backup of %s -> %s\n", sourceFile.string(), backupFile.string()); - } catch(fs::filesystem_error &error) { - strBackupWarning = strprintf(_("Failed to create backup, error: %s"), error.what()); - LogPrintf("%s\n", strBackupWarning); - nWalletBackups = -1; - return false; - } + try { + fs::copy_file(sourceFile, backupFile); + LogPrintf("Creating backup of %s -> %s\n", sourceFile.string(), backupFile.string()); + } catch(fs::filesystem_error &error) { + strBackupWarning = strprintf(_("Failed to create backup, error: %s"), error.what()); + LogPrintf("%s\n", strBackupWarning); + nWalletBackups = -1; + return false; + } #else - std::ifstream src(sourceFile.string(), std::ios::binary); - std::ofstream dst(backupFile.string(), std::ios::binary); - dst << src.rdbuf(); + std::ifstream src(sourceFile.string(), std::ios::binary); + std::ofstream dst(backupFile.string(), std::ios::binary); + dst << src.rdbuf(); #endif - } // Keep only the last 10 backups, including the new one of course typedef std::multimap folder_set_t; folder_set_t folder_set; fs::directory_iterator end_iter; - backupsDir.make_preferred(); // Build map of backup files for current(!) wallet sorted by last write time - fs::path currentFile; for (fs::directory_iterator dir_iter(backupsDir); dir_iter != end_iter; ++dir_iter) { // Only check regular files - if ( fs::is_regular_file(dir_iter->status())) { - currentFile = dir_iter->path().filename(); + if (fs::is_regular_file(dir_iter->status())) { // Only add the backups for the current wallet, e.g. wallet.dat.* if(dir_iter->path().stem().string() == strWalletFile) { folder_set.insert(folder_set_t::value_type(fs::last_write_time(dir_iter->path()), *dir_iter)); @@ -929,14 +916,14 @@ bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWa } // Loop backward through backup files and keep the N newest ones (1 <= N <= 10) int counter = 0; - for (std::pair file : reverse_iterate(folder_set)) { + for (const std::pair& file : reverse_iterate(folder_set)) { counter++; if (counter > nWalletBackups) { // More than nWalletBackups backups: delete oldest one(s) try { fs::remove(file.second); LogPrintf("Old backup deleted: %s\n", file.second); - } catch(fs::filesystem_error &error) { + } catch (fs::filesystem_error &error) { strBackupWarning = strprintf(_("Failed to delete backup, error: %s"), error.what()); LogPrintf("%s\n", strBackupWarning); return false; From 2e2d4677159076d5793eb7e7155226d30fdf0309 Mon Sep 17 00:00:00 2001 From: furszy Date: Thu, 6 May 2021 22:56:00 -0300 Subject: [PATCH 2/7] Wallet: unify wallet backup functions --- src/wallet/walletdb.cpp | 27 ++++++++------------------- src/wallet/walletdb.h | 4 +++- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 64d21a208a71..417b2e3392b4 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -884,21 +884,10 @@ bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWa return false; } -#if BOOST_VERSION >= 105800 - try { - fs::copy_file(sourceFile, backupFile); - LogPrintf("Creating backup of %s -> %s\n", sourceFile.string(), backupFile.string()); - } catch(fs::filesystem_error &error) { - strBackupWarning = strprintf(_("Failed to create backup, error: %s"), error.what()); - LogPrintf("%s\n", strBackupWarning); - nWalletBackups = -1; - return false; + // Try to backup + if (!AttemptBackupWallet(nullptr, sourceFile, backupFile)) { + return false; // error is logged internally } -#else - std::ifstream src(sourceFile.string(), std::ios::binary); - std::ofstream dst(backupFile.string(), std::ios::binary); - dst << src.rdbuf(); -#endif // Keep only the last 10 backups, including the new one of course typedef std::multimap folder_set_t; @@ -985,7 +974,7 @@ void MultiBackup(const CWallet& wallet, fs::path pathCustom, fs::path pathWithFi } } } - AttemptBackupWallet(wallet, pathSrc.string(), pathWithFile.string()); + AttemptBackupWallet(&wallet, pathSrc.string(), pathWithFile.string()); } bool BackupWallet(const CWallet& wallet, const fs::path& strDest) @@ -1011,7 +1000,7 @@ bool BackupWallet(const CWallet& wallet, const fs::path& strDest) if(!exists(pathDest)) create_directory(pathDest); pathDest /= strFile; } - bool defaultPath = AttemptBackupWallet(wallet, pathSrc.string(), pathDest.string()); + bool defaultPath = AttemptBackupWallet(&wallet, pathSrc.string(), pathDest.string()); if(defaultPath && !pathCustom.empty()) { MultiBackup(wallet, pathCustom, pathWithFile, pathSrc); @@ -1025,7 +1014,7 @@ bool BackupWallet(const CWallet& wallet, const fs::path& strDest) return false; } -bool AttemptBackupWallet(const CWallet& wallet, const fs::path& pathSrc, const fs::path& pathDest) +bool AttemptBackupWallet(const CWallet* wallet, const fs::path& pathSrc, const fs::path& pathDest) { bool retStatus; std::string strMessage; @@ -1046,7 +1035,7 @@ bool AttemptBackupWallet(const CWallet& wallet, const fs::path& pathSrc, const f src.close(); dst.close(); #endif - strMessage = strprintf("copied %s to %s\n", wallet.GetDBHandle().GetName(), pathDest.string()); + strMessage = strprintf("copied %s to %s\n", pathSrc.string(), pathDest.string()); LogPrintf("%s : %s\n", __func__, strMessage); retStatus = true; } catch (const fs::filesystem_error& e) { @@ -1054,7 +1043,7 @@ bool AttemptBackupWallet(const CWallet& wallet, const fs::path& pathSrc, const f strMessage = strprintf("%s\n", e.what()); LogPrintf("%s : %s\n", __func__, strMessage); } - NotifyBacked(wallet, retStatus, strMessage); + if (wallet) NotifyBacked(*wallet, retStatus, strMessage); return retStatus; } diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 281bba204508..e4dc58c8a774 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -239,7 +239,9 @@ class CWalletDB void NotifyBacked(const CWallet& wallet, bool fSuccess, std::string strMessage); bool BackupWallet(const CWallet& wallet, const fs::path& strDest); -bool AttemptBackupWallet(const CWallet& wallet, const fs::path& pathSrc, const fs::path& pathDest); +// If wallet is null, the NotifyBacked signal will not be broadcasted. +// todo: move NotifyBacked() signal to the caller side and/or decouple it from here in another function +bool AttemptBackupWallet(const CWallet* wallet, const fs::path& pathSrc, const fs::path& pathDest); //! Called during init: Automatic backups of wallet not running (just copying and renaming dat file) bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWarning, std::string& strBackupError); From 10ce5760684b5bf8c33d22ccbdf1944b0bedb3f3 Mon Sep 17 00:00:00 2001 From: furszy Date: Thu, 6 May 2021 23:24:49 -0300 Subject: [PATCH 3/7] Walletdb: unify sort backups file by last write. --- src/wallet/walletdb.cpp | 54 +++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 417b2e3392b4..df7cff0c6c09 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -855,6 +855,24 @@ std::pair GetBackupPath(const CWallet& wallet) return {pathCustom, pathWithFile}; } +typedef std::multimap folder_set_t; +static folder_set_t buildBackupsMapSortedByLastWrite(const std::string& strWalletFile, const fs::path& backupsDir) +{ + folder_set_t folder_set; + fs::directory_iterator end_iter; + // Build map of backup files for current(!) wallet sorted by last write time + for (fs::directory_iterator dir_iter(backupsDir); dir_iter != end_iter; ++dir_iter) { + // Only check regular files + if (fs::is_regular_file(dir_iter->status())) { + // Only add the backups for the current wallet, e.g. wallet.dat.* + if(dir_iter->path().stem().string() == strWalletFile) { + folder_set.insert(folder_set_t::value_type(fs::last_write_time(dir_iter->path()), *dir_iter)); + } + } + } + return folder_set; +} + bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWarning, std::string& strBackupError) { strBackupWarning = strBackupError = ""; @@ -889,20 +907,9 @@ bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWa return false; // error is logged internally } - // Keep only the last 10 backups, including the new one of course - typedef std::multimap folder_set_t; - folder_set_t folder_set; - fs::directory_iterator end_iter; - // Build map of backup files for current(!) wallet sorted by last write time - for (fs::directory_iterator dir_iter(backupsDir); dir_iter != end_iter; ++dir_iter) { - // Only check regular files - if (fs::is_regular_file(dir_iter->status())) { - // Only add the backups for the current wallet, e.g. wallet.dat.* - if(dir_iter->path().stem().string() == strWalletFile) { - folder_set.insert(folder_set_t::value_type(fs::last_write_time(dir_iter->path()), *dir_iter)); - } - } - } + // Keep only 0 < nWalletBackups <= 10 backups, including the new one of course + folder_set_t folder_set = buildBackupsMapSortedByLastWrite(strWalletFile, backupsDir); + // Loop backward through backup files and keep the N newest ones (1 <= N <= 10) int counter = 0; for (const std::pair& file : reverse_iterate(folder_set)) { @@ -926,25 +933,8 @@ void MultiBackup(const CWallet& wallet, fs::path pathCustom, fs::path pathWithFi { int nThreshold = gArgs.GetArg("-custombackupthreshold", DEFAULT_CUSTOMBACKUPTHRESHOLD); if (nThreshold > 0) { - - typedef std::multimap folder_set_t; - folder_set_t folderSet; - fs::directory_iterator end_iter; - pathCustom.make_preferred(); - // Build map of backup files for current(!) wallet sorted by last write time - - fs::path currentFile; - for (fs::directory_iterator dir_iter(pathCustom); dir_iter != end_iter; ++dir_iter) { - // Only check regular files - if (fs::is_regular_file(dir_iter->status())) { - currentFile = dir_iter->path().filename(); - // Only add the backups for the current wallet, e.g. wallet.dat.* - if (dir_iter->path().stem().string() == wallet.GetDBHandle().GetName()) { - folderSet.insert(folder_set_t::value_type(fs::last_write_time(dir_iter->path()), *dir_iter)); - } - } - } + folder_set_t folderSet = buildBackupsMapSortedByLastWrite(wallet.GetDBHandle().GetName(), pathCustom); int counter = 0; //TODO: add seconds to avoid naming conflicts for (auto entry : folderSet) { From 5fdc630a4c26bde70e9a5f7b6cbd662147d676f5 Mon Sep 17 00:00:00 2001 From: furszy Date: Thu, 6 May 2021 23:34:58 -0300 Subject: [PATCH 4/7] Walletdb: unify wallet backups cleanup. --- src/wallet/walletdb.cpp | 69 +++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 41 deletions(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index df7cff0c6c09..90e08db0bb99 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -873,6 +873,27 @@ static folder_set_t buildBackupsMapSortedByLastWrite(const std::string& strWalle return folder_set; } +static bool cleanWalletBackups(folder_set_t& folder_set, int nWalletBackups, std::string& strBackupWarning) +{ + // Loop backward through backup files and keep the N newest ones (1 <= N <= 10) + int counter = 0; + for (const std::pair& file : reverse_iterate(folder_set)) { + counter++; + if (counter > nWalletBackups) { + // More than nWalletBackups backups: delete oldest one(s) + try { + fs::remove(file.second); + LogPrintf("Old backup deleted: %s\n", file.second); + } catch (fs::filesystem_error &error) { + strBackupWarning = strprintf(_("Failed to delete backup, error: %s"), error.what()); + LogPrintf("%s\n", strBackupWarning); + return false; + } + } + } + return true; +} + bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWarning, std::string& strBackupError) { strBackupWarning = strBackupError = ""; @@ -909,60 +930,26 @@ bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWa // Keep only 0 < nWalletBackups <= 10 backups, including the new one of course folder_set_t folder_set = buildBackupsMapSortedByLastWrite(strWalletFile, backupsDir); - - // Loop backward through backup files and keep the N newest ones (1 <= N <= 10) - int counter = 0; - for (const std::pair& file : reverse_iterate(folder_set)) { - counter++; - if (counter > nWalletBackups) { - // More than nWalletBackups backups: delete oldest one(s) - try { - fs::remove(file.second); - LogPrintf("Old backup deleted: %s\n", file.second); - } catch (fs::filesystem_error &error) { - strBackupWarning = strprintf(_("Failed to delete backup, error: %s"), error.what()); - LogPrintf("%s\n", strBackupWarning); - return false; - } - } - } - return true; + return cleanWalletBackups(folder_set, nWalletBackups, strBackupWarning); } void MultiBackup(const CWallet& wallet, fs::path pathCustom, fs::path pathWithFile, const fs::path& pathSrc) { int nThreshold = gArgs.GetArg("-custombackupthreshold", DEFAULT_CUSTOMBACKUPTHRESHOLD); if (nThreshold > 0) { + std::string strBackupWarning; pathCustom.make_preferred(); folder_set_t folderSet = buildBackupsMapSortedByLastWrite(wallet.GetDBHandle().GetName(), pathCustom); + if (!cleanWalletBackups(folderSet, nThreshold, strBackupWarning)) { + NotifyBacked(wallet, false, strBackupWarning); + } - int counter = 0; //TODO: add seconds to avoid naming conflicts - for (auto entry : folderSet) { - counter++; + // TODO: add seconds to avoid naming conflicts + for (const auto& entry : folderSet) { if(entry.second == pathWithFile) { pathWithFile += "(1)"; } } - - if (counter >= nThreshold) { - std::time_t oldestBackup = 0; - for(auto entry : folderSet) { - if(oldestBackup == 0 || entry.first < oldestBackup) { - oldestBackup = entry.first; - } - } - - try { - auto entry = folderSet.find(oldestBackup); - if (entry != folderSet.end()) { - fs::remove(entry->second); - LogPrintf("Old backup deleted: %s\n", (*entry).second); - } - } catch (const fs::filesystem_error& error) { - std::string strMessage = strprintf("Failed to delete backup %s\n", error.what()); - NotifyBacked(wallet, false, strMessage); - } - } } AttemptBackupWallet(&wallet, pathSrc.string(), pathWithFile.string()); } From 2603353f52f578e2bc661420ed137f89e552a6c1 Mon Sep 17 00:00:00 2001 From: furszy Date: Mon, 17 May 2021 15:27:04 -0300 Subject: [PATCH 5/7] wallet: Create initial wallet backup after initialization. Plus fix "Failed to create backup..." error at startup when the wallet hasn't been created yet. --- src/wallet/init.cpp | 12 +++++++++++- src/wallet/wallet.cpp | 4 ++-- src/wallet/wallet.h | 2 +- src/wallet/walletdb.cpp | 4 ++-- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 98dc0417094b..867f5191814d 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -221,11 +221,21 @@ bool InitLoadWallet() } } - CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile); + bool fFirstRun; + CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile, fFirstRun); if (!pwallet) { return false; } vpwallets.emplace_back(pwallet); + + if (fFirstRun) { + // Initial backup + if (!AutoBackupWallet(walletFile, strWarning, strError)) { + LogPrintf("Initial auto-backup failed for wallet %s, error: %s, warning: %s\n", + pwallet->GetName(), (strError.empty() ? "no error" : strError), + (strWarning.empty() ? "no warning" : strWarning)); + } + } } return true; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3e084d7eda06..0a181ef3a260 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4079,7 +4079,7 @@ void CWallet::LockIfMyCollateral(const CTransactionRef& ptx) } } -CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) +CWallet* CWallet::CreateWalletFromFile(const std::string& walletFile, bool& fFirstRun) { // needed to restore wallet transaction meta data after -zapwallettxes std::vector vWtx; @@ -4103,7 +4103,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) fVerifyingBlocks = true; int64_t nStart = GetTimeMillis(); - bool fFirstRun = true; + fFirstRun = true; std::unique_ptr dbw(new CWalletDBWrapper(&bitdb, walletFile)); CWallet *walletInstance = new CWallet(std::move(dbw)); DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 3b354245dfd8..17e14ab08f14 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1155,7 +1155,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool AbandonTransaction(const uint256& hashTx); /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ - static CWallet* CreateWalletFromFile(const std::string walletFile); + static CWallet* CreateWalletFromFile(const std::string& walletFile, bool& fFirstRun); /** * Wallet post-init setup diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 90e08db0bb99..8ecf40f3e3f9 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -918,8 +918,8 @@ bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWa } if (!fs::exists(sourceFile)) { - strBackupWarning = _("Failed to create backup, wallet file not found"); - LogPrintf("%s\n", strBackupWarning); + // Do not warn here. This could happen if the wallet hasn't been created. + LogPrintf("%s\n", _("Cannot create wallet auto-backup, wallet file not found")); return false; } From e24cdd526bab66ac00db5bdf68e848a612b2e375 Mon Sep 17 00:00:00 2001 From: furszy Date: Tue, 18 May 2021 11:11:37 -0300 Subject: [PATCH 6/7] wallet: remove not longer available "-printcoinstake" init flag. --- src/wallet/init.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 867f5191814d..6aa959c7462a 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -44,7 +44,6 @@ std::string GetWalletHelpString(bool showDebug) strUsage += HelpMessageGroup(_("Wallet debugging/testing options:")); strUsage += HelpMessageOpt("-dblogsize=", strprintf(_("Flush database activity from memory pool to disk log every megabytes (default: %u)"), DEFAULT_WALLET_DBLOGSIZE)); strUsage += HelpMessageOpt("-flushwallet", strprintf(_("Run a thread to flush wallet periodically (default: %u)"), DEFAULT_FLUSHWALLET)); - strUsage += HelpMessageOpt("-printcoinstake", _("Display verbose coin stake messages in the debug.log file.")); strUsage += HelpMessageOpt("-privdb", strprintf(_("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), DEFAULT_WALLET_PRIVDB)); } From f36c4d04b20aed3cbcbedeed210858bcc3649dd4 Mon Sep 17 00:00:00 2001 From: random-zebra Date: Wed, 9 Jun 2021 18:46:59 +0200 Subject: [PATCH 7/7] [Refactor] InitLoadWallet: CreateWalletFromFile before AutoBackupWallet --- src/wallet/init.cpp | 25 +++++++++---------------- src/wallet/wallet.cpp | 4 ++-- src/wallet/wallet.h | 2 +- src/wallet/walletdb.cpp | 10 ++++++---- src/wallet/walletdb.h | 2 +- 5 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp index 6aa959c7462a..f7bfcf90e3c7 100644 --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -209,9 +209,15 @@ bool InitLoadWallet() } for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { - // automatic backups + // create/load wallet + CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile); + if (!pwallet) { + return false; + } + + // automatic backup std::string strWarning, strError; - if(!AutoBackupWallet(walletFile, strWarning, strError)) { + if (!AutoBackupWallet(*pwallet, strWarning, strError)) { if (!strWarning.empty()) { UIWarning(strprintf("%s: %s", walletFile, strWarning)); } @@ -220,21 +226,8 @@ bool InitLoadWallet() } } - bool fFirstRun; - CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile, fFirstRun); - if (!pwallet) { - return false; - } + // add to wallets in use vpwallets.emplace_back(pwallet); - - if (fFirstRun) { - // Initial backup - if (!AutoBackupWallet(walletFile, strWarning, strError)) { - LogPrintf("Initial auto-backup failed for wallet %s, error: %s, warning: %s\n", - pwallet->GetName(), (strError.empty() ? "no error" : strError), - (strWarning.empty() ? "no warning" : strWarning)); - } - } } return true; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 0a181ef3a260..caab46ca9642 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4079,7 +4079,7 @@ void CWallet::LockIfMyCollateral(const CTransactionRef& ptx) } } -CWallet* CWallet::CreateWalletFromFile(const std::string& walletFile, bool& fFirstRun) +CWallet* CWallet::CreateWalletFromFile(const std::string& walletFile) { // needed to restore wallet transaction meta data after -zapwallettxes std::vector vWtx; @@ -4103,7 +4103,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& walletFile, bool& fFir fVerifyingBlocks = true; int64_t nStart = GetTimeMillis(); - fFirstRun = true; + bool fFirstRun = true; std::unique_ptr dbw(new CWalletDBWrapper(&bitdb, walletFile)); CWallet *walletInstance = new CWallet(std::move(dbw)); DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 17e14ab08f14..aece698d0e8e 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1155,7 +1155,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool AbandonTransaction(const uint256& hashTx); /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ - static CWallet* CreateWalletFromFile(const std::string& walletFile, bool& fFirstRun); + static CWallet* CreateWalletFromFile(const std::string& walletFile); /** * Wallet post-init setup diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 8ecf40f3e3f9..92f47177755c 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -894,8 +894,10 @@ static bool cleanWalletBackups(folder_set_t& folder_set, int nWalletBackups, std return true; } -bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWarning, std::string& strBackupError) +bool AutoBackupWallet(const CWallet& wallet, std::string& strBackupWarning, std::string& strBackupError) { + std::string strWalletFile = wallet.GetDBHandle().GetName(); + strBackupWarning = strBackupError = ""; int nWalletBackups = std::max(0, std::min(10, (int)gArgs.GetArg("-createwalletbackups", DEFAULT_CREATEWALLETBACKUPS))); if (nWalletBackups == 0) { @@ -918,13 +920,13 @@ bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWa } if (!fs::exists(sourceFile)) { - // Do not warn here. This could happen if the wallet hasn't been created. - LogPrintf("%s\n", _("Cannot create wallet auto-backup, wallet file not found")); + strBackupWarning = _("Failed to create backup, wallet file not found"); + LogPrintf("%s\n", strBackupWarning); return false; } // Try to backup - if (!AttemptBackupWallet(nullptr, sourceFile, backupFile)) { + if (!AttemptBackupWallet(&wallet, sourceFile, backupFile)) { return false; // error is logged internally } diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index e4dc58c8a774..3463d48b891f 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -244,7 +244,7 @@ bool BackupWallet(const CWallet& wallet, const fs::path& strDest); bool AttemptBackupWallet(const CWallet* wallet, const fs::path& pathSrc, const fs::path& pathDest); //! Called during init: Automatic backups of wallet not running (just copying and renaming dat file) -bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWarning, std::string& strBackupError); +bool AutoBackupWallet(const CWallet& wallet, std::string& strBackupWarning, std::string& strBackupError); //! Compacts BDB state so that wallet.dat is self-contained (if there are changes) void MaybeCompactWalletDB();