From 1e688b739f23d43c685231d5e9ee422e6a7fc01e Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 14:20:36 +0100 Subject: [PATCH 01/12] [wallet] Add walletinit.cpp This commit adds a new walletinit translation unit and moves GetWalletHelpString() to walletinit from a static member function of CWallet. Apart from adding the new translation unit, this is a MOVE-ONLY commit. --- src/Makefile.am | 2 ++ src/init.cpp | 3 ++- src/wallet/wallet.cpp | 37 ------------------------------------- src/wallet/wallet.h | 3 --- src/wallet/walletinit.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/wallet/walletinit.h | 11 +++++++++++ 6 files changed, 61 insertions(+), 41 deletions(-) create mode 100644 src/wallet/walletinit.cpp create mode 100644 src/wallet/walletinit.h diff --git a/src/Makefile.am b/src/Makefile.am index 06b09404a76..96963ff5abc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -165,6 +165,7 @@ BITCOIN_CORE_H = \ wallet/rpcwallet.h \ wallet/wallet.h \ wallet/walletdb.h \ + wallet/walletinit.h \ warnings.h \ zmq/zmqabstractnotifier.h \ zmq/zmqconfig.h\ @@ -243,6 +244,7 @@ libbitcoin_wallet_a_SOURCES = \ wallet/rpcwallet.cpp \ wallet/wallet.cpp \ wallet/walletdb.cpp \ + wallet/walletinit.cpp \ $(BITCOIN_CORE_H) # crypto primitives library diff --git a/src/init.cpp b/src/init.cpp index 672ef77e80f..befffc4ac10 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -44,6 +44,7 @@ #include "validationinterface.h" #ifdef ENABLE_WALLET #include "wallet/wallet.h" +#include "wallet/walletinit.h" #endif #include "warnings.h" #include @@ -404,7 +405,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-maxuploadtarget=", strprintf(_("Tries to keep outbound traffic under the given target (in MiB per 24h), 0 = no limit (default: %d)"), DEFAULT_MAX_UPLOAD_TARGET)); #ifdef ENABLE_WALLET - strUsage += CWallet::GetWalletHelpString(showDebug); + strUsage += GetWalletHelpString(showDebug); #endif #if ENABLE_ZMQ diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 0d1a86dd244..19ddc468892 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3731,43 +3731,6 @@ std::vector CWallet::GetDestValues(const std::string& prefix) const return values; } -std::string CWallet::GetWalletHelpString(bool showDebug) -{ - std::string strUsage = HelpMessageGroup(_("Wallet options:")); - strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); - strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), DEFAULT_KEYPOOL_SIZE)); - strUsage += HelpMessageOpt("-fallbackfee=", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), - CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); - strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), - CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); - strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), - CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); - strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); - strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup")); - strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); - strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); - strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); - strUsage += HelpMessageOpt("-walletrbf", strprintf(_("Send transactions with full-RBF opt-in enabled (default: %u)"), DEFAULT_WALLET_RBF)); - strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); - strUsage += HelpMessageOpt("-wallet=", _("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("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); - strUsage += HelpMessageOpt("-zapwallettxes=", _("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)")); - - if (showDebug) - { - strUsage += HelpMessageGroup(_("Wallet debugging/testing options:")); - - strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); - strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); - strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); - strUsage += HelpMessageOpt("-walletrejectlongchains", strprintf(_("Wallet will not create transactions that violate mempool chain limits (default: %u)"), DEFAULT_WALLET_REJECT_LONG_CHAINS)); - } - - return strUsage; -} - CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) { // needed to restore wallet transaction meta data after -zapwallettxes diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 4f558adc772..af60edd2ee1 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1092,9 +1092,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface /** Mark a transaction as replaced by another transaction (e.g., BIP 125). */ bool MarkReplaced(const uint256& originalHash, const uint256& newHash); - /* Returns the wallets help message */ - static std::string GetWalletHelpString(bool showDebug); - /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ static CWallet* CreateWalletFromFile(const std::string walletFile); static bool InitLoadWallet(); diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp new file mode 100644 index 00000000000..f1f08456dc3 --- /dev/null +++ b/src/wallet/walletinit.cpp @@ -0,0 +1,46 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 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 "util.h" +#include "utilmoneystr.h" +#include "wallet/walletinit.h" + +std::string GetWalletHelpString(bool showDebug) +{ + std::string strUsage = HelpMessageGroup(_("Wallet options:")); + strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); + strUsage += HelpMessageOpt("-keypool=", strprintf(_("Set key pool size to (default: %u)"), DEFAULT_KEYPOOL_SIZE)); + strUsage += HelpMessageOpt("-fallbackfee=", strprintf(_("A fee rate (in %s/kB) that will be used when fee estimation has insufficient data (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_FALLBACK_FEE))); + strUsage += HelpMessageOpt("-mintxfee=", strprintf(_("Fees (in %s/kB) smaller than this are considered zero fee for transaction creation (default: %s)"), + CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MINFEE))); + strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), + CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); + strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); + strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup")); + strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); + strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); + strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP32. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); + strUsage += HelpMessageOpt("-walletrbf", strprintf(_("Send transactions with full-RBF opt-in enabled (default: %u)"), DEFAULT_WALLET_RBF)); + strUsage += HelpMessageOpt("-upgradewallet", _("Upgrade wallet to latest format on startup")); + strUsage += HelpMessageOpt("-wallet=", _("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("-walletnotify=", _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)")); + strUsage += HelpMessageOpt("-zapwallettxes=", _("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)")); + + if (showDebug) + { + strUsage += HelpMessageGroup(_("Wallet debugging/testing options:")); + + strUsage += HelpMessageOpt("-dblogsize=", strprintf("Flush wallet database activity from memory to disk log every megabytes (default: %u)", DEFAULT_WALLET_DBLOGSIZE)); + strUsage += HelpMessageOpt("-flushwallet", strprintf("Run a thread to flush wallet periodically (default: %u)", DEFAULT_FLUSHWALLET)); + strUsage += HelpMessageOpt("-privdb", strprintf("Sets the DB_PRIVATE flag in the wallet db environment (default: %u)", DEFAULT_WALLET_PRIVDB)); + strUsage += HelpMessageOpt("-walletrejectlongchains", strprintf(_("Wallet will not create transactions that violate mempool chain limits (default: %u)"), DEFAULT_WALLET_REJECT_LONG_CHAINS)); + } + + return strUsage; +} + diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h new file mode 100644 index 00000000000..e0ddd8f12c2 --- /dev/null +++ b/src/wallet/walletinit.h @@ -0,0 +1,11 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2016 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/wallet.h" + +#include + +//!Returns the wallets help message +std::string GetWalletHelpString(bool showDebug); From f548c07a9fd408e3b8c7a576ac8920942353e7fb Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 14:37:10 +0100 Subject: [PATCH 02/12] [wallet] Move WalletParameterInteraction() to walletinit.cpp This is a MOVE-ONLY commit. --- src/init.cpp | 3 +- src/wallet/wallet.cpp | 100 --------------------------------------------- src/wallet/wallet.h | 3 -- src/wallet/walletinit.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++++ src/wallet/walletinit.h | 4 ++ 5 files changed, 107 insertions(+), 105 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index befffc4ac10..19fc2ba96af 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1053,8 +1053,7 @@ bool AppInitParameterInteraction() nBytesPerSigOp = GetArg("-bytespersigop", nBytesPerSigOp); #ifdef ENABLE_WALLET - if (!CWallet::ParameterInteraction()) - return false; + if (!WalletParameterInteraction()) return false; #endif fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 19ddc468892..6ee5e528864 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3953,106 +3953,6 @@ void CWallet::postInitProcess(CScheduler& scheduler) } } -bool CWallet::ParameterInteraction() -{ - SoftSetArg("-wallet", DEFAULT_WALLET_DAT); - const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1; - - if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) - return true; - - if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && SoftSetBoolArg("-walletbroadcast", false)) { - LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__); - } - - if (GetBoolArg("-salvagewallet", false) && SoftSetBoolArg("-rescan", true)) { - if (is_multiwallet) { - return InitError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet")); - } - // Rewrite just private keys: rescan to find transactions - LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); - } - - // -zapwallettx implies a rescan - if (GetBoolArg("-zapwallettxes", false) && SoftSetBoolArg("-rescan", true)) { - if (is_multiwallet) { - return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes")); - } - LogPrintf("%s: parameter interaction: -zapwallettxes= -> setting -rescan=1\n", __func__); - } - - if (is_multiwallet) { - if (GetBoolArg("-upgradewallet", false)) { - return InitError(strprintf("%s is only allowed with a single wallet file", "-upgradewallet")); - } - } - - if (GetBoolArg("-sysperms", false)) - return InitError("-sysperms is not allowed in combination with enabled wallet functionality"); - if (GetArg("-prune", 0) && GetBoolArg("-rescan", false)) - return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.")); - - if (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB) - InitWarning(AmountHighWarn("-minrelaytxfee") + " " + - _("The wallet will avoid paying less than the minimum relay fee.")); - - if (IsArgSet("-mintxfee")) - { - CAmount n = 0; - if (!ParseMoney(GetArg("-mintxfee", ""), n) || 0 == n) - return InitError(AmountErrMsg("mintxfee", GetArg("-mintxfee", ""))); - if (n > HIGH_TX_FEE_PER_KB) - InitWarning(AmountHighWarn("-mintxfee") + " " + - _("This is the minimum transaction fee you pay on every transaction.")); - CWallet::minTxFee = CFeeRate(n); - } - if (IsArgSet("-fallbackfee")) - { - CAmount nFeePerK = 0; - if (!ParseMoney(GetArg("-fallbackfee", ""), nFeePerK)) - return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), GetArg("-fallbackfee", ""))); - if (nFeePerK > HIGH_TX_FEE_PER_KB) - InitWarning(AmountHighWarn("-fallbackfee") + " " + - _("This is the transaction fee you may pay when fee estimates are not available.")); - CWallet::fallbackFee = CFeeRate(nFeePerK); - } - if (IsArgSet("-paytxfee")) - { - CAmount nFeePerK = 0; - if (!ParseMoney(GetArg("-paytxfee", ""), nFeePerK)) - return InitError(AmountErrMsg("paytxfee", GetArg("-paytxfee", ""))); - if (nFeePerK > HIGH_TX_FEE_PER_KB) - InitWarning(AmountHighWarn("-paytxfee") + " " + - _("This is the transaction fee you will pay if you send a transaction.")); - - payTxFee = CFeeRate(nFeePerK, 1000); - if (payTxFee < ::minRelayTxFee) - { - return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s' (must be at least %s)"), - GetArg("-paytxfee", ""), ::minRelayTxFee.ToString())); - } - } - if (IsArgSet("-maxtxfee")) - { - CAmount nMaxFee = 0; - if (!ParseMoney(GetArg("-maxtxfee", ""), nMaxFee)) - return InitError(AmountErrMsg("maxtxfee", GetArg("-maxtxfee", ""))); - if (nMaxFee > HIGH_MAX_TX_FEE) - InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); - maxTxFee = nMaxFee; - if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) - { - return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), - GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString())); - } - } - nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); - bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); - fWalletRbf = GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF); - - return true; -} - bool CWallet::BackupWallet(const std::string& strDest) { return dbw->Backup(strDest); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index af60edd2ee1..6762ada68e3 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1102,9 +1102,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface */ void postInitProcess(CScheduler& scheduler); - /* Wallets parameter interaction */ - static bool ParameterInteraction(); - bool BackupWallet(const std::string& strDest); /* Set the HD chain model (chain child index counters) */ diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index f1f08456dc3..3871a9459f8 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -3,8 +3,10 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "net.h" #include "util.h" #include "utilmoneystr.h" +#include "validation.h" #include "wallet/walletinit.h" std::string GetWalletHelpString(bool showDebug) @@ -44,3 +46,103 @@ std::string GetWalletHelpString(bool showDebug) return strUsage; } +bool WalletParameterInteraction() +{ + SoftSetArg("-wallet", DEFAULT_WALLET_DAT); + const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1; + + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) + return true; + + if (GetBoolArg("-blocksonly", DEFAULT_BLOCKSONLY) && SoftSetBoolArg("-walletbroadcast", false)) { + LogPrintf("%s: parameter interaction: -blocksonly=1 -> setting -walletbroadcast=0\n", __func__); + } + + if (GetBoolArg("-salvagewallet", false) && SoftSetBoolArg("-rescan", true)) { + if (is_multiwallet) { + return InitError(strprintf("%s is only allowed with a single wallet file", "-salvagewallet")); + } + // Rewrite just private keys: rescan to find transactions + LogPrintf("%s: parameter interaction: -salvagewallet=1 -> setting -rescan=1\n", __func__); + } + + // -zapwallettx implies a rescan + if (GetBoolArg("-zapwallettxes", false) && SoftSetBoolArg("-rescan", true)) { + if (is_multiwallet) { + return InitError(strprintf("%s is only allowed with a single wallet file", "-zapwallettxes")); + } + LogPrintf("%s: parameter interaction: -zapwallettxes= -> setting -rescan=1\n", __func__); + } + + if (is_multiwallet) { + if (GetBoolArg("-upgradewallet", false)) { + return InitError(strprintf("%s is only allowed with a single wallet file", "-upgradewallet")); + } + } + + if (GetBoolArg("-sysperms", false)) + return InitError("-sysperms is not allowed in combination with enabled wallet functionality"); + if (GetArg("-prune", 0) && GetBoolArg("-rescan", false)) + return InitError(_("Rescans are not possible in pruned mode. You will need to use -reindex which will download the whole blockchain again.")); + + if (::minRelayTxFee.GetFeePerK() > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-minrelaytxfee") + " " + + _("The wallet will avoid paying less than the minimum relay fee.")); + + if (IsArgSet("-mintxfee")) + { + CAmount n = 0; + if (!ParseMoney(GetArg("-mintxfee", ""), n) || 0 == n) + return InitError(AmountErrMsg("mintxfee", GetArg("-mintxfee", ""))); + if (n > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-mintxfee") + " " + + _("This is the minimum transaction fee you pay on every transaction.")); + CWallet::minTxFee = CFeeRate(n); + } + if (IsArgSet("-fallbackfee")) + { + CAmount nFeePerK = 0; + if (!ParseMoney(GetArg("-fallbackfee", ""), nFeePerK)) + return InitError(strprintf(_("Invalid amount for -fallbackfee=: '%s'"), GetArg("-fallbackfee", ""))); + if (nFeePerK > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-fallbackfee") + " " + + _("This is the transaction fee you may pay when fee estimates are not available.")); + CWallet::fallbackFee = CFeeRate(nFeePerK); + } + if (IsArgSet("-paytxfee")) + { + CAmount nFeePerK = 0; + if (!ParseMoney(GetArg("-paytxfee", ""), nFeePerK)) + return InitError(AmountErrMsg("paytxfee", GetArg("-paytxfee", ""))); + if (nFeePerK > HIGH_TX_FEE_PER_KB) + InitWarning(AmountHighWarn("-paytxfee") + " " + + _("This is the transaction fee you will pay if you send a transaction.")); + + payTxFee = CFeeRate(nFeePerK, 1000); + if (payTxFee < ::minRelayTxFee) + { + return InitError(strprintf(_("Invalid amount for -paytxfee=: '%s' (must be at least %s)"), + GetArg("-paytxfee", ""), ::minRelayTxFee.ToString())); + } + } + if (IsArgSet("-maxtxfee")) + { + CAmount nMaxFee = 0; + if (!ParseMoney(GetArg("-maxtxfee", ""), nMaxFee)) + return InitError(AmountErrMsg("maxtxfee", GetArg("-maxtxfee", ""))); + if (nMaxFee > HIGH_MAX_TX_FEE) + InitWarning(_("-maxtxfee is set very high! Fees this large could be paid on a single transaction.")); + maxTxFee = nMaxFee; + if (CFeeRate(maxTxFee, 1000) < ::minRelayTxFee) + { + return InitError(strprintf(_("Invalid amount for -maxtxfee=: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"), + GetArg("-maxtxfee", ""), ::minRelayTxFee.ToString())); + } + } + nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); + bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); + fWalletRbf = GetBoolArg("-walletrbf", DEFAULT_WALLET_RBF); + + return true; +} + diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index e0ddd8f12c2..8d488f2c45e 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -9,3 +9,7 @@ //!Returns the wallets help message std::string GetWalletHelpString(bool showDebug); + +//!Wallet parameter interaction +bool WalletParameterInteraction(); + From d557f80eb76c570cb0ea26f57800c1d3ab38d542 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Thu, 6 Jul 2017 11:40:47 +0100 Subject: [PATCH 03/12] [wallet] Add RegisterWalletRPC to walletinit.cpp Adds a RegisterWalletRPC() to walletinit.cpp. This just calls through to RegisterWalletRPCCommands() in rpcwallet.cpp. --- src/init.cpp | 2 +- src/wallet/rpcwallet.cpp | 7 +++---- src/wallet/rpcwallet.h | 1 + src/wallet/walletinit.cpp | 6 ++++++ src/wallet/walletinit.h | 5 +++++ 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 19fc2ba96af..e9c11678054 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1008,7 +1008,7 @@ bool AppInitParameterInteraction() RegisterAllCoreRPCCommands(tableRPC); #ifdef ENABLE_WALLET - RegisterWalletRPCCommands(tableRPC); + RegisterWalletRPC(tableRPC); #endif nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 867ccd42444..cbc26a8a8dc 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3038,9 +3038,8 @@ static const CRPCCommand commands[] = void RegisterWalletRPCCommands(CRPCTable &t) { - if (GetBoolArg("-disablewallet", false)) - return; - - for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) + for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) { t.appendCommand(commands[vcidx].name, &commands[vcidx]); + } } + diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index bd5dad18ca5..8219f8f9968 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -7,6 +7,7 @@ class CRPCTable; class JSONRPCRequest; +class CWallet; void RegisterWalletRPCCommands(CRPCTable &t); diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index 3871a9459f8..a60f2009c59 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -146,3 +146,9 @@ bool WalletParameterInteraction() return true; } +void RegisterWalletRPC(CRPCTable &t) +{ + if (GetBoolArg("-disablewallet", false)) return; + + RegisterWalletRPCCommands(t); +} diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index 8d488f2c45e..6fd32a5b8a8 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -3,13 +3,18 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "wallet/rpcwallet.h" #include "wallet/wallet.h" #include +class CRPCTable; + //!Returns the wallets help message std::string GetWalletHelpString(bool showDebug); //!Wallet parameter interaction bool WalletParameterInteraction(); +//!Register Wallet RPC +void RegisterWalletRPC(CRPCTable &t); From 2c3bc2443809e12e37e1a6d3d02420be4e666ef2 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 14:49:48 +0100 Subject: [PATCH 04/12] [wallet] Move VerifyWallets() to walletinit.cpp MOVE-ONLY commit --- src/init.cpp | 3 +-- src/wallet/wallet.cpp | 42 ------------------------------------------ src/wallet/wallet.h | 3 --- src/wallet/walletinit.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/wallet/walletinit.h | 3 +++ 5 files changed, 46 insertions(+), 47 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index e9c11678054..39fd755479b 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1219,8 +1219,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 5: verify wallet database integrity #ifdef ENABLE_WALLET - if (!CWallet::Verify()) - return false; + if (!VerifyWallets()) return false; #endif // ********************************************************* Step 6: network initialization // Note that we absolutely cannot open any actual connections diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 6ee5e528864..3315ec4ebec 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -438,48 +438,6 @@ void CWallet::Flush(bool shutdown) dbw->Flush(shutdown); } -bool CWallet::Verify() -{ - if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) - return true; - - uiInterface.InitMessage(_("Verifying wallet(s)...")); - - for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { - if (boost::filesystem::path(walletFile).filename() != walletFile) { - return InitError(_("-wallet parameter must only specify a filename (not a path)")); - } else if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) { - return InitError(_("Invalid characters in -wallet filename")); - } - - std::string strError; - if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) { - return InitError(strError); - } - - if (GetBoolArg("-salvagewallet", false)) { - // Recover readable keypairs: - CWallet dummyWallet; - std::string backup_filename; - if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) { - return false; - } - } - - std::string strWarning; - bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError); - if (!strWarning.empty()) { - InitWarning(strWarning); - } - if (!dbV) { - InitError(strError); - return false; - } - } - - return true; -} - void CWallet::SyncMetaData(std::pair range) { // We want all the wallet transactions in range to have the same metadata as diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 6762ada68e3..53be4d8b9f4 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1053,9 +1053,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface //! Flush wallet (bitdb flush) void Flush(bool shutdown=false); - //! Verify the wallet database and perform salvage if required - static bool Verify(); - /** * Address book entry changed. * @note called with lock cs_wallet held. diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index a60f2009c59..38917aa7363 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -152,3 +152,45 @@ void RegisterWalletRPC(CRPCTable &t) RegisterWalletRPCCommands(t); } + +bool VerifyWallets() +{ + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) + return true; + + uiInterface.InitMessage(_("Verifying wallet(s)...")); + + for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { + if (boost::filesystem::path(walletFile).filename() != walletFile) { + return InitError(_("-wallet parameter must only specify a filename (not a path)")); + } else if (SanitizeString(walletFile, SAFE_CHARS_FILENAME) != walletFile) { + return InitError(_("Invalid characters in -wallet filename")); + } + + std::string strError; + if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) { + return InitError(strError); + } + + if (GetBoolArg("-salvagewallet", false)) { + // Recover readable keypairs: + CWallet dummyWallet; + std::string backup_filename; + if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) { + return false; + } + } + + std::string strWarning; + bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError); + if (!strWarning.empty()) { + InitWarning(strWarning); + } + if (!dbV) { + InitError(strError); + return false; + } + } + + return true; +} diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index 6fd32a5b8a8..84efdeaf48c 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -18,3 +18,6 @@ bool WalletParameterInteraction(); //!Register Wallet RPC void RegisterWalletRPC(CRPCTable &t); + +//! Verify the wallet database and perform salvage if required +bool VerifyWallets(); From 54b1a437b388aa745cf38b4157ebefdf32215889 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 15:10:13 +0100 Subject: [PATCH 05/12] [wallet] Allow individual wallets to be verified Removes the VerifyEnvironment() functions from CDB and CWalletDB. Environment verification is now done in walletinit. --- src/wallet/db.cpp | 35 +------------------------------ src/wallet/db.h | 2 -- src/wallet/wallet.cpp | 24 ++++++++++++++++++++++ src/wallet/wallet.h | 3 +++ src/wallet/walletdb.cpp | 5 ----- src/wallet/walletdb.h | 2 -- src/wallet/walletinit.cpp | 52 +++++++++++++++++++++++++---------------------- src/wallet/walletinit.h | 2 +- 8 files changed, 57 insertions(+), 68 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index da2d1807563..f5d8b836a97 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -224,42 +224,9 @@ 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) -{ - 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 - if (walletFile != fs::basename(walletFile) + fs::extension(walletFile)) - { - errorStr = strprintf(_("Wallet %s resides outside data directory %s"), walletFile, dataDir.string()); - return false; - } - - if (!bitdb.Open(dataDir)) - { - // try moving the database env out of the way - fs::path pathDatabase = dataDir / "database"; - fs::path pathDatabaseBak = dataDir / strprintf("database.%d.bak", GetTime()); - try { - fs::rename(pathDatabase, pathDatabaseBak); - LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); - } catch (const fs::filesystem_error&) { - // failure is ok (well, not really, but it's not worse than what we started with) - } - - // try again - if (!bitdb.Open(dataDir)) { - // if it still fails, it probably means we can't even create the database env - errorStr = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir()); - 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) { + LogPrintf("Using wallet %s\n", walletFile); if (fs::exists(dataDir / walletFile)) { std::string backup_filename; diff --git a/src/wallet/db.h b/src/wallet/db.h index 7cccc65660d..0c8ea2d03c8 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -163,8 +163,6 @@ class CDB /* flush the wallet passively (TRY_LOCK) 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); /* 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); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 3315ec4ebec..810ee65e206 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3689,6 +3689,30 @@ std::vector CWallet::GetDestValues(const std::string& prefix) const return values; } +bool VerifyWallet(std::string walletFile, bool salvage_wallet) +{ + if (salvage_wallet) { + // Recover readable keypairs: + CWallet dummyWallet; + std::string backup_filename; + if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) { + return false; + } + } + + std::string strError; + std::string strWarning; + bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError); + if (!strWarning.empty()) { + InitWarning(strWarning); + } + if (!dbV) { + InitError(strError); + return false; + } + return true; +} + CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) { // needed to restore wallet transaction meta data after -zapwallettxes diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 53be4d8b9f4..0174fe17a5a 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1118,6 +1118,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool SetHDMasterKey(const CPubKey& key); }; +//! Verify the database for a single wallet and perform salvage if required +bool VerifyWallet(std::string walletFile, bool salvage_wallet); + /** A key allocated from the key pool. */ class CReserveKey : public CReserveScript { diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index deb09a47710..761a000c032 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -813,11 +813,6 @@ bool CWalletDB::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDa return true; } -bool CWalletDB::VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr) -{ - return CDB::VerifyEnvironment(walletFile, dataDir, errorStr); -} - bool CWalletDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr) { return CDB::VerifyDatabaseFile(walletFile, dataDir, warningStr, errorStr, CWalletDB::Recover); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index d78f143ebd6..8f437bac7a5 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -225,8 +225,6 @@ class CWalletDB static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue); /* 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); /* verifies the database file */ static bool VerifyDatabaseFile(const std::string& walletFile, const fs::path& dataDir, std::string& warningStr, std::string& errorStr); diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index 38917aa7363..95351dda074 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -3,6 +3,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "fs.h" #include "net.h" #include "util.h" #include "utilmoneystr.h" @@ -160,6 +161,29 @@ bool VerifyWallets() uiInterface.InitMessage(_("Verifying wallet(s)...")); + LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); + + fs::path dataDir = GetDataDir().string(); + + if (!bitdb.Open(dataDir)) + { + // try moving the database env out of the way + fs::path pathDatabase = dataDir / "database"; + fs::path pathDatabaseBak = dataDir / strprintf("database.%d.bak", GetTime()); + try { + fs::rename(pathDatabase, pathDatabaseBak); + LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string()); + } catch (const fs::filesystem_error&) { + // failure is ok (well, not really, but it's not worse than what we started with) + } + + // try again + if (!bitdb.Open(dataDir)) { + // if it still fails, it probably means we can't even create the database env + return InitError(strprintf(_("Error initializing wallet database environment %s!"), GetDataDir())); + } + } + for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { if (boost::filesystem::path(walletFile).filename() != walletFile) { return InitError(_("-wallet parameter must only specify a filename (not a path)")); @@ -167,30 +191,10 @@ bool VerifyWallets() return InitError(_("Invalid characters in -wallet filename")); } - std::string strError; - if (!CWalletDB::VerifyEnvironment(walletFile, GetDataDir().string(), strError)) { - return InitError(strError); - } - - if (GetBoolArg("-salvagewallet", false)) { - // Recover readable keypairs: - CWallet dummyWallet; - std::string backup_filename; - if (!CWalletDB::Recover(walletFile, (void *)&dummyWallet, CWalletDB::RecoverKeysOnlyFilter, backup_filename)) { - return false; - } - } - - std::string strWarning; - bool dbV = CWalletDB::VerifyDatabaseFile(walletFile, GetDataDir().string(), strWarning, strError); - if (!strWarning.empty()) { - InitWarning(strWarning); - } - if (!dbV) { - InitError(strError); - return false; - } + // -salvagewallet is only permitted when loading a single wallet + // (belt-and-suspenders - WalletParameterInteraction() should prevent -salvagewallet with multiwallet) + bool salvage_wallet = GetBoolArg("-salvagewallet", false) && (gArgs.GetArgs("-wallet").size()) == 1; + if (!VerifyWallet(walletFile, salvage_wallet)) return false; } - return true; } diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index 84efdeaf48c..78d0247db09 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -19,5 +19,5 @@ bool WalletParameterInteraction(); //!Register Wallet RPC void RegisterWalletRPC(CRPCTable &t); -//! Verify the wallet database and perform salvage if required +//! Read and validate the -wallet arguments and verify the wallet database. bool VerifyWallets(); From 6c10c468476361e789326e93b8debca799622873 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 15:26:17 +0100 Subject: [PATCH 06/12] [wallet] Add AttachWallets() to walletinit.cpp Moves InitLoadWallets() to walletinit.cpp and renames it to AttachWallets. Apart from the name change, this is a MOVE-ONLY commit. --- src/init.cpp | 3 +-- src/wallet/wallet.cpp | 18 ------------------ src/wallet/wallet.h | 1 - src/wallet/walletinit.cpp | 18 ++++++++++++++++++ src/wallet/walletinit.h | 3 +++ 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 39fd755479b..24c631f32e7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1506,8 +1506,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 8: load wallet #ifdef ENABLE_WALLET - if (!CWallet::InitLoadWallet()) - return false; + if (!AttachWallets()) return false; #else LogPrintf("No wallet support compiled in!\n"); #endif diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 810ee65e206..039113947e4 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3903,24 +3903,6 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) return walletInstance; } -bool CWallet::InitLoadWallet() -{ - if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { - LogPrintf("Wallet disabled!\n"); - return true; - } - - for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { - CWallet * const pwallet = CreateWalletFromFile(walletFile); - if (!pwallet) { - return false; - } - vpwallets.push_back(pwallet); - } - - return true; -} - std::atomic CWallet::fFlushScheduled(false); void CWallet::postInitProcess(CScheduler& scheduler) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 0174fe17a5a..284d81372fc 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1091,7 +1091,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ static CWallet* CreateWalletFromFile(const std::string walletFile); - static bool InitLoadWallet(); /** * Wallet post-init setup diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index 95351dda074..73c9f433b9e 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -198,3 +198,21 @@ bool VerifyWallets() } return true; } + +bool AttachWallets() +{ + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { + LogPrintf("Wallet disabled!\n"); + return true; + } + + for (const std::string& walletFile : gArgs.GetArgs("-wallet")) { + CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile); + if (!pwallet) { + return false; + } + vpwallets.push_back(pwallet); + } + + return true; +} diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index 78d0247db09..64e72fb7b4a 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -21,3 +21,6 @@ void RegisterWalletRPC(CRPCTable &t); //! Read and validate the -wallet arguments and verify the wallet database. bool VerifyWallets(); + +//! Load and attaches wallets from file on startup +bool AttachWallets(); From 05e5f5f6e05e4ec914dcfc3ca593b85886ec1ab4 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 15:44:34 +0100 Subject: [PATCH 07/12] [wallet] Add WalletCompleteStartup() to walletinit.cpp This is more or less a CODE-MOVE only. --- src/init.cpp | 4 +--- src/wallet/wallet.cpp | 12 ------------ src/wallet/wallet.h | 8 +------- src/wallet/walletinit.cpp | 17 +++++++++++++++++ src/wallet/walletinit.h | 3 +++ 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 24c631f32e7..8ba83f02271 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1636,9 +1636,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.InitMessage(_("Done loading")); #ifdef ENABLE_WALLET - for (CWalletRef pwallet : vpwallets) { - pwallet->postInitProcess(scheduler); - } + WalletCompleteStartup(scheduler); #endif return !fRequestShutdown; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 039113947e4..ea49015c88d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3905,18 +3905,6 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) std::atomic CWallet::fFlushScheduled(false); -void CWallet::postInitProcess(CScheduler& scheduler) -{ - // Add wallet transactions that aren't already in a block to mempool - // Do this here as mempool requires genesis block to be loaded - ReacceptWalletTransactions(); - - // Run a thread to flush wallet periodically - if (!CWallet::fFlushScheduled.exchange(true)) { - scheduler.scheduleEvery(MaybeCompactWalletDB, 500); - } -} - bool CWallet::BackupWallet(const std::string& strDest) { return dbw->Backup(strDest); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 284d81372fc..72c48299ae4 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -650,7 +650,6 @@ class CAccountingEntry class CWallet : public CCryptoKeyStore, public CValidationInterface { private: - static std::atomic fFlushScheduled; std::atomic fAbortRescan; std::atomic fScanningWallet; @@ -796,6 +795,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface fScanningWallet = false; } + static std::atomic fFlushScheduled; std::map mapWallet; std::list laccentries; @@ -1092,12 +1092,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface /* Initializes the wallet, returns a new CWallet instance or a null pointer in case of an error */ static CWallet* CreateWalletFromFile(const std::string walletFile); - /** - * Wallet post-init setup - * Gives the wallet a chance to register repetitive tasks and complete post-init tasks - */ - void postInitProcess(CScheduler& scheduler); - bool BackupWallet(const std::string& strDest); /* Set the HD chain model (chain child index counters) */ diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index 73c9f433b9e..1e463f71060 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -5,6 +5,7 @@ #include "fs.h" #include "net.h" +#include "scheduler.h" #include "util.h" #include "utilmoneystr.h" #include "validation.h" @@ -216,3 +217,19 @@ bool AttachWallets() return true; } + +void WalletCompleteStartup(CScheduler& scheduler) +{ + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return; + + for (CWalletRef pwallet : vpwallets) { + // Add wallet transactions that aren't already in a block to mempool + // Do this here as mempool requires genesis block to be loaded + pwallet->ReacceptWalletTransactions(); + } + + // Run a thread to flush wallet periodically + if (!CWallet::fFlushScheduled.exchange(true)) { + scheduler.scheduleEvery(MaybeCompactWalletDB, 500); + } +} diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index 64e72fb7b4a..bc854a72d06 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -24,3 +24,6 @@ bool VerifyWallets(); //! Load and attaches wallets from file on startup bool AttachWallets(); + +//! Post-init setup for wallets +void WalletCompleteStartup(CScheduler& scheduler); From 3a86d2f11cf860fbf0dce1105c8df1c32313ed31 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 15:56:55 +0100 Subject: [PATCH 08/12] [wallet] Move FlushWallets and DeleteWallets to walletinit.cpp CODE-MOVE only This completes the movement of wallet initialization functions to walletinit.cpp. init.cpp now has an interface to the wallet consisting of the following functions: - GetWalletHelpString() - RegisterWalletRPCCommands() - WalletParameterInteraction() - VerifyWallets() - AttachWallets() - WalletCompleteStartup() - FlushWallets() - DeleteWallets() --- src/init.cpp | 14 +++----------- src/wallet/walletinit.cpp | 20 ++++++++++++++++++++ src/wallet/walletinit.h | 8 +++++++- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 8ba83f02271..dc72e03a390 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -43,7 +43,6 @@ #include "utilmoneystr.h" #include "validationinterface.h" #ifdef ENABLE_WALLET -#include "wallet/wallet.h" #include "wallet/walletinit.h" #endif #include "warnings.h" @@ -189,9 +188,7 @@ void Shutdown() StopRPC(); StopHTTPServer(); #ifdef ENABLE_WALLET - for (CWalletRef pwallet : vpwallets) { - pwallet->Flush(false); - } + FlushWallets(false); #endif MapPort(false); UnregisterValidationInterface(peerLogic.get()); @@ -231,9 +228,7 @@ void Shutdown() pblocktree = NULL; } #ifdef ENABLE_WALLET - for (CWalletRef pwallet : vpwallets) { - pwallet->Flush(true); - } + FlushWallets(true); #endif #if ENABLE_ZMQ @@ -253,10 +248,7 @@ void Shutdown() #endif UnregisterAllValidationInterfaces(); #ifdef ENABLE_WALLET - for (CWalletRef pwallet : vpwallets) { - delete pwallet; - } - vpwallets.clear(); + DeleteWallets(); #endif globalVerifyHandle.reset(); ECC_Stop(); diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index 1e463f71060..e40ad82d9b1 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -233,3 +233,23 @@ void WalletCompleteStartup(CScheduler& scheduler) scheduler.scheduleEvery(MaybeCompactWalletDB, 500); } } + +void FlushWallets(bool shutdown) +{ + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return; + + LOCK(bitdb.cs_db); + for (CWalletRef pwallet : vpwallets) { + pwallet->Flush(shutdown); + } +} + +void DeleteWallets() +{ + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return; + + for (CWalletRef pwallet : vpwallets) { + delete pwallet; + } + vpwallets.clear(); +} diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index bc854a72d06..4f7bd375e73 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -25,5 +25,11 @@ bool VerifyWallets(); //! Load and attaches wallets from file on startup bool AttachWallets(); -//! Post-init setup for wallets +//! Post-init setup for wallets void WalletCompleteStartup(CScheduler& scheduler); + +//! Flush wallets +void FlushWallets(bool shutdown); + +//! Delete wallets +void DeleteWallets(); From e8f481577f77e63671f3167fbe0f1f2fcb0c0d81 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 16:32:47 +0100 Subject: [PATCH 09/12] [wallet] Add CDBEnv::Shutdown() function CODE-MOVE only --- src/wallet/db.cpp | 20 +++++++++++--------- src/wallet/db.h | 1 + 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index f5d8b836a97..bb4b646208b 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -524,6 +524,16 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip) return false; } +void CDBEnv::Shutdown() +{ + char** listp; + if (mapFileUseCount.empty()) { + dbenv->log_archive(&listp, DB_ARCH_REMOVE); + Close(); + if (!fMockDb) + fs::remove_all(fs::path(strPath) / "database"); + } +} void CDBEnv::Flush(bool fShutdown) { @@ -553,15 +563,7 @@ void CDBEnv::Flush(bool fShutdown) mi++; } LogPrint(BCLog::DB, "CDBEnv::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart); - if (fShutdown) { - char** listp; - if (mapFileUseCount.empty()) { - dbenv->log_archive(&listp, DB_ARCH_REMOVE); - Close(); - if (!fMockDb) - fs::remove_all(fs::path(strPath) / "database"); - } - } + if (fShutdown) Shutdown(); } } diff --git a/src/wallet/db.h b/src/wallet/db.h index 0c8ea2d03c8..e30b7b675ff 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -71,6 +71,7 @@ class CDBEnv bool Open(const fs::path& path); void Close(); void Flush(bool fShutdown); + void Shutdown(); void CheckpointLSN(const std::string& strFile); void CloseDb(const std::string& strFile); From 9bfdaf996e78c83a4a93fdee6f7bb473d4db3a06 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 17:07:53 +0100 Subject: [PATCH 10/12] [wallet] Call CDBEnv.shutdown() from FlushWallets() This commit removes the call to CDBEnv.Shutdown() from CDBEnv.Flush() and calls CDBEnv.Shutdown directly from ShutdownWallets() in walletinit.cpp. This also changes the interface to CDBEnv.Flush() to allow an individual wallet to be flushed. --- src/qt/test/wallettests.cpp | 2 +- src/wallet/db.cpp | 17 ++++++++--------- src/wallet/db.h | 4 ++-- src/wallet/test/wallet_test_fixture.cpp | 3 ++- src/wallet/test/wallet_tests.cpp | 3 ++- src/wallet/wallet.cpp | 4 ++-- src/wallet/wallet.h | 2 +- src/wallet/walletinit.cpp | 3 ++- 8 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index ff1eb59f16b..a0e63119bef 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -184,7 +184,7 @@ void TestSendCoins() BumpFee(transactionView, txid2, false /* expect disabled */, {} /* expected error */, false /* cancel */); BumpFee(transactionView, txid2, true /* expect disabled */, "already bumped" /* expected error */, false /* cancel */); - bitdb.Flush(true); + bitdb.Flush("wallet_test.dat"); bitdb.Reset(); } diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index bb4b646208b..9be20725cdc 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -535,21 +535,21 @@ void CDBEnv::Shutdown() } } -void CDBEnv::Flush(bool fShutdown) +void CDBEnv::Flush(std::string strFile) { int64_t nStart = GetTimeMillis(); // Flush log data to the actual data file on all files that are not in use - LogPrint(BCLog::DB, "CDBEnv::Flush: Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started"); + LogPrint(BCLog::DB, "CDBEnv::Flush: Flush%s\n", fDbEnvInit ? "" : " database not started"); if (!fDbEnvInit) return; { LOCK(cs_db); std::map::iterator mi = mapFileUseCount.begin(); while (mi != mapFileUseCount.end()) { - std::string strFile = (*mi).first; + std::string foundStrFile = (*mi).first; int nRefCount = (*mi).second; - LogPrint(BCLog::DB, "CDBEnv::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount); - if (nRefCount == 0) { + if (foundStrFile == strFile && nRefCount == 0) { + LogPrint(BCLog::DB, "CDBEnv::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount); // Move log data to the dat file CloseDb(strFile); LogPrint(BCLog::DB, "CDBEnv::Flush: %s checkpoint\n", strFile); @@ -562,8 +562,7 @@ void CDBEnv::Flush(bool fShutdown) } else mi++; } - LogPrint(BCLog::DB, "CDBEnv::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart); - if (fShutdown) Shutdown(); + LogPrint(BCLog::DB, "CDBEnv::Flush: Flush took %15dms\n", GetTimeMillis() - nStart); } } @@ -652,9 +651,9 @@ bool CWalletDBWrapper::Backup(const std::string& strDest) return false; } -void CWalletDBWrapper::Flush(bool shutdown) +void CWalletDBWrapper::Flush() { if (!IsDummy()) { - env->Flush(shutdown); + env->Flush(strFile); } } diff --git a/src/wallet/db.h b/src/wallet/db.h index e30b7b675ff..3f438d9c7cf 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -70,7 +70,7 @@ class CDBEnv bool Open(const fs::path& path); void Close(); - void Flush(bool fShutdown); + void Flush(std::string strFile); void Shutdown(); void CheckpointLSN(const std::string& strFile); @@ -120,7 +120,7 @@ class CWalletDBWrapper /** Make sure all changes are flushed to disk. */ - void Flush(bool shutdown); + void Flush(); void IncrementUpdateCounter(); diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index 922fcc8e898..26ed8a99c00 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -30,6 +30,7 @@ WalletTestingSetup::~WalletTestingSetup() delete pwalletMain; pwalletMain = NULL; - bitdb.Flush(true); + bitdb.Flush("wallet_test.dat"); + bitdb.Shutdown(); bitdb.Reset(); } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index 96a1b14b60e..156403d60ed 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -606,7 +606,8 @@ class ListCoinsTestingSetup : public TestChain100Setup ~ListCoinsTestingSetup() { wallet.reset(); - ::bitdb.Flush(true); + ::bitdb.Flush("wallet_test.dat"); + ::bitdb.Shutdown(); ::bitdb.Reset(); } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ea49015c88d..e22cac9dc27 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -433,9 +433,9 @@ bool CWallet::HasWalletSpend(const uint256& txid) const return (iter != mapTxSpends.end() && iter->first.hash == txid); } -void CWallet::Flush(bool shutdown) +void CWallet::Flush() { - dbw->Flush(shutdown); + dbw->Flush(); } void CWallet::SyncMetaData(std::pair range) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 72c48299ae4..df60eb834d9 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1051,7 +1051,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool HasWalletSpend(const uint256& txid) const; //! Flush wallet (bitdb flush) - void Flush(bool shutdown=false); + void Flush(); /** * Address book entry changed. diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index e40ad82d9b1..da763f5c0c1 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -240,8 +240,9 @@ void FlushWallets(bool shutdown) LOCK(bitdb.cs_db); for (CWalletRef pwallet : vpwallets) { - pwallet->Flush(shutdown); + pwallet->Flush(); } + if (shutdown) bitdb.Shutdown(); } void DeleteWallets() From 1dc6393c46d3ed552ab9125be3cda3b581438ceb Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 17:37:23 +0100 Subject: [PATCH 11/12] [wallet] Remove early call to FlushWallets() This commit removes the early call to FlushWallets() in the init.cpp Shutdown() function. This appears to be vestigial Satoshi-era code. --- src/init.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index dc72e03a390..73034eb87aa 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -187,9 +187,6 @@ void Shutdown() StopREST(); StopRPC(); StopHTTPServer(); -#ifdef ENABLE_WALLET - FlushWallets(false); -#endif MapPort(false); UnregisterValidationInterface(peerLogic.get()); peerLogic.reset(); From 3696ed0026559892aa45e0c3d3cc69093a8035d4 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Fri, 7 Jul 2017 15:48:43 +0100 Subject: [PATCH 12/12] [wallet] Rename wallet shutdown functions Renames FlushWallets() and DeleteWallets() to ShutdownWallets() and DetachWallets() --- src/init.cpp | 4 ++-- src/wallet/walletinit.cpp | 6 +++--- src/wallet/walletinit.h | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 73034eb87aa..985bb84cbb0 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -225,7 +225,7 @@ void Shutdown() pblocktree = NULL; } #ifdef ENABLE_WALLET - FlushWallets(true); + ShutdownWallets(); #endif #if ENABLE_ZMQ @@ -245,7 +245,7 @@ void Shutdown() #endif UnregisterAllValidationInterfaces(); #ifdef ENABLE_WALLET - DeleteWallets(); + DetachWallets(); #endif globalVerifyHandle.reset(); ECC_Stop(); diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index da763f5c0c1..e37c3d96254 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -234,7 +234,7 @@ void WalletCompleteStartup(CScheduler& scheduler) } } -void FlushWallets(bool shutdown) +void ShutdownWallets() { if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return; @@ -242,10 +242,10 @@ void FlushWallets(bool shutdown) for (CWalletRef pwallet : vpwallets) { pwallet->Flush(); } - if (shutdown) bitdb.Shutdown(); + bitdb.Shutdown(); } -void DeleteWallets() +void DetachWallets() { if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return; diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index 4f7bd375e73..beef6310c3b 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -29,7 +29,7 @@ bool AttachWallets(); void WalletCompleteStartup(CScheduler& scheduler); //! Flush wallets -void FlushWallets(bool shutdown); +void ShutdownWallets(); -//! Delete wallets -void DeleteWallets(); +//! Detach wallets +void DetachWallets();