Add -walletdir parameter to specify custom wallet dir
This commit is contained in:
parent
99bc0b428b
commit
0530ba0eae
12 changed files with 76 additions and 24 deletions
|
@ -168,6 +168,7 @@ BITCOIN_CORE_H = \
|
||||||
wallet/rpcwallet.h \
|
wallet/rpcwallet.h \
|
||||||
wallet/wallet.h \
|
wallet/wallet.h \
|
||||||
wallet/walletdb.h \
|
wallet/walletdb.h \
|
||||||
|
wallet/walletutil.h \
|
||||||
warnings.h \
|
warnings.h \
|
||||||
zmq/zmqabstractnotifier.h \
|
zmq/zmqabstractnotifier.h \
|
||||||
zmq/zmqconfig.h\
|
zmq/zmqconfig.h\
|
||||||
|
@ -249,6 +250,7 @@ libbitcoin_wallet_a_SOURCES = \
|
||||||
wallet/rpcwallet.cpp \
|
wallet/rpcwallet.cpp \
|
||||||
wallet/wallet.cpp \
|
wallet/wallet.cpp \
|
||||||
wallet/walletdb.cpp \
|
wallet/walletdb.cpp \
|
||||||
|
wallet/walletutil.cpp \
|
||||||
$(BITCOIN_CORE_H)
|
$(BITCOIN_CORE_H)
|
||||||
|
|
||||||
# crypto primitives library
|
# crypto primitives library
|
||||||
|
|
|
@ -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());
|
fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", "").c_str());
|
||||||
return false;
|
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
|
try
|
||||||
{
|
{
|
||||||
gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
|
gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
|
||||||
|
|
|
@ -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("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()));
|
||||||
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
|
LogPrintf("Default data directory %s\n", GetDefaultDataDir().string());
|
||||||
LogPrintf("Using data directory %s\n", GetDataDir().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 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);
|
LogPrintf("Using at most %i automatic connections (%i file descriptors available)\n", nMaxConnections, nFD);
|
||||||
|
|
||||||
|
|
|
@ -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", ""))));
|
QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
|
||||||
return EXIT_FAILURE;
|
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 {
|
try {
|
||||||
gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
|
gArgs.ReadConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <protocol.h>
|
#include <protocol.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <utilstrencodings.h>
|
#include <utilstrencodings.h>
|
||||||
|
#include <wallet/walletutil.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
@ -257,7 +258,7 @@ bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*reco
|
||||||
return fSuccess;
|
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 BerkeleyDB version %s\n", DbEnv::version(0, 0, 0));
|
||||||
LogPrintf("Using wallet %s\n", walletFile);
|
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
|
// Wallet file must be a plain filename without a directory
|
||||||
if (walletFile != fs::basename(walletFile) + fs::extension(walletFile))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bitdb.Open(dataDir))
|
if (!bitdb.Open(walletDir))
|
||||||
{
|
{
|
||||||
// try moving the database env out of the way
|
// try moving the database env out of the way
|
||||||
fs::path pathDatabase = dataDir / "database";
|
fs::path pathDatabase = walletDir / "database";
|
||||||
fs::path pathDatabaseBak = dataDir / strprintf("database.%d.bak", GetTime());
|
fs::path pathDatabaseBak = walletDir / strprintf("database.%d.bak", GetTime());
|
||||||
try {
|
try {
|
||||||
fs::rename(pathDatabase, pathDatabaseBak);
|
fs::rename(pathDatabase, pathDatabaseBak);
|
||||||
LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
|
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
|
// 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
|
// 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 false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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;
|
std::string backup_filename;
|
||||||
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, recoverFunc, 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"
|
" Original %s saved as %s in %s; if"
|
||||||
" your balance or transactions are incorrect you should"
|
" your balance or transactions are incorrect you should"
|
||||||
" restore from a backup."),
|
" restore from a backup."),
|
||||||
walletFile, backup_filename, dataDir);
|
walletFile, backup_filename, walletDir);
|
||||||
}
|
}
|
||||||
if (r == CDBEnv::RECOVER_FAIL)
|
if (r == CDBEnv::RECOVER_FAIL)
|
||||||
{
|
{
|
||||||
|
@ -407,7 +408,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK(env->cs_db);
|
LOCK(env->cs_db);
|
||||||
if (!env->Open(GetDataDir()))
|
if (!env->Open(GetWalletDir()))
|
||||||
throw std::runtime_error("CDB: Failed to open database environment.");
|
throw std::runtime_error("CDB: Failed to open database environment.");
|
||||||
|
|
||||||
pdb = env->mapDb[strFilename];
|
pdb = env->mapDb[strFilename];
|
||||||
|
@ -695,7 +696,7 @@ bool CWalletDBWrapper::Backup(const std::string& strDest)
|
||||||
env->mapFileUseCount.erase(strFile);
|
env->mapFileUseCount.erase(strFile);
|
||||||
|
|
||||||
// Copy wallet file
|
// Copy wallet file
|
||||||
fs::path pathSrc = GetDataDir() / strFile;
|
fs::path pathSrc = GetWalletDir() / strFile;
|
||||||
fs::path pathDest(strDest);
|
fs::path pathDest(strDest);
|
||||||
if (fs::is_directory(pathDest))
|
if (fs::is_directory(pathDest))
|
||||||
pathDest /= strFile;
|
pathDest /= strFile;
|
||||||
|
|
|
@ -167,9 +167,9 @@ public:
|
||||||
ideal to be called periodically */
|
ideal to be called periodically */
|
||||||
static bool PeriodicFlush(CWalletDBWrapper& dbw);
|
static bool PeriodicFlush(CWalletDBWrapper& dbw);
|
||||||
/* verifies the database environment */
|
/* 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 */
|
/* 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:
|
public:
|
||||||
template <typename K, typename T>
|
template <typename K, typename T>
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <utilmoneystr.h>
|
#include <utilmoneystr.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
#include <wallet/wallet.h>
|
|
||||||
#include <wallet/rpcwallet.h>
|
#include <wallet/rpcwallet.h>
|
||||||
|
#include <wallet/wallet.h>
|
||||||
|
#include <wallet/walletutil.h>
|
||||||
|
|
||||||
std::string GetWalletHelpString(bool showDebug)
|
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("-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("-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("-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("-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") +
|
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)"));
|
" " + _("(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));
|
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))) {
|
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));
|
return InitError(strprintf(_("Error loading wallet %s. -wallet filename must be a regular file."), walletFile));
|
||||||
|
@ -216,7 +218,7 @@ bool VerifyWallets()
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string strError;
|
std::string strError;
|
||||||
if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) {
|
if (!CWalletDB::VerifyEnvironment(walletFile, GetWalletDir().string(), strError)) {
|
||||||
return InitError(strError);
|
return InitError(strError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +232,7 @@ bool VerifyWallets()
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string strWarning;
|
std::string strWarning;
|
||||||
bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError);
|
bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetWalletDir().string(), strWarning, strError);
|
||||||
if (!strWarning.empty()) {
|
if (!strWarning.empty()) {
|
||||||
InitWarning(strWarning);
|
InitWarning(strWarning);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <wallet/feebumper.h>
|
#include <wallet/feebumper.h>
|
||||||
#include <wallet/wallet.h>
|
#include <wallet/wallet.h>
|
||||||
#include <wallet/walletdb.h>
|
#include <wallet/walletdb.h>
|
||||||
|
#include <wallet/walletutil.h>
|
||||||
|
|
||||||
#include <init.h> // For StartShutdown
|
#include <init.h> // For StartShutdown
|
||||||
|
|
||||||
|
|
|
@ -814,14 +814,14 @@ bool CWalletDB::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDa
|
||||||
return true;
|
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)
|
bool CWalletDB::WriteDestData(const std::string &address, const std::string &key, const std::string &value)
|
||||||
|
|
|
@ -226,9 +226,9 @@ public:
|
||||||
/* Function to determine if a certain KV/key-type is a key (cryptographical key) type */
|
/* Function to determine if a certain KV/key-type is a key (cryptographical key) type */
|
||||||
static bool IsKeyType(const std::string& strType);
|
static bool IsKeyType(const std::string& strType);
|
||||||
/* verifies the database environment */
|
/* 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 */
|
/* 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)
|
//! write the hdchain model (external chain child index counter)
|
||||||
bool WriteHDChain(const CHDChain& chain);
|
bool WriteHDChain(const CHDChain& chain);
|
||||||
|
|
23
src/wallet/walletutil.cpp
Normal file
23
src/wallet/walletutil.cpp
Normal 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
13
src/wallet/walletutil.h
Normal 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
|
Loading…
Reference in a new issue