Add -walletdir parameter to specify custom wallet dir

This commit is contained in:
MeshCollider 2017-10-09 09:48:07 +13:00
parent 99bc0b428b
commit 0530ba0eae
12 changed files with 76 additions and 24 deletions

View File

@ -168,6 +168,7 @@ BITCOIN_CORE_H = \
wallet/rpcwallet.h \
wallet/wallet.h \
wallet/walletdb.h \
wallet/walletutil.h \
warnings.h \
zmq/zmqabstractnotifier.h \
zmq/zmqconfig.h\
@ -249,6 +250,7 @@ libbitcoin_wallet_a_SOURCES = \
wallet/rpcwallet.cpp \
wallet/wallet.cpp \
wallet/walletdb.cpp \
wallet/walletutil.cpp \
$(BITCOIN_CORE_H)
# crypto primitives library

View File

@ -101,6 +101,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", BITCOIN_CONF_FILENAME));

View File

@ -1220,6 +1220,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
LogPrintf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 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", BITCOIN_CONF_FILENAME)).string());
LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);

View File

@ -626,6 +626,11 @@ int main(int argc, char *argv[])
QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
return EXIT_FAILURE;
}
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", BITCOIN_CONF_FILENAME));
} catch (const std::exception& e) {

View File

@ -11,6 +11,7 @@
#include <protocol.h>
#include <util.h>
#include <utilstrencodings.h>
#include <wallet/walletutil.h>
#include <stdint.h>
@ -257,7 +258,7 @@ 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);
@ -265,15 +266,15 @@ bool CDB::VerifyEnvironment(const std::string& walletFile, const fs::path& dataD
// Wallet file must be a plain filename without a directory
if (walletFile != fs::basename(walletFile) + fs::extension(walletFile))
{
errorStr = strprintf(_("Wallet %s resides outside data directory %s"), walletFile, dataDir.string());
errorStr = strprintf(_("Wallet %s resides outside wallet directory %s"), walletFile, walletDir.string());
return false;
}
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());
@ -282,18 +283,18 @@ 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);
@ -303,7 +304,7 @@ bool CDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& data
" 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)
{
@ -407,7 +408,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];
@ -695,7 +696,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;

View File

@ -167,9 +167,9 @@ public:
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>

View File

@ -9,8 +9,9 @@
#include <util.h>
#include <utilmoneystr.h>
#include <validation.h>
#include <wallet/wallet.h>
#include <wallet/rpcwallet.h>
#include <wallet/wallet.h>
#include <wallet/walletutil.h>
std::string GetWalletHelpString(bool showDebug)
{
@ -34,6 +35,7 @@ std::string GetWalletHelpString(bool showDebug)
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("-walletbroadcast", _("Make the wallet broadcast transactions") + " " + strprintf(_("(default: %u)"), DEFAULT_WALLETBROADCAST));
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. account owner and payment request information, 2 = drop tx meta data)"));
@ -205,7 +207,7 @@ bool VerifyWallets()
return InitError(strprintf(_("Error loading wallet %s. Invalid characters in -wallet filename."), walletFile));
}
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 InitError(strprintf(_("Error loading wallet %s. -wallet filename must be a regular file."), walletFile));
@ -216,7 +218,7 @@ bool VerifyWallets()
}
std::string strError;
if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) {
if (!CWalletDB::VerifyEnvironment(walletFile, GetWalletDir().string(), strError)) {
return InitError(strError);
}
@ -230,7 +232,7 @@ bool VerifyWallets()
}
std::string strWarning;
bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError);
bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetWalletDir().string(), strWarning, strError);
if (!strWarning.empty()) {
InitWarning(strWarning);
}

View File

@ -26,6 +26,7 @@
#include <wallet/feebumper.h>
#include <wallet/wallet.h>
#include <wallet/walletdb.h>
#include <wallet/walletutil.h>
#include <init.h> // For StartShutdown

View File

@ -814,14 +814,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)

View File

@ -226,9 +226,9 @@ public:
/* Function to determine 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);
//! write the hdchain model (external chain child index counter)
bool WriteHDChain(const CHDChain& chain);

23
src/wallet/walletutil.cpp Normal file
View File

@ -0,0 +1,23 @@
// 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"
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
src/wallet/walletutil.h Normal file
View File

@ -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 "util.h"
//! Get the path of the wallet directory.
fs::path GetWalletDir();
#endif // BITCOIN_WALLET_UTIL_H