Skip to content

Commit

Permalink
Slightly refactor AutoBackupWallet (dashpay#1927)
Browse files Browse the repository at this point in the history
- make incoming strWalletFile a const reference, do not modify it directly inside the function
- follow `false false ... false true` principle
  • Loading branch information
UdjinM6 authored and CryptoCentric committed Mar 2, 2019
1 parent f23b405 commit ac390a5
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 96 deletions.
192 changes: 97 additions & 95 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5176,127 +5176,129 @@ bool CWallet::BackupWallet(const std::string& strDest)

// This should be called carefully:
// either supply "wallet" (if already loaded) or "strWalletFile" (if wallet wasn't loaded yet)
bool AutoBackupWallet (CWallet* wallet, std::string strWalletFile, std::string& strBackupWarning, std::string& strBackupError)
bool AutoBackupWallet(CWallet* wallet, const std::string& strWalletFile_, std::string& strBackupWarningRet, std::string& strBackupErrorRet)
{
namespace fs = boost::filesystem;

strBackupWarning = strBackupError = "";
strBackupWarningRet = strBackupErrorRet = "";
std::string strWalletFile = "";

if(nWalletBackups > 0)
{
fs::path backupsDir = GetBackupsDir();
if (nWalletBackups <= 0) {
LogPrintf("Automatic wallet backups are disabled!\n");
return false;
}

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;
}
} else if (!fs::is_directory(backupsDir)) {
fs::path backupsDir = GetBackupsDir();

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(_("%s is not a valid backup folder!"), backupsDir.string());
LogPrintf("%s\n", strBackupError);
strBackupErrorRet = strprintf(_("Wasn't able to create wallet backup folder %s!"), backupsDir.string());
LogPrintf("%s\n", strBackupErrorRet);
nWalletBackups = -1;
return false;
}
} else if (!fs::is_directory(backupsDir)) {
// smth is wrong, we shouldn't continue until it's resolved
strBackupErrorRet = strprintf(_("%s is not a valid backup folder!"), backupsDir.string());
LogPrintf("%s\n", strBackupErrorRet);
nWalletBackups = -1;
return false;
}

// Create backup of the ...
std::string dateTimeStr = DateTimeStrFormat(".%Y-%m-%d-%H-%M", GetTime());
if (wallet)
// Create backup of the ...
std::string dateTimeStr = DateTimeStrFormat(".%Y-%m-%d-%H-%M", GetTime());
if (wallet)
{
// ... opened wallet
LOCK2(cs_main, wallet->cs_wallet);
strWalletFile = wallet->strWalletFile;
fs::path backupFile = backupsDir / (strWalletFile + dateTimeStr);
if(!wallet->BackupWallet(backupFile.string())) {
strBackupWarningRet = strprintf(_("Failed to create backup %s!"), backupFile.string());
LogPrintf("%s\n", strBackupWarningRet);
nWalletBackups = -1;
return false;
}
// Update nKeysLeftSinceAutoBackup using current external keypool size
wallet->nKeysLeftSinceAutoBackup = wallet->KeypoolCountExternalKeys();
LogPrintf("nKeysLeftSinceAutoBackup: %d\n", wallet->nKeysLeftSinceAutoBackup);
if(wallet->IsLocked(true)) {
strBackupWarningRet = _("Wallet is locked, can't replenish keypool! Automatic backups and mixing are disabled, please unlock your wallet to replenish keypool.");
LogPrintf("%s\n", strBackupWarningRet);
nWalletBackups = -2;
return false;
}
} else {
// ... strWalletFile file
strWalletFile = strWalletFile_;
fs::path sourceFile = GetDataDir() / strWalletFile;
fs::path backupFile = backupsDir / (strWalletFile + dateTimeStr);
sourceFile.make_preferred();
backupFile.make_preferred();
if (fs::exists(backupFile))
{
// ... opened wallet
LOCK2(cs_main, wallet->cs_wallet);
strWalletFile = wallet->strWalletFile;
fs::path backupFile = backupsDir / (strWalletFile + dateTimeStr);
if(!wallet->BackupWallet(backupFile.string())) {
strBackupWarning = strprintf(_("Failed to create backup %s!"), backupFile.string());
LogPrintf("%s\n", strBackupWarning);
strBackupWarningRet = _("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", strBackupWarningRet);
return false;
}
if(fs::exists(sourceFile)) {
try {
fs::copy_file(sourceFile, backupFile);
LogPrintf("Creating backup of %s -> %s\n", sourceFile.string(), backupFile.string());
} catch(fs::filesystem_error &error) {
strBackupWarningRet = strprintf(_("Failed to create backup, error: %s"), error.what());
LogPrintf("%s\n", strBackupWarningRet);
nWalletBackups = -1;
return false;
}
// Update nKeysLeftSinceAutoBackup using current external keypool size
wallet->nKeysLeftSinceAutoBackup = wallet->KeypoolCountExternalKeys();
LogPrintf("nKeysLeftSinceAutoBackup: %d\n", wallet->nKeysLeftSinceAutoBackup);
if(wallet->IsLocked(true)) {
strBackupWarning = _("Wallet is locked, can't replenish keypool! Automatic backups and mixing are disabled, please unlock your wallet to replenish keypool.");
LogPrintf("%s\n", strBackupWarning);
nWalletBackups = -2;
return false;
}
} else {
// ... strWalletFile file
fs::path sourceFile = GetDataDir() / strWalletFile;
fs::path backupFile = backupsDir / (strWalletFile + dateTimeStr);
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", strBackupWarning);
return false;
}
if(fs::exists(sourceFile)) {
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;
}
}
}
}

// Keep only the last 10 backups, including the new one of course
typedef std::multimap<std::time_t, fs::path> 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)
// Keep only the last 10 backups, including the new one of course
typedef std::multimap<std::time_t, fs::path> 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()))
{
// 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() == strWalletFile)
{
currentFile = dir_iter->path().filename();
// 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));
}
folder_set.insert(folder_set_t::value_type(fs::last_write_time(dir_iter->path()), *dir_iter));
}
}
}

// Loop backward through backup files and keep the N newest ones (1 <= N <= 10)
int counter = 0;
BOOST_REVERSE_FOREACH(PAIRTYPE(const std::time_t, fs::path) file, folder_set)
// Loop backward through backup files and keep the N newest ones (1 <= N <= 10)
int counter = 0;
BOOST_REVERSE_FOREACH(PAIRTYPE(const std::time_t, fs::path) file, folder_set)
{
counter++;
if (counter > nWalletBackups)
{
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;
}
// 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) {
strBackupWarningRet = strprintf(_("Failed to delete backup, error: %s"), error.what());
LogPrintf("%s\n", strBackupWarningRet);
return false;
}
}
return true;
}

LogPrintf("Automatic wallet backups are disabled!\n");
return false;
return true;
}
CKeyPool::CKeyPool()
{
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ extern const char * DEFAULT_WALLET_DAT;
//! if set, all keys will be derived by using BIP39/BIP44
static const bool DEFAULT_USE_HD_WALLET = false;

bool AutoBackupWallet (CWallet* wallet, std::string strWalletFile, std::string& strBackupWarning, std::string& strBackupError);
bool AutoBackupWallet (CWallet* wallet, const std::string& strWalletFile_, std::string& strBackupWarningRet, std::string& strBackupErrorRet);

class CBlockIndex;
class CCoinControl;
Expand Down

0 comments on commit ac390a5

Please sign in to comment.