Skip to content

Commit 1270ef8

Browse files
committed
[Refactor] Break up Auto-backup monolithic code in init.cpp
1 parent 6ab142b commit 1270ef8

File tree

5 files changed

+126
-78
lines changed

5 files changed

+126
-78
lines changed

src/init.cpp

Lines changed: 4 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
#include "net_processing.h"
3838
#include "policy/feerate.h"
3939
#include "policy/policy.h"
40-
#include "reverse_iterate.h"
4140
#include "rpc/register.h"
4241
#include "rpc/server.h"
4342
#include "script/sigcache.h"
@@ -87,9 +86,6 @@
8786
#endif
8887

8988

90-
#ifdef ENABLE_WALLET
91-
int nWalletBackups = 10;
92-
#endif
9389
volatile bool fFeeEstimatesInitialized = false;
9490
volatile bool fRestartRequested = false; // true: restart false: shutdown
9591
static const bool DEFAULT_PROXYRANDOMIZE = true;
@@ -1305,74 +1301,11 @@ bool AppInitMain()
13051301

13061302
// ********************************************************* Step 5: Backup wallet and verify wallet database integrity
13071303
#ifdef ENABLE_WALLET
1304+
if (!InitAutoBackupWallet()) {
1305+
return false;
1306+
}
1307+
13081308
// not fixing indentation as this block of code will be moved away from here in the following commits
1309-
fs::path backupDir = GetDataDir() / "backups";
1310-
if (!fs::exists(backupDir)) {
1311-
// Always create backup folder to not confuse the operating system's file browser
1312-
fs::create_directories(backupDir);
1313-
}
1314-
nWalletBackups = gArgs.GetArg("-createwalletbackups", DEFAULT_CREATEWALLETBACKUPS);
1315-
nWalletBackups = std::max(0, std::min(10, nWalletBackups));
1316-
if (nWalletBackups > 0) {
1317-
if (fs::exists(backupDir)) {
1318-
// Create backup of the wallet
1319-
std::string dateTimeStr = FormatISO8601DateTimeForBackup(GetTime());
1320-
std::string backupPathStr = backupDir.string();
1321-
backupPathStr += "/" + strWalletFile;
1322-
std::string sourcePathStr = GetDataDir().string();
1323-
sourcePathStr += "/" + strWalletFile;
1324-
fs::path sourceFile = sourcePathStr;
1325-
fs::path backupFile = backupPathStr + dateTimeStr;
1326-
sourceFile.make_preferred();
1327-
backupFile.make_preferred();
1328-
if (fs::exists(sourceFile)) {
1329-
#if BOOST_VERSION >= 105800
1330-
try {
1331-
fs::copy_file(sourceFile, backupFile);
1332-
LogPrintf("Creating backup of %s -> %s\n", sourceFile, backupFile);
1333-
} catch (const fs::filesystem_error& error) {
1334-
LogPrintf("Failed to create backup %s\n", error.what());
1335-
}
1336-
#else
1337-
std::ifstream src(sourceFile.string(), std::ios::binary);
1338-
std::ofstream dst(backupFile.string(), std::ios::binary);
1339-
dst << src.rdbuf();
1340-
#endif
1341-
}
1342-
// Keep only the last 10 backups, including the new one of course
1343-
typedef std::multimap<std::time_t, fs::path> folder_set_t;
1344-
folder_set_t folder_set;
1345-
fs::directory_iterator end_iter;
1346-
fs::path backupFolder = backupDir.string();
1347-
backupFolder.make_preferred();
1348-
// Build map of backup files for current(!) wallet sorted by last write time
1349-
fs::path currentFile;
1350-
for (fs::directory_iterator dir_iter(backupFolder); dir_iter != end_iter; ++dir_iter) {
1351-
// Only check regular files
1352-
if (fs::is_regular_file(dir_iter->status())) {
1353-
currentFile = dir_iter->path().filename();
1354-
// Only add the backups for the current wallet, e.g. wallet.dat.*
1355-
if (dir_iter->path().stem().string() == strWalletFile) {
1356-
folder_set.insert(folder_set_t::value_type(fs::last_write_time(dir_iter->path()), *dir_iter));
1357-
}
1358-
}
1359-
}
1360-
// Loop backward through backup files and keep the N newest ones (1 <= N <= 10)
1361-
int counter = 0;
1362-
for (std::pair<const std::time_t, fs::path> file : reverse_iterate(folder_set)) {
1363-
counter++;
1364-
if (counter > nWalletBackups) {
1365-
// More than nWalletBackups backups: delete oldest one(s)
1366-
try {
1367-
fs::remove(file.second);
1368-
LogPrintf("Old backup deleted: %s\n", file.second);
1369-
} catch (const fs::filesystem_error& error) {
1370-
LogPrintf("Failed to delete backup %s\n", error.what());
1371-
}
1372-
}
1373-
}
1374-
}
1375-
}
13761309

13771310
if (gArgs.GetBoolArg("-resync", false)) {
13781311
uiInterface.InitMessage(_("Preparing for resync..."));

src/wallet/wallet.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) 2009-2010 Satoshi Nakamoto
2-
// Copyright (c) 2009-2014 The Bitcoin developers
2+
// Copyright (c) 2009-2021 The Bitcoin developers
33
// Copyright (c) 2014-2015 The Dash developers
4-
// Copyright (c) 2015-2020 The PIVX developers
4+
// Copyright (c) 2015-2021 The PIVX developers
55
// Distributed under the MIT software license, see the accompanying
66
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
77

@@ -4856,3 +4856,20 @@ const CWDestination* CAddressBookIterator::GetDestKey()
48564856
CStakeableOutput::CStakeableOutput(const CWalletTx* txIn, int iIn, int nDepthIn, bool fSpendableIn, bool fSolvableIn,
48574857
const CBlockIndex*& _pindex) : COutput(txIn, iIn, nDepthIn, fSpendableIn, fSolvableIn),
48584858
pindex(_pindex) {}
4859+
4860+
bool InitAutoBackupWallet()
4861+
{
4862+
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
4863+
return true;
4864+
}
4865+
4866+
std::string strWalletFile = gArgs.GetArg("-wallet", DEFAULT_WALLET_DAT);
4867+
4868+
std::string strWarning, strError;
4869+
if(!AutoBackupWallet(strWalletFile, strWarning, strError)) {
4870+
if (!strWarning.empty()) UIWarning(strWarning);
4871+
if (!strError.empty()) return UIError(strError);
4872+
}
4873+
4874+
return true;
4875+
}

src/wallet/wallet.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// Copyright (c) 2009-2010 Satoshi Nakamoto
2-
// Copyright (c) 2009-2014 The Bitcoin developers
2+
// Copyright (c) 2009-2021 The Bitcoin developers
33
// Copyright (c) 2014-2015 The Dash developers
4-
// Copyright (c) 2015-2020 The PIVX developers
4+
// Copyright (c) 2015-2021 The PIVX developers
55
// Distributed under the MIT software license, see the accompanying
66
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
77

8-
#ifndef BITCOIN_WALLET_H
9-
#define BITCOIN_WALLET_H
8+
#ifndef PIVX_WALLET_H
9+
#define PIVX_WALLET_H
1010

1111
#include "addressbook.h"
1212
#include "amount.h"
@@ -1267,4 +1267,7 @@ class WalletRescanReserver
12671267
}
12681268
};
12691269

1270-
#endif // BITCOIN_WALLET_H
1270+
// !TODO: move to wallet/init.*
1271+
bool InitAutoBackupWallet();
1272+
1273+
#endif // PIVX_WALLET_H

src/wallet/walletdb.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "base58.h"
1313
#include "protocol.h"
14+
#include "reverse_iterate.h"
1415
#include "sapling/key_io_sapling.h"
1516
#include "serialize.h"
1617
#include "sync.h"
@@ -870,6 +871,97 @@ std::pair<fs::path, fs::path> GetBackupPath(const CWallet& wallet)
870871
return {pathCustom, pathWithFile};
871872
}
872873

874+
bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWarning, std::string& strBackupError)
875+
{
876+
strBackupWarning = strBackupError = "";
877+
878+
int nWalletBackups = gArgs.GetArg("-createwalletbackups", DEFAULT_CREATEWALLETBACKUPS);
879+
nWalletBackups = std::max(0, std::min(10, nWalletBackups));
880+
881+
if (nWalletBackups == 0) {
882+
LogPrintf("Automatic wallet backups are disabled!\n");
883+
return false;
884+
}
885+
886+
fs::path backupsDir = GetDataDir() / "backups";
887+
if (!fs::exists(backupsDir)) {
888+
// Always create backup folder to not confuse the operating system's file browser
889+
LogPrintf("Creating backup folder %s\n", backupsDir.string());
890+
if(!fs::create_directories(backupsDir)) {
891+
// smth is wrong, we shouldn't continue until it's resolved
892+
strBackupError = strprintf(_("Wasn't able to create wallet backup folder %s!"), backupsDir.string());
893+
LogPrintf("%s\n", strBackupError);
894+
nWalletBackups = -1;
895+
return false;
896+
}
897+
}
898+
// Create backup of the ...
899+
std::string dateTimeStr = FormatISO8601DateTimeForBackup(GetTime());
900+
901+
// ... strWalletFile file
902+
fs::path sourceFile = GetDataDir() / strWalletFile;
903+
fs::path backupFile = backupsDir / (strWalletFile + dateTimeStr);
904+
sourceFile.make_preferred();
905+
backupFile.make_preferred();
906+
if (fs::exists(backupFile)) {
907+
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.");
908+
LogPrintf("%s\n", strBackupWarning);
909+
return false;
910+
}
911+
if(fs::exists(sourceFile)) {
912+
#if BOOST_VERSION >= 105800
913+
try {
914+
fs::copy_file(sourceFile, backupFile);
915+
LogPrintf("Creating backup of %s -> %s\n", sourceFile.string(), backupFile.string());
916+
} catch(fs::filesystem_error &error) {
917+
strBackupWarning = strprintf(_("Failed to create backup, error: %s"), error.what());
918+
LogPrintf("%s\n", strBackupWarning);
919+
nWalletBackups = -1;
920+
return false;
921+
}
922+
#else
923+
std::ifstream src(sourceFile.string(), std::ios::binary);
924+
std::ofstream dst(backupFile.string(), std::ios::binary);
925+
dst << src.rdbuf();
926+
#endif
927+
}
928+
929+
// Keep only the last 10 backups, including the new one of course
930+
typedef std::multimap<std::time_t, fs::path> folder_set_t;
931+
folder_set_t folder_set;
932+
fs::directory_iterator end_iter;
933+
backupsDir.make_preferred();
934+
// Build map of backup files for current(!) wallet sorted by last write time
935+
fs::path currentFile;
936+
for (fs::directory_iterator dir_iter(backupsDir); dir_iter != end_iter; ++dir_iter) {
937+
// Only check regular files
938+
if ( fs::is_regular_file(dir_iter->status())) {
939+
currentFile = dir_iter->path().filename();
940+
// Only add the backups for the current wallet, e.g. wallet.dat.*
941+
if(dir_iter->path().stem().string() == strWalletFile) {
942+
folder_set.insert(folder_set_t::value_type(fs::last_write_time(dir_iter->path()), *dir_iter));
943+
}
944+
}
945+
}
946+
// Loop backward through backup files and keep the N newest ones (1 <= N <= 10)
947+
int counter = 0;
948+
for (std::pair<const std::time_t, fs::path> file : reverse_iterate(folder_set)) {
949+
counter++;
950+
if (counter > nWalletBackups) {
951+
// More than nWalletBackups backups: delete oldest one(s)
952+
try {
953+
fs::remove(file.second);
954+
LogPrintf("Old backup deleted: %s\n", file.second);
955+
} catch(fs::filesystem_error &error) {
956+
strBackupWarning = strprintf(_("Failed to delete backup, error: %s"), error.what());
957+
LogPrintf("%s\n", strBackupWarning);
958+
return false;
959+
}
960+
}
961+
}
962+
return true;
963+
}
964+
873965
void MultiBackup(const CWallet& wallet, fs::path pathCustom, fs::path pathWithFile, const fs::path& pathSrc)
874966
{
875967
int nThreshold = gArgs.GetArg("-custombackupthreshold", DEFAULT_CUSTOMBACKUPTHRESHOLD);

src/wallet/walletdb.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,9 @@ void NotifyBacked(const CWallet& wallet, bool fSuccess, std::string strMessage);
221221
bool BackupWallet(const CWallet& wallet, const fs::path& strDest);
222222
bool AttemptBackupWallet(const CWallet& wallet, const fs::path& pathSrc, const fs::path& pathDest);
223223

224+
//! Called during init: Automatic backups of wallet not running (just copying and renaming dat file)
225+
bool AutoBackupWallet(const std::string& strWalletFile, std::string& strBackupWarning, std::string& strBackupError);
226+
224227
//! Compacts BDB state so that wallet.dat is self-contained (if there are changes)
225228
void MaybeCompactWalletDB();
226229

0 commit comments

Comments
 (0)