mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Merge pull request #4481 from Munkybooty/backports-0.19-pr2
Backports 0.19 pr2
This commit is contained in:
commit
0e4ebdc4aa
1
.gitignore
vendored
1
.gitignore
vendored
@ -10,6 +10,7 @@ src/dash
|
||||
src/dashd
|
||||
src/dash-cli
|
||||
src/dash-tx
|
||||
src/dash-wallet
|
||||
src/test/fuzz
|
||||
!src/test/fuzz/*.*
|
||||
src/test/test_dash
|
||||
|
20
configure.ac
20
configure.ac
@ -18,6 +18,7 @@ BITCOIN_DAEMON_NAME=dashd
|
||||
BITCOIN_GUI_NAME=dash-qt
|
||||
BITCOIN_CLI_NAME=dash-cli
|
||||
BITCOIN_TX_NAME=dash-tx
|
||||
BITCOIN_WALLET_TOOL_NAME=dash-wallet
|
||||
|
||||
dnl Unless the user specified ARFLAGS, force it to be cr
|
||||
AC_ARG_VAR(ARFLAGS, [Flags for the archiver, defaults to <cr> if not set])
|
||||
@ -537,7 +538,7 @@ CPPFLAGS="$CPPFLAGS -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS"
|
||||
|
||||
AC_ARG_WITH([utils],
|
||||
[AS_HELP_STRING([--with-utils],
|
||||
[build dash-cli dash-tx (default=yes)])],
|
||||
[build dash-cli dash-tx dash-wallet (default=yes)])],
|
||||
[build_bitcoin_utils=$withval],
|
||||
[build_bitcoin_utils=yes])
|
||||
|
||||
@ -553,6 +554,12 @@ AC_ARG_ENABLE([util-tx],
|
||||
[build_bitcoin_tx=$enableval],
|
||||
[build_bitcoin_tx=$build_bitcoin_utils])
|
||||
|
||||
AC_ARG_ENABLE([util-wallet],
|
||||
[AS_HELP_STRING([--enable-util-wallet],
|
||||
[build dash-wallet])],
|
||||
[build_bitcoin_wallet=$enableval],
|
||||
[build_bitcoin_wallet=$build_bitcoin_utils])
|
||||
|
||||
AC_ARG_WITH([libs],
|
||||
[AS_HELP_STRING([--with-libs],
|
||||
[build libraries (default=yes)])],
|
||||
@ -1161,7 +1168,7 @@ if test x$suppress_external_warnings != xno ; then
|
||||
QT_TEST_INCLUDES=SUPPRESS_WARNINGS($QT_TEST_INCLUDES)
|
||||
fi
|
||||
|
||||
if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnononononono; then
|
||||
if test x$build_bitcoin_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononononono; then
|
||||
use_boost=no
|
||||
else
|
||||
use_boost=yes
|
||||
@ -1387,7 +1394,7 @@ AC_CHECK_LIB([gmp], [__gmpz_init],GMP_LIBS=-lgmp, AC_MSG_ERROR(libgmp missing))
|
||||
dnl check if immer headers-only library is present
|
||||
AC_CHECK_HEADER([immer/map.hpp],, AC_MSG_ERROR(immer map headers missing))
|
||||
|
||||
if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnononononono; then
|
||||
if test x$build_bitcoin_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononononono; then
|
||||
need_bundled_univalue=no
|
||||
else
|
||||
|
||||
@ -1449,6 +1456,10 @@ AC_MSG_CHECKING([whether to build dash-tx])
|
||||
AM_CONDITIONAL([BUILD_BITCOIN_TX], [test x$build_bitcoin_tx = xyes])
|
||||
AC_MSG_RESULT($build_bitcoin_tx)
|
||||
|
||||
AC_MSG_CHECKING([whether to build dash-wallet])
|
||||
AM_CONDITIONAL([BUILD_BITCOIN_WALLET], [test x$build_bitcoin_wallet = xyes])
|
||||
AC_MSG_RESULT($build_bitcoin_wallet)
|
||||
|
||||
AC_MSG_CHECKING([whether to build libraries])
|
||||
AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes])
|
||||
if test x$build_bitcoin_libs = xyes; then
|
||||
@ -1602,7 +1613,7 @@ else
|
||||
fi
|
||||
AC_MSG_RESULT($dsymutil_needs_flat)
|
||||
|
||||
if test x$build_bitcoin_cli$build_bitcoin_tx$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_bench$use_tests = xnonononononono; then
|
||||
if test x$build_bitcoin_wallet$build_bitcoin_cli$build_bitcoin_tx$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononononono; then
|
||||
AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui --enable-bench or --enable-tests])
|
||||
fi
|
||||
|
||||
@ -1651,6 +1662,7 @@ AC_SUBST(BITCOIN_DAEMON_NAME)
|
||||
AC_SUBST(BITCOIN_GUI_NAME)
|
||||
AC_SUBST(BITCOIN_CLI_NAME)
|
||||
AC_SUBST(BITCOIN_TX_NAME)
|
||||
AC_SUBST(BITCOIN_WALLET_TOOL_NAME)
|
||||
|
||||
AC_SUBST(RELDFLAGS)
|
||||
AC_SUBST(DEBUG_CPPFLAGS)
|
||||
|
@ -64,6 +64,7 @@ LIBBITCOINCONSENSUS=libdashconsensus.la
|
||||
endif
|
||||
if ENABLE_WALLET
|
||||
LIBBITCOIN_WALLET=libdash_wallet.a
|
||||
LIBBITCOIN_WALLET_TOOL=libdash_wallet_tool.a
|
||||
endif
|
||||
|
||||
LIBBITCOIN_CRYPTO= $(LIBBITCOIN_CRYPTO_BASE)
|
||||
@ -93,6 +94,7 @@ EXTRA_LIBRARIES += \
|
||||
$(LIBBITCOIN_SERVER) \
|
||||
$(LIBBITCOIN_CLI) \
|
||||
$(LIBBITCOIN_WALLET) \
|
||||
$(LIBBITCOIN_WALLET_TOOL) \
|
||||
$(LIBBITCOIN_ZMQ)
|
||||
|
||||
lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS)
|
||||
@ -112,6 +114,11 @@ endif
|
||||
if BUILD_BITCOIN_TX
|
||||
bin_PROGRAMS += dash-tx
|
||||
endif
|
||||
if ENABLE_WALLET
|
||||
if BUILD_BITCOIN_WALLET
|
||||
bin_PROGRAMS += dash-wallet
|
||||
endif
|
||||
endif
|
||||
|
||||
.PHONY: FORCE check-symbols check-security
|
||||
# dash core #
|
||||
@ -305,6 +312,7 @@ BITCOIN_CORE_H = \
|
||||
wallet/rpcwallet.h \
|
||||
wallet/wallet.h \
|
||||
wallet/walletdb.h \
|
||||
wallet/wallettool.h \
|
||||
wallet/walletutil.h \
|
||||
wallet/coinselection.h \
|
||||
warnings.h \
|
||||
@ -462,6 +470,12 @@ libdash_wallet_a_SOURCES = \
|
||||
wallet/coinselection.cpp \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
libdash_wallet_tool_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
libdash_wallet_tool_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
libdash_wallet_tool_a_SOURCES = \
|
||||
wallet/wallettool.cpp \
|
||||
$(BITCOIN_CORE_H)
|
||||
|
||||
# crypto primitives library
|
||||
crypto_libdash_crypto_base_a_CPPFLAGS = $(AM_CPPFLAGS) $(PIC_FLAGS)
|
||||
crypto_libdash_crypto_base_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) $(PIC_FLAGS)
|
||||
@ -739,6 +753,37 @@ dash_tx_LDADD = \
|
||||
dash_tx_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(CRYPTO_LIBS) $(BLS_LIBS) $(GMP_LIBS)
|
||||
#
|
||||
|
||||
# dash-wallet binary #
|
||||
dash_wallet_SOURCES = dash-wallet.cpp
|
||||
dash_wallet_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
dash_wallet_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
dash_wallet_LDFLAGS = $(LDFLAGS_WRAP_EXCEPTIONS) $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
|
||||
if TARGET_WINDOWS
|
||||
dash_wallet_SOURCES += dash-wallet-res.rc
|
||||
endif
|
||||
|
||||
# Libraries below may be listed more than once to resolve circular dependencies (see
|
||||
# https://eli.thegreenplace.net/2013/07/09/library-order-in-static-linking#circular-dependency)
|
||||
dash_wallet_LDADD = \
|
||||
$(LIBBITCOIN_WALLET_TOOL) \
|
||||
$(LIBBITCOIN_SERVER) \
|
||||
$(LIBBITCOIN_WALLET) \
|
||||
$(LIBBITCOIN_SERVER) \
|
||||
$(LIBBITCOIN_COMMON) \
|
||||
$(LIBBITCOIN_CONSENSUS) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBBITCOIN_CRYPTO) \
|
||||
$(LIBBITCOIN_ZMQ) \
|
||||
$(LIBLEVELDB) \
|
||||
$(LIBLEVELDB_SSE42) \
|
||||
$(LIBMEMENV) \
|
||||
$(LIBSECP256K1) \
|
||||
$(LIBUNIVALUE)
|
||||
|
||||
dash_wallet_LDADD += $(BACKTRACE_LIB) $(BOOST_LIBS) $(BDB_LIBS) $(CRYPTO_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(MINIUPNPC_LIBS) $(ZMQ_LIBS) $(BLS_LIBS) $(GMP_LIBS)
|
||||
#
|
||||
|
||||
# dashconsensus library #
|
||||
if BUILD_BITCOIN_LIBS
|
||||
include_HEADERS = script/dashconsensus.h
|
||||
|
35
src/dash-wallet-res.rc
Normal file
35
src/dash-wallet-res.rc
Normal file
@ -0,0 +1,35 @@
|
||||
#include <windows.h> // needed for VERSIONINFO
|
||||
#include "clientversion.h" // holds the needed client version information
|
||||
|
||||
#define VER_PRODUCTVERSION CLIENT_VERSION_MAJOR,CLIENT_VERSION_MINOR,CLIENT_VERSION_REVISION,CLIENT_VERSION_BUILD
|
||||
#define VER_PRODUCTVERSION_STR STRINGIZE(CLIENT_VERSION_MAJOR) "." STRINGIZE(CLIENT_VERSION_MINOR) "." STRINGIZE(CLIENT_VERSION_REVISION) "." STRINGIZE(CLIENT_VERSION_BUILD)
|
||||
#define VER_FILEVERSION VER_PRODUCTVERSION
|
||||
#define VER_FILEVERSION_STR VER_PRODUCTVERSION_STR
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_PRODUCTVERSION
|
||||
FILEOS VOS_NT_WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4" // U.S. English - multilingual (hex)
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Dash Core"
|
||||
VALUE "FileDescription", "dash-wallet (CLI tool for " PACKAGE_NAME " wallets)"
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", "dash-wallet"
|
||||
VALUE "LegalCopyright", COPYRIGHT_STR
|
||||
VALUE "LegalTrademarks1", "Distributed under the MIT software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
|
||||
VALUE "OriginalFilename", "dash-wallet.exe"
|
||||
VALUE "ProductName", "dash-wallet"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x0, 1252 // language neutral - multilingual (decimal)
|
||||
END
|
||||
END
|
118
src/dash-wallet.cpp
Normal file
118
src/dash-wallet.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
// Copyright (c) 2016-2018 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config/dash-config.h>
|
||||
#endif
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <chainparamsbase.h>
|
||||
#include <consensus/consensus.h>
|
||||
#include <logging.h>
|
||||
#include <util/system.h>
|
||||
#include <util/strencodings.h>
|
||||
#include <wallet/wallettool.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
|
||||
|
||||
static void SetupWalletToolArgs()
|
||||
{
|
||||
SetupChainParamsBaseOptions();
|
||||
|
||||
gArgs.AddArg("-?", "This help message", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
gArgs.AddArg("-datadir=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
gArgs.AddArg("-wallet=<wallet-name>", "Specify wallet name", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
|
||||
gArgs.AddArg("-debug=<category>", "Output debugging information (default: 0).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
|
||||
gArgs.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -debug is true, 0 otherwise.", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
|
||||
|
||||
gArgs.AddArg("info", "Get wallet info", ArgsManager::ALLOW_ANY, OptionsCategory::COMMANDS);
|
||||
gArgs.AddArg("create", "Create new wallet file", ArgsManager::ALLOW_ANY, OptionsCategory::COMMANDS);
|
||||
|
||||
// Hidden
|
||||
gArgs.AddArg("-h", "", ArgsManager::ALLOW_ANY, OptionsCategory::HIDDEN);
|
||||
gArgs.AddArg("-help", "", ArgsManager::ALLOW_ANY, OptionsCategory::HIDDEN);
|
||||
}
|
||||
|
||||
static bool WalletAppInit(int argc, char* argv[])
|
||||
{
|
||||
SetupWalletToolArgs();
|
||||
std::string error_message;
|
||||
if (!gArgs.ParseParameters(argc, argv, error_message)) {
|
||||
tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error_message);
|
||||
return false;
|
||||
}
|
||||
if (argc < 2 || HelpRequested(gArgs)) {
|
||||
std::string usage = strprintf("%s dash-wallet version", PACKAGE_NAME) + " " + FormatFullVersion() + "\n\n" +
|
||||
"wallet-tool is an offline tool for creating and interacting with Dash Core wallet files.\n" +
|
||||
"By default wallet-tool will act on wallets in the default mainnet wallet directory in the datadir.\n" +
|
||||
"To change the target wallet, use the -datadir, -wallet and -testnet/-regtest arguments.\n\n" +
|
||||
"Usage:\n" +
|
||||
" dash-wallet [options] <command>\n\n" +
|
||||
gArgs.GetHelpMessage();
|
||||
|
||||
tfm::format(std::cout, "%s", usage);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for printtoconsole, allow -debug
|
||||
LogInstance().m_print_to_console = gArgs.GetBoolArg("-printtoconsole", gArgs.GetBoolArg("-debug", false));
|
||||
|
||||
if (!fs::is_directory(GetDataDir(false))) {
|
||||
tfm::format(std::cerr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", ""));
|
||||
return false;
|
||||
}
|
||||
// Check for -testnet or -regtest parameter (Params() calls are only valid after this clause)
|
||||
SelectParams(gArgs.GetChainName());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
#ifdef WIN32
|
||||
util::WinCmdLineArgs winArgs;
|
||||
std::tie(argc, argv) = winArgs.get();
|
||||
#endif
|
||||
SetupEnvironment();
|
||||
RandomInit();
|
||||
try {
|
||||
if (!WalletAppInit(argc, argv)) return EXIT_FAILURE;
|
||||
} catch (...) {
|
||||
PrintExceptionContinue(std::current_exception(), "WalletAppInit()");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::string method {};
|
||||
for(int i = 1; i < argc; ++i) {
|
||||
if (!IsSwitchChar(argv[i][0])) {
|
||||
if (!method.empty()) {
|
||||
tfm::format(std::cerr, "Error: two methods provided (%s and %s). Only one method should be provided.\n", method, argv[i]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
method = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (method.empty()) {
|
||||
tfm::format(std::cerr, "No method provided. Run `dash-wallet -help` for valid methods.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// A name must be provided when creating a file
|
||||
if (method == "create" && !gArgs.IsArgSet("-wallet")) {
|
||||
tfm::format(std::cerr, "Wallet name must be provided when creating a new wallet.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
std::string name = gArgs.GetArg("-wallet", "");
|
||||
|
||||
ECCVerifyHandle globalVerifyHandle;
|
||||
ECC_Start();
|
||||
if (!WalletTool::ExecuteWalletToolFunc(method, name))
|
||||
return EXIT_FAILURE;
|
||||
ECC_Stop();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
@ -469,6 +469,11 @@ QList<QModelIndex> getEntryData(QAbstractItemView *view, int column)
|
||||
return view->selectionModel()->selectedRows(column);
|
||||
}
|
||||
|
||||
QString getDefaultDataDirectory()
|
||||
{
|
||||
return boostPathToQString(GetDefaultDataDir());
|
||||
}
|
||||
|
||||
QString getSaveFileName(QWidget *parent, const QString &caption, const QString &dir,
|
||||
const QString &filter,
|
||||
QString *selectedSuffixOut)
|
||||
|
@ -145,6 +145,11 @@ namespace GUIUtil
|
||||
|
||||
void setClipboard(const QString& str);
|
||||
|
||||
/**
|
||||
* Determine default data directory for operating system.
|
||||
*/
|
||||
QString getDefaultDataDirectory();
|
||||
|
||||
/** Get save filename, mimics QFileDialog::getSaveFileName, except that it appends a default suffix
|
||||
when no suffix is provided by the user.
|
||||
|
||||
|
@ -170,7 +170,7 @@ QString Intro::getDataDirectory()
|
||||
void Intro::setDataDirectory(const QString &dataDir)
|
||||
{
|
||||
ui->dataDirectory->setText(dataDir);
|
||||
if(dataDir == getDefaultDataDirectory())
|
||||
if(dataDir == GUIUtil::getDefaultDataDirectory())
|
||||
{
|
||||
ui->dataDirDefault->setChecked(true);
|
||||
ui->dataDirectory->setEnabled(false);
|
||||
@ -182,11 +182,6 @@ void Intro::setDataDirectory(const QString &dataDir)
|
||||
}
|
||||
}
|
||||
|
||||
QString Intro::getDefaultDataDirectory()
|
||||
{
|
||||
return GUIUtil::boostPathToQString(GetDefaultDataDir());
|
||||
}
|
||||
|
||||
bool Intro::pickDataDirectory(interfaces::Node& node)
|
||||
{
|
||||
QSettings settings;
|
||||
@ -195,13 +190,13 @@ bool Intro::pickDataDirectory(interfaces::Node& node)
|
||||
if(!gArgs.GetArg("-datadir", "").empty())
|
||||
return true;
|
||||
/* 1) Default data directory for operating system */
|
||||
QString dataDirDefaultCurrent = getDefaultDataDirectory();
|
||||
QString dataDirDefaultCurrent = GUIUtil::getDefaultDataDirectory();
|
||||
/* 2) Allow QSettings to override default dir */
|
||||
QString dataDir = settings.value("strDataDir", dataDirDefaultCurrent).toString();
|
||||
/* 3) Check to see if default datadir is the one we expect */
|
||||
QString dataDirDefaultSettings = settings.value("strDataDirDefault").toString();
|
||||
|
||||
if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || gArgs.GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR) || dataDirDefaultCurrent != dataDirDefaultSettings)
|
||||
if(!fs::exists(GUIUtil::qstringToBoostPath(dataDir)) || gArgs.GetBoolArg("-choosedatadir", DEFAULT_CHOOSE_DATADIR) || dataDirDefaultCurrent != dataDirDefaultSettings || settings.value("fReset", false).toBool() || gArgs.GetBoolArg("-resetguisettings", false))
|
||||
{
|
||||
/* Use selectParams here to guarantee Params() can be used by node interface */
|
||||
try {
|
||||
@ -240,12 +235,13 @@ bool Intro::pickDataDirectory(interfaces::Node& node)
|
||||
|
||||
settings.setValue("strDataDir", dataDir);
|
||||
settings.setValue("strDataDirDefault", dataDirDefaultCurrent);
|
||||
settings.setValue("fReset", false);
|
||||
}
|
||||
/* Only override -datadir if different from the default, to make it possible to
|
||||
* override -datadir in the dash.conf file in the default data directory
|
||||
* (to be consistent with dashd behavior)
|
||||
*/
|
||||
if(dataDir != dataDirDefaultCurrent) {
|
||||
if(dataDir != GUIUtil::getDefaultDataDirectory()) {
|
||||
node.softSetArg("-datadir", GUIUtil::qstringToBoostPath(dataDir).string()); // use OS locale for path setting
|
||||
}
|
||||
return true;
|
||||
@ -299,7 +295,7 @@ void Intro::on_ellipsisButton_clicked()
|
||||
|
||||
void Intro::on_dataDirDefault_clicked()
|
||||
{
|
||||
setDataDirectory(getDefaultDataDirectory());
|
||||
setDataDirectory(GUIUtil::getDefaultDataDirectory());
|
||||
}
|
||||
|
||||
void Intro::on_dataDirCustom_clicked()
|
||||
|
@ -48,11 +48,6 @@ public:
|
||||
*/
|
||||
static bool pickDataDirectory(interfaces::Node& node);
|
||||
|
||||
/**
|
||||
* Determine default data directory for operating system.
|
||||
*/
|
||||
static QString getDefaultDataDirectory();
|
||||
|
||||
Q_SIGNALS:
|
||||
void requestCheck();
|
||||
|
||||
|
@ -208,6 +208,9 @@ void OptionsModel::Init(bool resetSettings)
|
||||
if (!m_node.softSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString()))
|
||||
addOverriddenOption("-par");
|
||||
|
||||
if (!settings.contains("strDataDir"))
|
||||
settings.setValue("strDataDir", GUIUtil::getDefaultDataDirectory());
|
||||
|
||||
// Wallet
|
||||
#ifdef ENABLE_WALLET
|
||||
if (!settings.contains("bSpendZeroConfChange"))
|
||||
@ -306,9 +309,19 @@ void OptionsModel::Reset()
|
||||
// Backup old settings to chain-specific datadir for troubleshooting
|
||||
BackupSettings(GetDataDir(true) / "guisettings.ini.bak", settings);
|
||||
|
||||
// Save the strDataDir setting
|
||||
QString dataDir = GUIUtil::getDefaultDataDirectory();
|
||||
dataDir = settings.value("strDataDir", dataDir).toString();
|
||||
|
||||
// Remove all entries from our QSettings object
|
||||
settings.clear();
|
||||
|
||||
// Set strDataDir
|
||||
settings.setValue("strDataDir", dataDir);
|
||||
|
||||
// Set that this was reset
|
||||
settings.setValue("fReset", true);
|
||||
|
||||
// default setting for OptionsModel::StartAtStartup - disabled
|
||||
if (GUIUtil::GetStartOnSystemStartup())
|
||||
GUIUtil::SetStartOnSystemStartup(false);
|
||||
|
@ -242,7 +242,7 @@ bool CCryptoKeyStore::Lock(bool fAllowMixing)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly)
|
||||
bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly, bool accept_no_keys)
|
||||
{
|
||||
{
|
||||
LOCK(cs_KeyStore);
|
||||
@ -271,7 +271,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixin
|
||||
LogPrintf("The wallet is probably corrupted: Some keys decrypt but not all.\n");
|
||||
throw std::runtime_error("Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
|
||||
}
|
||||
if (keyFail || (!keyPass && cryptedHDChain.IsNull()))
|
||||
if (keyFail || (!keyPass && cryptedHDChain.IsNull() && !accept_no_keys))
|
||||
return false;
|
||||
|
||||
vMasterKey = vMasterKeyIn;
|
||||
|
@ -140,7 +140,7 @@ protected:
|
||||
bool SetHDChain(const CHDChain& chain);
|
||||
bool SetCryptedHDChain(const CHDChain& chain);
|
||||
|
||||
bool Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly = false);
|
||||
bool Unlock(const CKeyingMaterial& vMasterKeyIn, bool fForMixingOnly = false, bool accept_no_keys = false);
|
||||
CryptedKeyMap mapCryptedKeys GUARDED_BY(cs_KeyStore);
|
||||
|
||||
public:
|
||||
|
@ -579,7 +579,7 @@ bool CWallet::LoadWatchOnly(const CScript &dest)
|
||||
return CCryptoKeyStore::AddWatchOnly(dest);
|
||||
}
|
||||
|
||||
bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool fForMixingOnly)
|
||||
bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool fForMixingOnly, bool accept_no_keys)
|
||||
{
|
||||
SecureString strWalletPassphraseFinal;
|
||||
|
||||
@ -609,7 +609,7 @@ bool CWallet::Unlock(const SecureString& strWalletPassphrase, bool fForMixingOnl
|
||||
return false;
|
||||
if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
|
||||
continue; // try another master key
|
||||
if (CCryptoKeyStore::Unlock(_vMasterKey, fForMixingOnly)) {
|
||||
if (CCryptoKeyStore::Unlock(_vMasterKey, fForMixingOnly, accept_no_keys)) {
|
||||
if(nWalletBackups == -2) {
|
||||
TopUpKeyPool();
|
||||
WalletLogPrintf("Keypool replenished, re-initializing automatic backups.\n");
|
||||
@ -4154,7 +4154,10 @@ bool CWallet::NewKeyPool()
|
||||
batch.ErasePool(nIndex);
|
||||
}
|
||||
setExternalKeyPool.clear();
|
||||
coinJoinClientManagers.at(GetName())->StopMixing();
|
||||
auto it = coinJoinClientManagers.find(GetName());
|
||||
if (it != coinJoinClientManagers.end()) {
|
||||
it->second->StopMixing();
|
||||
}
|
||||
nKeysLeftSinceAutoBackup = 0;
|
||||
|
||||
m_pool_key_to_index.clear();
|
||||
|
@ -979,7 +979,7 @@ public:
|
||||
//! Holds a timestamp at which point the wallet is scheduled (externally) to be relocked. Caller must arrange for actual relocking to occur via Lock().
|
||||
int64_t nRelockTime = 0;
|
||||
|
||||
bool Unlock(const SecureString& strWalletPassphrase, bool fForMixingOnly = false);
|
||||
bool Unlock(const SecureString& strWalletPassphrase, bool fForMixingOnly = false, bool accept_no_keys = false);
|
||||
bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
|
||||
bool EncryptWallet(const SecureString& strWalletPassphrase);
|
||||
|
||||
|
140
src/wallet/wallettool.cpp
Normal file
140
src/wallet/wallettool.cpp
Normal file
@ -0,0 +1,140 @@
|
||||
// Copyright (c) 2016-2018 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 <base58.h>
|
||||
#include <fs.h>
|
||||
#include <interfaces/chain.h>
|
||||
#include <util/system.h>
|
||||
#include <wallet/wallet.h>
|
||||
#include <wallet/walletutil.h>
|
||||
|
||||
namespace WalletTool {
|
||||
|
||||
// The standard wallet deleter function blocks on the validation interface
|
||||
// queue, which doesn't exist for the dash-wallet. Define our own
|
||||
// deleter here.
|
||||
static void WalletToolReleaseWallet(CWallet* wallet)
|
||||
{
|
||||
wallet->WalletLogPrintf("Releasing wallet\n");
|
||||
wallet->Flush();
|
||||
delete wallet;
|
||||
}
|
||||
|
||||
static std::shared_ptr<CWallet> CreateWallet(const std::string& name, const fs::path& path)
|
||||
{
|
||||
if (fs::exists(path)) {
|
||||
tfm::format(std::cerr, "Error: File exists already\n");
|
||||
return nullptr;
|
||||
}
|
||||
// dummy chain interface
|
||||
auto chain = interfaces::MakeChain();
|
||||
std::shared_ptr<CWallet> wallet_instance(new CWallet(*chain, WalletLocation(name), WalletDatabase::Create(path)), WalletToolReleaseWallet);
|
||||
bool first_run = true;
|
||||
DBErrors load_wallet_ret = wallet_instance->LoadWallet(first_run);
|
||||
if (load_wallet_ret != DBErrors::LOAD_OK) {
|
||||
tfm::format(std::cerr, "Error creating %s", name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
wallet_instance->SetMinVersion(FEATURE_HD);
|
||||
|
||||
// generate a new HD seed
|
||||
// NOTE: we do not yet create HD wallets by default
|
||||
// wallet_instance->GenerateNewHDChain("", "");
|
||||
|
||||
tfm::format(std::cout, "Topping up keypool...\n");
|
||||
wallet_instance->TopUpKeyPool();
|
||||
return wallet_instance;
|
||||
}
|
||||
|
||||
static std::shared_ptr<CWallet> LoadWallet(const std::string& name, const fs::path& path)
|
||||
{
|
||||
if (!fs::exists(path)) {
|
||||
tfm::format(std::cerr, "Error: Wallet files does not exist\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// dummy chain interface
|
||||
auto chain = interfaces::MakeChain();
|
||||
std::shared_ptr<CWallet> wallet_instance(new CWallet(*chain, WalletLocation(name), WalletDatabase::Create(path)), WalletToolReleaseWallet);
|
||||
DBErrors load_wallet_ret;
|
||||
try {
|
||||
bool first_run;
|
||||
load_wallet_ret = wallet_instance->LoadWallet(first_run);
|
||||
} catch (const std::runtime_error) {
|
||||
tfm::format(std::cerr, "Error loading %s. Is wallet being used by another process?\n", name);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (load_wallet_ret != DBErrors::LOAD_OK) {
|
||||
wallet_instance = nullptr;
|
||||
if (load_wallet_ret == DBErrors::CORRUPT) {
|
||||
tfm::format(std::cerr, "Error loading %s: Wallet corrupted", name);
|
||||
return nullptr;
|
||||
} else if (load_wallet_ret == DBErrors::NONCRITICAL_ERROR) {
|
||||
tfm::format(std::cerr, "Error reading %s! All keys read correctly, but transaction data"
|
||||
" or address book entries might be missing or incorrect.",
|
||||
name);
|
||||
} else if (load_wallet_ret == DBErrors::TOO_NEW) {
|
||||
tfm::format(std::cerr, "Error loading %s: Wallet requires newer version of %s",
|
||||
name, PACKAGE_NAME);
|
||||
return nullptr;
|
||||
} else if (load_wallet_ret == DBErrors::NEED_REWRITE) {
|
||||
tfm::format(std::cerr, "Wallet needed to be rewritten: restart %s to complete", PACKAGE_NAME);
|
||||
return nullptr;
|
||||
} else {
|
||||
tfm::format(std::cerr, "Error loading %s", name);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return wallet_instance;
|
||||
}
|
||||
|
||||
static void WalletShowInfo(CWallet* wallet_instance)
|
||||
{
|
||||
// lock required because of some AssertLockHeld()
|
||||
LOCK(wallet_instance->cs_wallet);
|
||||
|
||||
CHDChain hdChainTmp;
|
||||
tfm::format(std::cout, "Wallet info\n===========\n");
|
||||
tfm::format(std::cout, "Encrypted: %s\n", wallet_instance->IsCrypted() ? "yes" : "no");
|
||||
tfm::format(std::cout, "HD (hd seed available): %s\n", wallet_instance->GetHDChain(hdChainTmp) ? "yes" : "no");
|
||||
tfm::format(std::cout, "Keypool Size: %u\n", wallet_instance->GetKeyPoolSize());
|
||||
tfm::format(std::cout, "Transactions: %zu\n", wallet_instance->mapWallet.size());
|
||||
tfm::format(std::cout, "Address Book: %zu\n", wallet_instance->mapAddressBook.size());
|
||||
}
|
||||
|
||||
bool ExecuteWalletToolFunc(const std::string& command, const std::string& name)
|
||||
{
|
||||
fs::path path = fs::absolute(name, GetWalletDir());
|
||||
|
||||
if (command == "create") {
|
||||
std::shared_ptr<CWallet> wallet_instance = CreateWallet(name, path);
|
||||
if (wallet_instance) {
|
||||
WalletShowInfo(wallet_instance.get());
|
||||
wallet_instance->Flush();
|
||||
}
|
||||
} else if (command == "info") {
|
||||
if (!fs::exists(path)) {
|
||||
tfm::format(std::cerr, "Error: no wallet file at %s\n", name);
|
||||
return false;
|
||||
}
|
||||
std::string error;
|
||||
if (!WalletBatch::VerifyEnvironment(path, error)) {
|
||||
tfm::format(std::cerr, "Error loading %s. Is wallet being used by other process?\n", name);
|
||||
return false;
|
||||
}
|
||||
std::shared_ptr<CWallet> wallet_instance = LoadWallet(name, path);
|
||||
if (!wallet_instance) return false;
|
||||
WalletShowInfo(wallet_instance.get());
|
||||
wallet_instance->Flush();
|
||||
} else {
|
||||
tfm::format(std::cerr, "Invalid command: %s\n", command);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace WalletTool
|
20
src/wallet/wallettool.h
Normal file
20
src/wallet/wallettool.h
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2016-2018 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_WALLETTOOL_H
|
||||
#define BITCOIN_WALLET_WALLETTOOL_H
|
||||
|
||||
#include <script/ismine.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
namespace WalletTool {
|
||||
|
||||
std::shared_ptr<CWallet> CreateWallet(const std::string& name, const fs::path& path);
|
||||
std::shared_ptr<CWallet> LoadWallet(const std::string& name, const fs::path& path);
|
||||
void WalletShowInfo(CWallet* wallet_instance);
|
||||
bool ExecuteWalletToolFunc(const std::string& command, const std::string& file);
|
||||
|
||||
} // namespace WalletTool
|
||||
|
||||
#endif // BITCOIN_WALLET_WALLETTOOL_H
|
@ -6,6 +6,7 @@
|
||||
# test/functional/test_runner.py and test/util/bitcoin-util-test.py
|
||||
|
||||
[environment]
|
||||
PACKAGE_NAME=@PACKAGE_NAME@
|
||||
SRCDIR=@abs_top_srcdir@
|
||||
BUILDDIR=@abs_top_builddir@
|
||||
EXEEXT=@EXEEXT@
|
||||
|
@ -23,7 +23,7 @@ class FilelockTest(BitcoinTestFramework):
|
||||
self.log.info("Using datadir {}".format(datadir))
|
||||
|
||||
self.log.info("Check that we can't start a second dashd instance using the same datadir")
|
||||
expected_msg = "Error: Cannot obtain a lock on data directory {}. Dash Core is probably already running.".format(datadir)
|
||||
expected_msg = "Error: Cannot obtain a lock on data directory {0}. {1} is probably already running.".format(datadir, self.config['environment']['PACKAGE_NAME'])
|
||||
self.nodes[1].assert_start_raises_init_error(extra_args=['-datadir={}'.format(self.nodes[0].datadir), '-noserver'], expected_msg=expected_msg)
|
||||
|
||||
if self.is_wallet_compiled():
|
||||
|
@ -16,7 +16,7 @@ class TestBitcoinCli(BitcoinTestFramework):
|
||||
"""Main test logic"""
|
||||
|
||||
cli_response = self.nodes[0].cli("-version").send_cli()
|
||||
assert "Dash Core RPC client version" in cli_response
|
||||
assert "{} RPC client version".format(self.config['environment']['PACKAGE_NAME']) in cli_response
|
||||
|
||||
self.log.info("Compare responses from getwalletinfo RPC and `dash-cli getwalletinfo`")
|
||||
if self.is_wallet_compiled():
|
||||
|
@ -179,6 +179,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
config.read_file(open(self.options.configfile))
|
||||
self.config = config
|
||||
self.options.bitcoind = os.getenv("BITCOIND", default=config["environment"]["BUILDDIR"] + '/src/dashd' + config["environment"]["EXEEXT"])
|
||||
self.options.bitcoincli = os.getenv("BITCOINCLI", default=config["environment"]["BUILDDIR"] + '/src/dash-cli' + config["environment"]["EXEEXT"])
|
||||
|
||||
|
@ -120,6 +120,7 @@ BASE_SCRIPTS = [
|
||||
'interface_bitcoin_cli.py',
|
||||
'mempool_resurrect.py',
|
||||
'wallet_txn_doublespend.py --mineblock',
|
||||
'tool_wallet.py',
|
||||
'wallet_txn_clone.py',
|
||||
'rpc_getchaintips.py',
|
||||
'rpc_misc.py',
|
||||
@ -606,7 +607,7 @@ class TestResult():
|
||||
def check_script_prefixes():
|
||||
"""Check that test scripts start with one of the allowed name prefixes."""
|
||||
|
||||
good_prefixes_re = re.compile("(example|feature|interface|mempool|mining|p2p|rpc|wallet)_")
|
||||
good_prefixes_re = re.compile("(example|feature|interface|mempool|mining|p2p|rpc|wallet|tool)_")
|
||||
bad_script_names = [script for script in ALL_SCRIPTS if good_prefixes_re.match(script) is None]
|
||||
|
||||
if bad_script_names:
|
||||
|
114
test/functional/tool_wallet.py
Executable file
114
test/functional/tool_wallet.py
Executable file
@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2018 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Test dash-wallet."""
|
||||
import subprocess
|
||||
import textwrap
|
||||
|
||||
from test_framework.test_framework import BitcoinTestFramework
|
||||
from test_framework.util import assert_equal
|
||||
|
||||
class ToolWalletTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 1
|
||||
self.setup_clean_chain = True
|
||||
|
||||
def skip_test_if_missing_module(self):
|
||||
self.skip_if_no_wallet()
|
||||
|
||||
def dash_wallet_process(self, *args):
|
||||
binary = self.config["environment"]["BUILDDIR"] + '/src/dash-wallet' + self.config["environment"]["EXEEXT"]
|
||||
args = ['-datadir={}'.format(self.nodes[0].datadir), '-regtest'] + list(args)
|
||||
return subprocess.Popen([binary] + args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
|
||||
|
||||
def assert_raises_tool_error(self, error, *args):
|
||||
p = self.dash_wallet_process(*args)
|
||||
stdout, stderr = p.communicate()
|
||||
assert_equal(p.poll(), 1)
|
||||
assert_equal(stdout, '')
|
||||
assert_equal(stderr.strip(), error)
|
||||
|
||||
def assert_tool_output(self, output, *args):
|
||||
p = self.dash_wallet_process(*args)
|
||||
stdout, stderr = p.communicate()
|
||||
assert_equal(p.poll(), 0)
|
||||
assert_equal(stderr, '')
|
||||
assert_equal(stdout, output)
|
||||
|
||||
def run_test(self):
|
||||
|
||||
self.assert_raises_tool_error('Invalid command: foo', 'foo')
|
||||
# `dash-wallet help` is an error. Use `dash-wallet -help`
|
||||
self.assert_raises_tool_error('Invalid command: help', 'help')
|
||||
self.assert_raises_tool_error('Error: two methods provided (info and create). Only one method should be provided.', 'info', 'create')
|
||||
self.assert_raises_tool_error('Error parsing command line arguments: Invalid parameter -foo', '-foo')
|
||||
self.assert_raises_tool_error('Error loading wallet.dat. Is wallet being used by other process?', '-wallet=wallet.dat', 'info')
|
||||
self.assert_raises_tool_error('Error: no wallet file at nonexistent.dat', '-wallet=nonexistent.dat', 'info')
|
||||
|
||||
# stop the node to close the wallet to call info command
|
||||
self.stop_node(0)
|
||||
|
||||
out = textwrap.dedent('''\
|
||||
Wallet info
|
||||
===========
|
||||
Encrypted: no
|
||||
HD (hd seed available): no
|
||||
Keypool Size: 1
|
||||
Transactions: 0
|
||||
Address Book: 0
|
||||
''')
|
||||
self.assert_tool_output(out, '-wallet=wallet.dat', 'info')
|
||||
|
||||
self.start_node(0)
|
||||
self.nodes[0].upgradetohd()
|
||||
self.stop_node(0)
|
||||
|
||||
out = textwrap.dedent('''\
|
||||
Wallet info
|
||||
===========
|
||||
Encrypted: no
|
||||
HD (hd seed available): yes
|
||||
Keypool Size: 2
|
||||
Transactions: 0
|
||||
Address Book: 0
|
||||
''')
|
||||
self.assert_tool_output(out, '-wallet=wallet.dat', 'info')
|
||||
|
||||
# mutate the wallet to check the info command output changes accordingly
|
||||
self.start_node(0)
|
||||
self.nodes[0].generate(1)
|
||||
self.stop_node(0)
|
||||
|
||||
out = textwrap.dedent('''\
|
||||
Wallet info
|
||||
===========
|
||||
Encrypted: no
|
||||
HD (hd seed available): yes
|
||||
Keypool Size: 1
|
||||
Transactions: 1
|
||||
Address Book: 0
|
||||
''')
|
||||
self.assert_tool_output(out, '-wallet=wallet.dat', 'info')
|
||||
|
||||
out = textwrap.dedent('''\
|
||||
Topping up keypool...
|
||||
Wallet info
|
||||
===========
|
||||
Encrypted: no
|
||||
HD (hd seed available): no
|
||||
Keypool Size: 1000
|
||||
Transactions: 0
|
||||
Address Book: 0
|
||||
''')
|
||||
self.assert_tool_output(out, '-wallet=foo', 'create')
|
||||
|
||||
self.start_node(0, ['-wallet=foo'])
|
||||
out = self.nodes[0].getwalletinfo()
|
||||
self.stop_node(0)
|
||||
|
||||
assert_equal(0, out['txcount'])
|
||||
assert_equal(1000, out['keypoolsize'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
ToolWalletTest().main()
|
Loading…
Reference in New Issue
Block a user