Skip to content

Commit

Permalink
Add -walletdir parameter to specify custom wallet dir
Browse files Browse the repository at this point in the history
Adaptation of btc@0530ba0eae147563921b162ed05347234d8b53c0
  • Loading branch information
furszy committed Jul 21, 2021
1 parent 5b31813 commit 71a4701
Show file tree
Hide file tree
Showing 13 changed files with 85 additions and 24 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Expand Up @@ -267,6 +267,7 @@ set(WALLET_SOURCES
./src/legacy/stakemodifier.cpp
./src/wallet/wallet.cpp
./src/wallet/walletdb.cpp
./src/wallet/walletutil.cpp
./src/zpiv/zpivmodule.cpp
./src/zpiv/zpos.cpp
./src/stakeinput.cpp
Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.am
Expand Up @@ -305,6 +305,7 @@ BITCOIN_CORE_H = \
wallet/init.h \
wallet/wallet.h \
wallet/walletdb.h \
wallet/walletutil.h \
warnings.h \
zpivchain.h \
zpiv/zpos.h \
Expand Down Expand Up @@ -408,6 +409,7 @@ libbitcoin_wallet_a_SOURCES = \
destination_io.cpp \
wallet/wallet.cpp \
wallet/walletdb.cpp \
wallet/walletutil.cpp \
stakeinput.cpp \
zpiv/zpos.cpp \
$(BITCOIN_CORE_H) \
Expand Down
2 changes: 2 additions & 0 deletions src/init.cpp
Expand Up @@ -64,6 +64,7 @@
#include "wallet/init.h"
#include "wallet/wallet.h"
#include "wallet/rpcwallet.h"
#include "wallet/walletutil.h"
#endif

#include <atomic>
Expand Down Expand Up @@ -1268,6 +1269,7 @@ bool AppInitMain()
LogPrintf("Startup time: %s\n", FormatISO8601DateTime(GetTime()));
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
LogPrintf("Using data directory %s\n", GetDataDir().string());
LogPrintf("Using wallet directory %s\n", GetWalletDir().string());
LogPrintf("Using config file %s\n", GetConfigFile(gArgs.GetArg("-conf", PIVX_CONF_FILENAME)).string());
LogPrintf("Using at most %i connections (%i file descriptors available)\n", nMaxConnections, nFD);
std::ostringstream strErrors;
Expand Down
9 changes: 8 additions & 1 deletion src/pivxd.cpp
Expand Up @@ -11,9 +11,12 @@
#include "init.h"
#include "masternodeconfig.h"
#include "noui.h"
#include "rpc/server.h"
#include "util/system.h"

#ifdef ENABLE_WALLET
#include "wallet/walletutil.h"
#endif

#include <stdio.h>

/* Introduction text for doxygen: */
Expand Down Expand Up @@ -81,6 +84,10 @@ bool AppInit(int argc, char* argv[])
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str());
return false;
}
if (gArgs.IsArgSet("-walletdir") && !fs::is_directory(GetWalletDir())) {
fprintf(stderr, "Error: Specified wallet directory \"%s\" does not exist.\n", gArgs.GetArg("-walletdir", "").c_str());
return false;
}
try {
gArgs.ReadConfigFile(gArgs.GetArg("-conf", PIVX_CONF_FILENAME));
} catch (const std::exception& e) {
Expand Down
6 changes: 6 additions & 0 deletions src/qt/pivx.cpp
Expand Up @@ -26,6 +26,7 @@
#include "paymentserver.h"
#include "walletmodel.h"
#include "interfaces/wallet.h"
#include "wallet/walletutil.h"
#endif
#include "masternodeconfig.h"

Expand Down Expand Up @@ -607,6 +608,11 @@ int main(int argc, char* argv[])
QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
return 1;
}
if (gArgs.IsArgSet("-walletdir") && !fs::is_directory(GetWalletDir())) {
QMessageBox::critical(0, QObject::tr(PACKAGE_NAME),
QObject::tr("Error: Specified wallet directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-walletdir", ""))));
return EXIT_FAILURE;
}
try {
gArgs.ReadConfigFile(gArgs.GetArg("-conf", PIVX_CONF_FILENAME));
} catch (const std::exception& e) {
Expand Down
27 changes: 15 additions & 12 deletions src/wallet/db.cpp
Expand Up @@ -12,6 +12,7 @@
#include "protocol.h"
#include "util/system.h"
#include "utilstrencodings.h"
#include "wallet/walletutil.h"

#include <stdint.h>

Expand Down Expand Up @@ -255,20 +256,21 @@ bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*reco
return fSuccess;
}

bool CDB::VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr)
bool CDB::VerifyEnvironment(const std::string& walletFile, const fs::path& walletDir, std::string& errorStr)
{
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
LogPrintf("Using wallet %s\n", walletFile);

// Wallet file must be a plain filename without a directory
fs::path wallet_file_path(walletFile);
if (walletFile != wallet_file_path.filename().string())
return UIError(strprintf(_("Wallet %s resides outside data directory %s"), walletFile, dataDir.string()));
return UIError(strprintf(_("Wallet %s resides outside data directory %s"), walletFile, walletDir.string()));

if (!bitdb.Open(dataDir)) {
if (!bitdb.Open(walletDir))
{
// try moving the database env out of the way
fs::path pathDatabase = dataDir / "database";
fs::path pathDatabaseBak = dataDir / strprintf("database.%d.bak", GetTime());
fs::path pathDatabase = walletDir / "database";
fs::path pathDatabaseBak = walletDir / strprintf("database.%d.bak", GetTime());
try {
fs::rename(pathDatabase, pathDatabaseBak);
LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
Expand All @@ -277,26 +279,27 @@ bool CDB::VerifyEnvironment(const std::string& walletFile, const fs::path& dataD
}

// try again
if (!bitdb.Open(dataDir)) {
if (!bitdb.Open(walletDir)) {
// if it still fails, it probably means we can't even create the database env
errorStr = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir());
errorStr = strprintf(_("Error initializing wallet database environment %s!"), walletDir);
return false;
}
}
return true;
}

bool CDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc)
bool CDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& walletDir, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc)
{
if (fs::exists(dataDir / walletFile)) {
if (fs::exists(walletDir / walletFile))
{
std::string backup_filename;
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, recoverFunc, backup_filename);
if (r == CDBEnv::RECOVER_OK) {
warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!"
" Original %s saved as %s in %s; if"
" your balance or transactions are incorrect you should"
" restore from a backup."),
walletFile, backup_filename, dataDir);
walletFile, backup_filename, walletDir);
}
if (r == CDBEnv::RECOVER_FAIL) {
errorStr = strprintf(_("%s corrupt, salvage failed"), walletFile);
Expand Down Expand Up @@ -399,7 +402,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb

{
LOCK(env->cs_db);
if (!env->Open(GetDataDir()))
if (!env->Open(GetWalletDir()))
throw std::runtime_error("CDB: Failed to open database environment.");

pdb = env->mapDb[strFilename];
Expand Down Expand Up @@ -686,7 +689,7 @@ bool CWalletDBWrapper::Backup(const std::string& strDest)
env->mapFileUseCount.erase(strFile);

// Copy wallet file
fs::path pathSrc = GetDataDir() / strFile;
fs::path pathSrc = GetWalletDir() / strFile;
fs::path pathDest(strDest);
if (fs::is_directory(pathDest))
pathDest /= strFile;
Expand Down
4 changes: 2 additions & 2 deletions src/wallet/db.h
Expand Up @@ -169,9 +169,9 @@ class CDB
ideal to be called periodically */
static bool PeriodicFlush(CWalletDBWrapper& dbw);
/* verifies the database environment */
static bool VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr);
static bool VerifyEnvironment(const std::string& walletFile, const fs::path& walletDir, std::string& errorStr);
/* verifies the database file */
static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc);
static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& walletDir, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc);

public:
template <typename K, typename T>
Expand Down
8 changes: 5 additions & 3 deletions src/wallet/init.cpp
Expand Up @@ -12,6 +12,7 @@
#include "utilmoneystr.h"
#include "validation.h"
#include "wallet/wallet.h"
#include "wallet/walletutil.h"

std::string GetWalletHelpString(bool showDebug)
{
Expand All @@ -31,6 +32,7 @@ std::string GetWalletHelpString(bool showDebug)
strUsage += HelpMessageOpt("-txconfirmtarget=<n>", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), 1));
strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format") + " " + _("on startup"));
strUsage += HelpMessageOpt("-wallet=<file>", _("Specify wallet file (within data directory)") + " " + strprintf(_("(default: %s)"), DEFAULT_WALLET_DAT));
strUsage += HelpMessageOpt("-walletdir=<dir>", _("Specify directory to hold wallets (default: <datadir>/wallets if it exists, otherwise <datadir>)"));
strUsage += HelpMessageOpt("-walletnotify=<cmd>", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)"));
strUsage += HelpMessageOpt("-zapwallettxes=<mode>", _("Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup") +
" " + _("(1 = keep tx meta data e.g. payment request information, 2 = drop tx meta data)"));
Expand Down Expand Up @@ -159,7 +161,7 @@ bool WalletVerify()
return UIError(strprintf(_("Error loading wallet %s. Invalid characters in %s filename."), walletFile, "-wallet"));
}

fs::path wallet_path = fs::absolute(walletFile, GetDataDir());
fs::path wallet_path = fs::absolute(walletFile, GetWalletDir());

if (fs::exists(wallet_path) && (!fs::is_regular_file(wallet_path) || fs::is_symlink(wallet_path))) {
return UIError(strprintf(_("Error loading wallet %s. %s filename must be a regular file."), walletFile, "-wallet"));
Expand All @@ -170,7 +172,7 @@ bool WalletVerify()
}

std::string strError;
if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) {
if (!CWalletDB::VerifyEnvironment(walletFile, GetWalletDir().string(), strError)) {
return UIError(strError);
}

Expand All @@ -189,7 +191,7 @@ bool WalletVerify()
}

std::string strWarning;
bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError);
bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetWalletDir().string(), strWarning, strError);
if (!strWarning.empty()) {
UIWarning(strWarning);
}
Expand Down
1 change: 1 addition & 0 deletions src/wallet/rpcwallet.cpp
Expand Up @@ -27,6 +27,7 @@
#include "utilmoneystr.h"
#include "wallet/wallet.h"
#include "wallet/walletdb.h"
#include "wallet/walletutil.h"
#include "zpivchain.h"

#include <init.h> // for StartShutdown
Expand Down
8 changes: 4 additions & 4 deletions src/wallet/walletdb.cpp
Expand Up @@ -1064,14 +1064,14 @@ bool CWalletDB::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDa
return true;
}

bool CWalletDB::VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr)
bool CWalletDB::VerifyEnvironment(const std::string& walletFile, const fs::path& walletDir, std::string& errorStr)
{
return CDB::VerifyEnvironment(walletFile, dataDir, errorStr);
return CDB::VerifyEnvironment(walletFile, walletDir, errorStr);
}

bool CWalletDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr)
bool CWalletDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& walletDir, std::string& warningStr, std::string& errorStr)
{
return CDB::VerifyDatabaseFile(walletFile, dataDir, warningStr, errorStr, CWalletDB::Recover);
return CDB::VerifyDatabaseFile(walletFile, walletDir, warningStr, errorStr, CWalletDB::Recover);
}

bool CWalletDB::WriteDestData(const std::string& address, const std::string& key, const std::string& value)
Expand Down
4 changes: 2 additions & 2 deletions src/wallet/walletdb.h
Expand Up @@ -212,9 +212,9 @@ class CWalletDB
/* Function to determin if a certain KV/key-type is a key (cryptographical key) type */
static bool IsKeyType(const std::string& strType);
/* verifies the database environment */
static bool VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr);
static bool VerifyEnvironment(const std::string& walletFile, const fs::path& walletDir, std::string& errorStr);
/* verifies the database file */
static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr);
static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& walletDir, std::string& warningStr, std::string& errorStr);

//! Begin a new transaction
bool TxnBegin();
Expand Down
24 changes: 24 additions & 0 deletions src/wallet/walletutil.cpp
@@ -0,0 +1,24 @@
// Copyright (c) 2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "wallet/walletutil.h"
#include "util/system.h"

fs::path GetWalletDir()
{
fs::path path;

if (gArgs.IsArgSet("-walletdir")) {
path = fs::system_complete(gArgs.GetArg("-walletdir", ""));
if (!fs::is_directory(path)) {
// If the path specified doesn't exist, we return the deliberately
// invalid empty string.
path = "";
}
} else {
path = GetDataDir();
}

return path;
}
13 changes: 13 additions & 0 deletions src/wallet/walletutil.h
@@ -0,0 +1,13 @@
// Copyright (c) 2017 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_WALLET_UTIL_H
#define BITCOIN_WALLET_UTIL_H

#include "fs.h"

//! Get the path of the wallet directory.
fs::path GetWalletDir();

#endif // BITCOIN_WALLET_UTIL_H

0 comments on commit 71a4701

Please sign in to comment.