Skip to content

Commit

Permalink
Merge #2362: [Refactoring] Move automatic-wallet-backup code out of i…
Browse files Browse the repository at this point in the history
…nit.cpp

4dfc8e0 [MOVE-ONLY] Init: move -resync interaction out of init-wallet (step 5) (random-zebra)
1270ef8 [Refactor] Break up Auto-backup monolithic code in init.cpp (random-zebra)
6ab142b [Refactoring] Move sysperms + enabled wallet check in wallet.cpp (random-zebra)
d8d723b [wallet] Introduce DEFAULT_DISABLE_WALLET (MarcoFalke)
d098e5b init: Get rid of fDisableWallet (random-zebra)

Pull request description:

  Simple refactoring. First two commits are coming from bitcoin#8768.
  Other commits break up a big chunk of code from init.cpp into more manageable functions in wallet/walletdb.

  This will make the implementation of auto-backups for multi-wallets cleaner (will now rebase #2337 on top of this one).

ACKs for top commit:
  furszy:
     All good, code review ACK 4dfc8e0.
  Fuzzbawls:
    ACK 4dfc8e0

Tree-SHA512: d87c8aa7bb5293cc9f15650d4329313a63af8f33f08b82dd8e119a75db3608b4c2535322ccae82b404a68801dba76d858236b9e0c09bc1800f7f7cc0e8f21383
  • Loading branch information
random-zebra committed May 11, 2021
2 parents ecee30d + 4dfc8e0 commit 6fc3498
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 135 deletions.
169 changes: 44 additions & 125 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#include "net_processing.h"
#include "policy/feerate.h"
#include "policy/policy.h"
#include "reverse_iterate.h"
#include "rpc/register.h"
#include "rpc/server.h"
#include "script/sigcache.h"
Expand Down Expand Up @@ -87,9 +86,6 @@
#endif


#ifdef ENABLE_WALLET
int nWalletBackups = 10;
#endif
volatile bool fFeeEstimatesInitialized = false;
volatile bool fRestartRequested = false; // true: restart false: shutdown
static const bool DEFAULT_PROXYRANDOMIZE = true;
Expand Down Expand Up @@ -839,7 +835,6 @@ namespace { // Variables internal to initialization process only
ServiceFlags nLocalServices = NODE_NETWORK;

std::string strWalletFile;
bool fDisableWallet = false;
}

bool AppInitBasicSetup()
Expand Down Expand Up @@ -872,12 +867,7 @@ bool AppInitBasicSetup()
return UIError("Error: Initializing networking failed");

#ifndef WIN32
if (gArgs.GetBoolArg("-sysperms", false)) {
#ifdef ENABLE_WALLET
if (!gArgs.GetBoolArg("-disablewallet", false))
return UIError("Error: -sysperms is not allowed in combination with enabled wallet functionality");
#endif
} else {
if (!gArgs.GetBoolArg("-sysperms", false)) {
umask(077);
}

Expand Down Expand Up @@ -1137,18 +1127,14 @@ bool AppInitParameterInteraction()
setvbuf(stdout, NULL, _IOLBF, 0); /// ***TODO*** do we still need this after -printtoconsole is gone?

RegisterAllCoreRPCCommands(tableRPC);

// Staking needs a CWallet instance, so make sure wallet is enabled
#ifdef ENABLE_WALLET
bool fDisableWallet = gArgs.GetBoolArg("-disablewallet", false);
if (fDisableWallet) {
#endif
if (gArgs.SoftSetBoolArg("-staking", false))
LogPrintf("AppInit2 : parameter interaction: wallet functionality not enabled -> setting -staking=0\n");
#ifdef ENABLE_WALLET
} else {
// Register wallet RPC commands
RegisterWalletRPCCommands(tableRPC);
}
// Register wallet RPC commands
RegisterWalletRPCCommands(tableRPC);
#else
if (gArgs.SoftSetBoolArg("-staking", false))
LogPrintf("AppInit2 : parameter interaction: wallet functionality not enabled -> setting -staking=0\n");
#endif

nConnectTimeout = gArgs.GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT);
Expand Down Expand Up @@ -1313,117 +1299,50 @@ bool AppInitMain()
return UIError(_("Unable to start HTTP server. See debug log for details."));
}

// ********************************************************* Step 5: Backup wallet and verify wallet database integrity
#ifdef ENABLE_WALLET
if (!fDisableWallet) {
fs::path backupDir = GetDataDir() / "backups";
if (!fs::exists(backupDir)) {
// Always create backup folder to not confuse the operating system's file browser
fs::create_directories(backupDir);
}
nWalletBackups = gArgs.GetArg("-createwalletbackups", DEFAULT_CREATEWALLETBACKUPS);
nWalletBackups = std::max(0, std::min(10, nWalletBackups));
if (nWalletBackups > 0) {
if (fs::exists(backupDir)) {
// Create backup of the wallet
std::string dateTimeStr = FormatISO8601DateTimeForBackup(GetTime());
std::string backupPathStr = backupDir.string();
backupPathStr += "/" + strWalletFile;
std::string sourcePathStr = GetDataDir().string();
sourcePathStr += "/" + strWalletFile;
fs::path sourceFile = sourcePathStr;
fs::path backupFile = backupPathStr + dateTimeStr;
sourceFile.make_preferred();
backupFile.make_preferred();
if (fs::exists(sourceFile)) {
#if BOOST_VERSION >= 105800
try {
fs::copy_file(sourceFile, backupFile);
LogPrintf("Creating backup of %s -> %s\n", sourceFile, backupFile);
} catch (const fs::filesystem_error& error) {
LogPrintf("Failed to create backup %s\n", error.what());
}
#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<std::time_t, fs::path> folder_set_t;
folder_set_t folder_set;
fs::directory_iterator end_iter;
fs::path backupFolder = backupDir.string();
backupFolder.make_preferred();
// Build map of backup files for current(!) wallet sorted by last write time
fs::path currentFile;
for (fs::directory_iterator dir_iter(backupFolder); 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() == strWalletFile) {
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;
for (std::pair<const std::time_t, fs::path> 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 (const fs::filesystem_error& error) {
LogPrintf("Failed to delete backup %s\n", error.what());
}
}
}
}
}

if (gArgs.GetBoolArg("-resync", false)) {
uiInterface.InitMessage(_("Preparing for resync..."));
// Delete the local blockchain folders to force a resync from scratch to get a consitent blockchain-state
fs::path blocksDir = GetBlocksDir();
fs::path chainstateDir = GetDataDir() / "chainstate";
fs::path sporksDir = GetDataDir() / "sporks";
fs::path zerocoinDir = GetDataDir() / "zerocoin";
if (gArgs.GetBoolArg("-resync", false)) {
uiInterface.InitMessage(_("Preparing for resync..."));
// Delete the local blockchain folders to force a resync from scratch to get a consitent blockchain-state
fs::path blocksDir = GetBlocksDir();
fs::path chainstateDir = GetDataDir() / "chainstate";
fs::path sporksDir = GetDataDir() / "sporks";
fs::path zerocoinDir = GetDataDir() / "zerocoin";

LogPrintf("Deleting blockchain folders blocks, chainstate, sporks and zerocoin\n");
// We delete in 4 individual steps in case one of the folder is missing already
try {
if (fs::exists(blocksDir)){
fs::remove_all(blocksDir);
LogPrintf("-resync: folder deleted: %s\n", blocksDir.string().c_str());
}
LogPrintf("Deleting blockchain folders blocks, chainstate, sporks and zerocoin\n");
// We delete in 4 individual steps in case one of the folder is missing already
try {
if (fs::exists(blocksDir)){
fs::remove_all(blocksDir);
LogPrintf("-resync: folder deleted: %s\n", blocksDir.string().c_str());
}

if (fs::exists(chainstateDir)){
fs::remove_all(chainstateDir);
LogPrintf("-resync: folder deleted: %s\n", chainstateDir.string().c_str());
}
if (fs::exists(chainstateDir)){
fs::remove_all(chainstateDir);
LogPrintf("-resync: folder deleted: %s\n", chainstateDir.string().c_str());
}

if (fs::exists(sporksDir)){
fs::remove_all(sporksDir);
LogPrintf("-resync: folder deleted: %s\n", sporksDir.string().c_str());
}
if (fs::exists(sporksDir)){
fs::remove_all(sporksDir);
LogPrintf("-resync: folder deleted: %s\n", sporksDir.string().c_str());
}

if (fs::exists(zerocoinDir)){
fs::remove_all(zerocoinDir);
LogPrintf("-resync: folder deleted: %s\n", zerocoinDir.string().c_str());
}
} catch (const fs::filesystem_error& error) {
LogPrintf("Failed to delete blockchain folders %s\n", error.what());
if (fs::exists(zerocoinDir)){
fs::remove_all(zerocoinDir);
LogPrintf("-resync: folder deleted: %s\n", zerocoinDir.string().c_str());
}
} catch (const fs::filesystem_error& error) {
LogPrintf("Failed to delete blockchain folders %s\n", error.what());
}
}

if (!CWallet::Verify())
return false;

} // (!fDisableWallet)
#endif // ENABLE_WALLET
// ********************************************************* Step 5: Backup wallet and verify wallet database integrity
#ifdef ENABLE_WALLET
if (!InitAutoBackupWallet()) {
return false;
}
if (!CWallet::Verify()) {
return false;
}
#endif

// ********************************************************* Step 6: network initialization
// Note that we absolutely cannot open any actual connections
Expand Down
2 changes: 1 addition & 1 deletion src/qt/pivx/pivxgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ PIVXGUI::PIVXGUI(const NetworkStyle* networkStyle, QWidget* parent) :

#ifdef ENABLE_WALLET
/* if compiled with wallet support, -disablewallet can still disable the wallet */
enableWallet = !gArgs.GetBoolArg("-disablewallet", false);
enableWallet = !gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET);
#else
enableWallet = false;
#endif // ENABLE_WALLET
Expand Down
6 changes: 5 additions & 1 deletion src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4253,6 +4253,10 @@ static const CRPCCommand commands[] =

void RegisterWalletRPCCommands(CRPCTable &tableRPC)
{
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
if (gArgs.GetBoolArg("-disablewallet", false)) {
return;
}
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) {
tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
}
}
35 changes: 32 additions & 3 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2009-2021 The Bitcoin developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2020 The PIVX developers
// Copyright (c) 2015-2021 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

Expand Down Expand Up @@ -646,6 +646,14 @@ void CWallet::SyncMetaData(std::pair<typename TxSpendMap<T>::iterator, typename

bool CWallet::ParameterInteraction()
{
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
return true;
}

if (gArgs.GetBoolArg("-sysperms", false)) {
return UIError("-sysperms is not allowed in combination with enabled wallet functionality");
}

if (gArgs.IsArgSet("-mintxfee")) {
CAmount n = 0;
if (ParseMoney(gArgs.GetArg("-mintxfee", ""), n) && n > 0)
Expand Down Expand Up @@ -2063,6 +2071,10 @@ std::set<uint256> CWalletTx::GetConflicts() const

bool CWallet::Verify()
{
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
return true;
}

uiInterface.InitMessage(_("Verifying wallet..."));
std::string walletFile = gArgs.GetArg("-wallet", DEFAULT_WALLET_DAT);
std::string strDataDir = GetDataDir().string();
Expand Down Expand Up @@ -4082,7 +4094,7 @@ std::string CWallet::GetWalletHelpString(bool showDebug)
strUsage += HelpMessageOpt("-backuppath=<dir|file>", _("Specify custom backup path to add a copy of any wallet backup. If set as dir, every backup generates a timestamped file. If set as file, will rewrite to that file every backup."));
strUsage += HelpMessageOpt("-createwalletbackups=<n>", strprintf(_("Number of automatic wallet backups (default: %d)"), DEFAULT_CREATEWALLETBACKUPS));
strUsage += HelpMessageOpt("-custombackupthreshold=<n>", strprintf(_("Number of custom location backups to retain (default: %d)"), DEFAULT_CUSTOMBACKUPTHRESHOLD));
strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls"));
strUsage += HelpMessageOpt("-disablewallet", strprintf(_("Do not load the wallet and disable wallet RPC calls (default: %u)"), DEFAULT_DISABLE_WALLET));
strUsage += HelpMessageOpt("-keypool=<n>", strprintf(_("Set key pool size to <n> (default: %u)"), DEFAULT_KEYPOOL_SIZE));
strUsage += HelpMessageOpt("-legacywallet", _("On first run, create a legacy wallet instead of a HD wallet"));
strUsage += HelpMessageOpt("-maxtxfee=<amt>", strprintf(_("Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s)"), FormatMoney(maxTxFee)));
Expand Down Expand Up @@ -4844,3 +4856,20 @@ const CWDestination* CAddressBookIterator::GetDestKey()
CStakeableOutput::CStakeableOutput(const CWalletTx* txIn, int iIn, int nDepthIn, bool fSpendableIn, bool fSolvableIn,
const CBlockIndex*& _pindex) : COutput(txIn, iIn, nDepthIn, fSpendableIn, fSolvableIn),
pindex(_pindex) {}

bool InitAutoBackupWallet()
{
if (gArgs.GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) {
return true;
}

std::string strWalletFile = gArgs.GetArg("-wallet", DEFAULT_WALLET_DAT);

std::string strWarning, strError;
if(!AutoBackupWallet(strWalletFile, strWarning, strError)) {
if (!strWarning.empty()) UIWarning(strWarning);
if (!strError.empty()) return UIError(strError);
}

return true;
}
13 changes: 8 additions & 5 deletions src/wallet/wallet.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2009-2021 The Bitcoin developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2020 The PIVX developers
// Copyright (c) 2015-2021 The PIVX developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_WALLET_H
#define BITCOIN_WALLET_H
#ifndef PIVX_WALLET_H
#define PIVX_WALLET_H

#include "addressbook.h"
#include "amount.h"
Expand Down Expand Up @@ -1267,4 +1267,7 @@ class WalletRescanReserver
}
};

#endif // BITCOIN_WALLET_H
// !TODO: move to wallet/init.*
bool InitAutoBackupWallet();

#endif // PIVX_WALLET_H
Loading

0 comments on commit 6fc3498

Please sign in to comment.