From 73b2df7439632ef58a09bd91faa943445bba5c9c Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 14:20:36 +0100 Subject: [PATCH 01/16] [wallet] Add walletinit.cpp This commit adds a new walletinit translation unit and moves GetWalletHelpString() to walletinit from a static member function of CWallet. --- src/Makefile.am | 2 ++ src/init.cpp | 3 ++- src/wallet/wallet.cpp | 37 ------------------------------------- src/wallet/wallet.h | 3 --- src/wallet/walletinit.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ src/wallet/walletinit.h | 6 ++++++ 6 files changed, 51 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..442f790bd6a --- /dev/null +++ b/src/wallet/walletinit.cpp @@ -0,0 +1,41 @@ +#include "wallet/walletinit.h" +#include "util.h" +#include "utilmoneystr.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..412f3522508 --- /dev/null +++ b/src/wallet/walletinit.h @@ -0,0 +1,6 @@ +#include "wallet/wallet.h" + +#include + +//!Returns the wallets help message +std::string GetWalletHelpString(bool showDebug); From 19e018fef33e790d85b3de7208a7bc4d2143c837 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 14:37:10 +0100 Subject: [PATCH 02/16] [wallet] move WalletParameterInteraction() to walletinit.cpp --- src/init.cpp | 3 +- src/wallet/wallet.cpp | 100 -------------------------------------------- src/wallet/wallet.h | 3 -- src/wallet/walletinit.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++++- src/wallet/walletinit.h | 4 ++ 5 files changed, 108 insertions(+), 106 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 442f790bd6a..ba2fc1be54a 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -1,6 +1,8 @@ -#include "wallet/walletinit.h" +#include "net.h" #include "util.h" #include "utilmoneystr.h" +#include "validation.h" +#include "wallet/walletinit.h" std::string GetWalletHelpString(bool showDebug) { @@ -39,3 +41,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 412f3522508..057edb65eab 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -4,3 +4,7 @@ //!Returns the wallets help message std::string GetWalletHelpString(bool showDebug); + +//!Wallet parameter interaction +bool WalletParameterInteraction(); + From e5a82107eb33a1f715ff68ae4d5c426dc8dc0711 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Thu, 6 Jul 2017 11:40:47 +0100 Subject: [PATCH 03/16] [wallet] move RegisterWalletRPC to walletinit.cpp --- src/init.cpp | 2 +- src/wallet/rpcwallet.cpp | 7 +++---- src/wallet/walletinit.cpp | 6 ++++++ src/wallet/walletinit.h | 5 +++++ 4 files changed, 15 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/walletinit.cpp b/src/wallet/walletinit.cpp index ba2fc1be54a..6221c69e059 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -141,3 +141,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 057edb65eab..2de5d51ace1 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -1,10 +1,15 @@ #include "wallet/wallet.h" +#include "wallet/rpcwallet.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 81bbc926f5fbfd080a4f49de494d4bf6c0d51975 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 14:49:48 +0100 Subject: [PATCH 04/16] [wallet] move VerifyWallets() to walletinit.cpp --- src/init.cpp | 3 +-- src/wallet/wallet.cpp | 42 ------------------------------------------ src/wallet/wallet.h | 3 --- src/wallet/walletinit.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/wallet/walletinit.h | 6 ++++++ 5 files changed, 49 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 6221c69e059..619187572c4 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -147,3 +147,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 2de5d51ace1..6bd81824b85 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -13,3 +13,9 @@ bool WalletParameterInteraction(); //!Register Wallet RPC void RegisterWalletRPC(CRPCTable &t); + +//! Read and validate the -wallet arguments and verify the wallet database. +// This function will perform salvage on the wallet if requested, as long as +// only one wallet is being loaded (CWallet::ParameterInteraction forbids +// -salvagewallet, -zapwallettxes or -upgradewallet with multiwallet). +bool VerifyWallets(); From dbda84b44bf189dc4e27ebd06cdc11d02ef57c11 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 15:10:13 +0100 Subject: [PATCH 05/16] [wallet] Allow individual wallets to be verified --- src/wallet/db.cpp | 30 +-------------------------- src/wallet/wallet.cpp | 24 ++++++++++++++++++++++ src/wallet/wallet.h | 3 +++ src/wallet/walletinit.cpp | 52 +++++++++++++++++++++++++---------------------- src/wallet/walletinit.h | 3 --- 5 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index da2d1807563..b387d611d64 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -226,40 +226,12 @@ bool CDB::Recover(const std::string& filename, void *callbackDataIn, bool (*reco 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/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/walletinit.cpp b/src/wallet/walletinit.cpp index 619187572c4..b642f72f07d 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -1,3 +1,4 @@ +#include "fs.h" #include "net.h" #include "util.h" #include "utilmoneystr.h" @@ -155,6 +156,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)")); @@ -162,30 +186,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 6bd81824b85..7fd4267b2d7 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -15,7 +15,4 @@ bool WalletParameterInteraction(); void RegisterWalletRPC(CRPCTable &t); //! Read and validate the -wallet arguments and verify the wallet database. -// This function will perform salvage on the wallet if requested, as long as -// only one wallet is being loaded (CWallet::ParameterInteraction forbids -// -salvagewallet, -zapwallettxes or -upgradewallet with multiwallet). bool VerifyWallets(); From b7ad935d9ef310eb83bb7fd93a96fb0d4aa29fbb Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 15:26:17 +0100 Subject: [PATCH 06/16] [wallet] move InitLoadWallets() to walletinit.cpp --- 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..b00dd5de3f5 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 (!InitLoadWallets()) 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 b642f72f07d..a485dfc9305 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -193,3 +193,21 @@ bool VerifyWallets() } return true; } + +bool InitLoadWallets() +{ + 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 7fd4267b2d7..ebfa04d3d2c 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -16,3 +16,6 @@ void RegisterWalletRPC(CRPCTable &t); //! Read and validate the -wallet arguments and verify the wallet database. bool VerifyWallets(); + +//! Load walllets from file on startup +bool InitLoadWallets(); From dc672331b8e5ec1300fc34ea616d310b92c0bcc0 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 15:44:34 +0100 Subject: [PATCH 07/16] [wallet] move calls to postInitProcess() to walletinit.cpp --- src/init.cpp | 4 +--- src/wallet/wallet.h | 2 +- src/wallet/walletinit.cpp | 17 +++++++++++++++++ src/wallet/walletinit.h | 3 +++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index b00dd5de3f5..a347e3cdfbc 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.h b/src/wallet/wallet.h index 284d81372fc..b3b7bc73a37 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; diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index a485dfc9305..7600b03bbc8 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -1,5 +1,6 @@ #include "fs.h" #include "net.h" +#include "scheduler.h" #include "util.h" #include "utilmoneystr.h" #include "validation.h" @@ -211,3 +212,19 @@ bool InitLoadWallets() 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 ebfa04d3d2c..22510b147c4 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -19,3 +19,6 @@ bool VerifyWallets(); //! Load walllets from file on startup bool InitLoadWallets(); + +//! Post-init setup for wallets +void WalletCompleteStartup(CScheduler& scheduler); From 6317b4093ec66e240d1789ad5078f81fc6b3f208 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 15:56:55 +0100 Subject: [PATCH 08/16] [wallet] move FlushWallets and DeleteWallets to walletinit.cpp 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() - InitLoadWallets() - 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 a347e3cdfbc..529ccd169d8 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 7600b03bbc8..de8879ae2c6 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -228,3 +228,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 22510b147c4..1d7a19f943e 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -20,5 +20,11 @@ bool VerifyWallets(); //! Load walllets from file on startup bool InitLoadWallets(); -//! 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 08467a80e3facd7eeac88592c3e1ca06803c8b48 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 16:32:47 +0100 Subject: [PATCH 09/16] [wallet] add CDBEnv::Shutdown() function --- 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 b387d611d64..32759fc7d71 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -529,6 +529,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) { @@ -558,15 +568,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 7cccc65660d..71330b96eab 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 c1fadcbdf0d9c51ce0009c5de0dde0ed1a1dbeff Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 17:07:53 +0100 Subject: [PATCH 10/16] [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 32759fc7d71..aa4789d6c4e 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -540,21 +540,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); @@ -567,8 +567,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); } } @@ -657,9 +656,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 71330b96eab..4c2268a12c8 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 039113947e4..65a0274d778 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 b3b7bc73a37..4d8f5338af1 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 de8879ae2c6..ce6622dc6a5 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -235,8 +235,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 c3bf190a06a79d2ffdb1b1ab0911d30dc14ea4a1 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Mon, 3 Jul 2017 17:37:23 +0100 Subject: [PATCH 11/16] [wallet] remove early call to FlushWallets() This commit removes the early call to FlushWallets() in Shutdown() and renames the function in walletinit.cpp to ShutdownWallets(). --- src/init.cpp | 5 +---- src/wallet/walletinit.cpp | 4 ++-- src/wallet/walletinit.h | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 529ccd169d8..0a867075aec 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(); @@ -228,7 +225,7 @@ void Shutdown() pblocktree = NULL; } #ifdef ENABLE_WALLET - FlushWallets(true); + ShutdownWallets(); #endif #if ENABLE_ZMQ diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index ce6622dc6a5..b6c0e3d91c9 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -229,7 +229,7 @@ void WalletCompleteStartup(CScheduler& scheduler) } } -void FlushWallets(bool shutdown) +void ShutdownWallets() { if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return; @@ -237,7 +237,7 @@ void FlushWallets(bool shutdown) for (CWalletRef pwallet : vpwallets) { pwallet->Flush(); } - if (shutdown) bitdb.Shutdown(); + bitdb.Shutdown(); } void DeleteWallets() diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index 1d7a19f943e..ea380fe60c8 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -24,7 +24,7 @@ bool InitLoadWallets(); void WalletCompleteStartup(CScheduler& scheduler); //! Flush wallets -void FlushWallets(bool shutdown); +void ShutdownWallets(); //! Delete wallets void DeleteWallets(); From 0b7918ea24c957977a6b9f6e50b5eca39a89f04a Mon Sep 17 00:00:00 2001 From: John Newbery Date: Thu, 6 Jul 2017 08:50:48 +0100 Subject: [PATCH 12/16] [wallet] create wallet init interface --- src/Makefile.am | 2 ++ src/walletinitinterface.cpp | 45 ++++++++++++++++++++++++++++++++++++ src/walletinitinterface.h | 56 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 src/walletinitinterface.cpp create mode 100644 src/walletinitinterface.h diff --git a/src/Makefile.am b/src/Makefile.am index 96963ff5abc..467fe2a6a34 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -158,6 +158,7 @@ BITCOIN_CORE_H = \ validation.h \ validationinterface.h \ versionbits.h \ + walletinitinterface.h \ wallet/coincontrol.h \ wallet/crypter.h \ wallet/db.h \ @@ -220,6 +221,7 @@ libbitcoin_server_a_SOURCES = \ validation.cpp \ validationinterface.cpp \ versionbits.cpp \ + walletinitinterface.cpp \ $(BITCOIN_CORE_H) if ENABLE_ZMQ diff --git a/src/walletinitinterface.cpp b/src/walletinitinterface.cpp new file mode 100644 index 00000000000..97e747c3cd2 --- /dev/null +++ b/src/walletinitinterface.cpp @@ -0,0 +1,45 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "walletinitinterface.h" + +static WalletInitSignals g_signals; + +WalletInitSignals& GetWalletInitSignals() +{ + return g_signals; +} + +void RegisterWalletInitInterface(WalletInitInterface* wallet_interface) { + g_signals.GetWalletHelpString.connect(boost::bind(&WalletInitInterface::GetWalletHelpString, wallet_interface, _1)); + g_signals.WalletParameterInteraction.connect(boost::bind(&WalletInitInterface::WalletParameterInteraction, wallet_interface)); + g_signals.RegisterWalletRPC.connect(boost::bind(&WalletInitInterface::RegisterWalletRPC, wallet_interface, _1)); + g_signals.VerifyWallets.connect(boost::bind(&WalletInitInterface::VerifyWallets, wallet_interface)); + g_signals.InitLoadWallets.connect(boost::bind(&WalletInitInterface::InitLoadWallets, wallet_interface)); + g_signals.WalletCompleteStartup.connect(boost::bind(&WalletInitInterface::WalletCompleteStartup, wallet_interface, _1)); + g_signals.ShutdownWallets.connect(boost::bind(&WalletInitInterface::ShutdownWallets, wallet_interface)); + g_signals.DeleteWallets.connect(boost::bind(&WalletInitInterface::DeleteWallets, wallet_interface)); +} + +void UnregisterWalletInitInterface(WalletInitInterface* pwalletIn) { + g_signals.GetWalletHelpString.disconnect(boost::bind(&WalletInitInterface::GetWalletHelpString, pwalletIn, _1)); + g_signals.WalletParameterInteraction.disconnect(boost::bind(&WalletInitInterface::WalletParameterInteraction, pwalletIn)); + g_signals.RegisterWalletRPC.disconnect(boost::bind(&WalletInitInterface::RegisterWalletRPC, pwalletIn, _1)); + g_signals.VerifyWallets.disconnect(boost::bind(&WalletInitInterface::VerifyWallets, pwalletIn)); + g_signals.InitLoadWallets.disconnect(boost::bind(&WalletInitInterface::InitLoadWallets, pwalletIn)); + g_signals.WalletCompleteStartup.disconnect(boost::bind(&WalletInitInterface::WalletCompleteStartup, pwalletIn, _1)); + g_signals.ShutdownWallets.disconnect(boost::bind(&WalletInitInterface::ShutdownWallets, pwalletIn)); + g_signals.DeleteWallets.disconnect(boost::bind(&WalletInitInterface::DeleteWallets, pwalletIn)); +} + +void UnregisterAllWalletInitInterfaces() { + g_signals.GetWalletHelpString.disconnect_all_slots(); + g_signals.WalletParameterInteraction.disconnect_all_slots(); + g_signals.RegisterWalletRPC.disconnect_all_slots(); + g_signals.VerifyWallets.disconnect_all_slots(); + g_signals.InitLoadWallets.disconnect_all_slots(); + g_signals.WalletCompleteStartup.disconnect_all_slots(); + g_signals.ShutdownWallets.disconnect_all_slots(); + g_signals.DeleteWallets.disconnect_all_slots(); +} diff --git a/src/walletinitinterface.h b/src/walletinitinterface.h new file mode 100644 index 00000000000..409aecd13b0 --- /dev/null +++ b/src/walletinitinterface.h @@ -0,0 +1,56 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef WALLETINITINTERFACE_H +#define WALLETINITINTERFACE_H + +#include + +class CScheduler; +class CRPCTable; + +class WalletInitInterface { +protected: + virtual std::string GetWalletHelpString(bool showDebug) {return (std::string)"";} + virtual bool WalletParameterInteraction() {return false;} + virtual bool RegisterWalletRPC(CRPCTable &) {return false;} + virtual bool VerifyWallets() {return false;} + virtual bool InitLoadWallets() {return false;} + virtual void WalletCompleteStartup(CScheduler& scheduler) {} + virtual void ShutdownWallets() {} + virtual void DeleteWallets() {} + friend void ::RegisterWalletInitInterface(WalletInitInterface*); + friend void ::UnregisterWalletInitInterface(WalletInitInterface*); + friend void ::UnregisterAllWalletInitInterfaces(); +}; + +/** Register a wallet initialization/shutdown interface from bitcoin_server*/ +void RegisterWalletInitInterface(WalletInitInterface* wallet_interface); +/** unregister a wallet initialization/shutdown interface from bitcoin_server*/ +void UnregisterWalletInitInterface(WalletInitInterface* wallet_interface); +/** unregister all wallet initialization/shutdown interfaces from bitcoin_server*/ +void UnregisterAllWalletInitInterfaces(); + +struct WalletInitSignals { + /** Callback to get wallet help string */ + boost::signals2::signal GetWalletHelpString; + /** Callback to check wallet parameter interaction */ + boost::signals2::signal WalletParameterInteraction; + /** Callback to register wallet RPC*/ + boost::signals2::signal RegisterWalletRPC; + /** Callback to verify wallets */ + boost::signals2::signal VerifyWallets; + /** Callback to start loading wallets*/ + boost::signals2::signal InitLoadWallets; + /** Callback to complete loading wallets*/ + boost::signals2::signal WalletCompleteStartup; + /** Callback to Shutdown Wallets*/ + boost::signals2::signal ShutdownWallets; + /** Callback to delete wallets */ + boost::signals2::signal DeleteWallets; +}; + +WalletInitSignals& GetWalletInitSignals(); + +#endif // WALLETINITINTERFACE_H From 702a1faf93a84c12f8474102e1af26da260e9c68 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Thu, 6 Jul 2017 11:16:40 +0100 Subject: [PATCH 13/16] [wallet] move wallet init functions into WalletInit class --- src/init.cpp | 16 ++++++++-------- src/wallet/walletinit.cpp | 16 ++++++++-------- src/wallet/walletinit.h | 37 +++++++++++++++++++++---------------- 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 0a867075aec..24a7b4ebacd 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -225,7 +225,7 @@ void Shutdown() pblocktree = NULL; } #ifdef ENABLE_WALLET - ShutdownWallets(); + WalletInit::ShutdownWallets(); #endif #if ENABLE_ZMQ @@ -245,7 +245,7 @@ void Shutdown() #endif UnregisterAllValidationInterfaces(); #ifdef ENABLE_WALLET - DeleteWallets(); + WalletInit::DeleteWallets(); #endif globalVerifyHandle.reset(); ECC_Stop(); @@ -394,7 +394,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 += GetWalletHelpString(showDebug); + strUsage += WalletInit::GetWalletHelpString(showDebug); #endif #if ENABLE_ZMQ @@ -997,7 +997,7 @@ bool AppInitParameterInteraction() RegisterAllCoreRPCCommands(tableRPC); #ifdef ENABLE_WALLET - RegisterWalletRPC(tableRPC); + WalletInit::RegisterWalletRPC(tableRPC); #endif nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); @@ -1042,7 +1042,7 @@ bool AppInitParameterInteraction() nBytesPerSigOp = GetArg("-bytespersigop", nBytesPerSigOp); #ifdef ENABLE_WALLET - if (!WalletParameterInteraction()) return false; + if (!WalletInit::WalletParameterInteraction()) return false; #endif fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); @@ -1208,7 +1208,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 5: verify wallet database integrity #ifdef ENABLE_WALLET - if (!VerifyWallets()) return false; + if (!WalletInit::VerifyWallets()) return false; #endif // ********************************************************* Step 6: network initialization // Note that we absolutely cannot open any actual connections @@ -1495,7 +1495,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) // ********************************************************* Step 8: load wallet #ifdef ENABLE_WALLET - if (!InitLoadWallets()) return false; + if (!WalletInit::InitLoadWallets()) return false; #else LogPrintf("No wallet support compiled in!\n"); #endif @@ -1625,7 +1625,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.InitMessage(_("Done loading")); #ifdef ENABLE_WALLET - WalletCompleteStartup(scheduler); + WalletInit::WalletCompleteStartup(scheduler); #endif return !fRequestShutdown; diff --git a/src/wallet/walletinit.cpp b/src/wallet/walletinit.cpp index b6c0e3d91c9..511bf25a584 100644 --- a/src/wallet/walletinit.cpp +++ b/src/wallet/walletinit.cpp @@ -6,7 +6,7 @@ #include "validation.h" #include "wallet/walletinit.h" -std::string GetWalletHelpString(bool showDebug) +std::string WalletInit::GetWalletHelpString(bool showDebug) { std::string strUsage = HelpMessageGroup(_("Wallet options:")); strUsage += HelpMessageOpt("-disablewallet", _("Do not load the wallet and disable wallet RPC calls")); @@ -43,7 +43,7 @@ std::string GetWalletHelpString(bool showDebug) return strUsage; } -bool WalletParameterInteraction() +bool WalletInit::WalletParameterInteraction() { SoftSetArg("-wallet", DEFAULT_WALLET_DAT); const bool is_multiwallet = gArgs.GetArgs("-wallet").size() > 1; @@ -143,14 +143,14 @@ bool WalletParameterInteraction() return true; } -void RegisterWalletRPC(CRPCTable &t) +void WalletInit::RegisterWalletRPC(CRPCTable &t) { if (GetBoolArg("-disablewallet", false)) return; RegisterWalletRPCCommands(t); } -bool VerifyWallets() +bool WalletInit::VerifyWallets() { if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return true; @@ -195,7 +195,7 @@ bool VerifyWallets() return true; } -bool InitLoadWallets() +bool WalletInit::InitLoadWallets() { if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { LogPrintf("Wallet disabled!\n"); @@ -213,7 +213,7 @@ bool InitLoadWallets() return true; } -void WalletCompleteStartup(CScheduler& scheduler) +void WalletInit::WalletCompleteStartup(CScheduler& scheduler) { if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return; @@ -229,7 +229,7 @@ void WalletCompleteStartup(CScheduler& scheduler) } } -void ShutdownWallets() +void WalletInit::ShutdownWallets() { if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return; @@ -240,7 +240,7 @@ void ShutdownWallets() bitdb.Shutdown(); } -void DeleteWallets() +void WalletInit::DeleteWallets() { if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) return; diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index ea380fe60c8..43bcfa01c8c 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -5,26 +5,31 @@ class CRPCTable; -//!Returns the wallets help message -std::string GetWalletHelpString(bool showDebug); +class WalletInit { -//!Wallet parameter interaction -bool WalletParameterInteraction(); +public: -//!Register Wallet RPC -void RegisterWalletRPC(CRPCTable &t); + //!Returns the wallets help message + static std::string GetWalletHelpString(bool showDebug); -//! Read and validate the -wallet arguments and verify the wallet database. -bool VerifyWallets(); + //!Register Wallet RPC + static void RegisterWalletRPC(CRPCTable &t); -//! Load walllets from file on startup -bool InitLoadWallets(); + //!Wallet parameter interaction + static bool WalletParameterInteraction(); -//! Post-init setup for wallets -void WalletCompleteStartup(CScheduler& scheduler); + //! Read and validate the -wallet arguments and verify the wallet database. + static bool VerifyWallets(); -//! Flush wallets -void ShutdownWallets(); + //! Load walllets from file on startup + static bool InitLoadWallets(); -//! Delete wallets -void DeleteWallets(); + //! Post-init setup for wallets + static void WalletCompleteStartup(CScheduler& scheduler); + + //! Flush wallets + static void ShutdownWallets(); + + //! Delete wallets + static void DeleteWallets(); +}; From 223e1f5d2b20743beedb06fbdbb893a9d292c9c6 Mon Sep 17 00:00:00 2001 From: John Newbery Date: Thu, 6 Jul 2017 16:40:10 +0100 Subject: [PATCH 14/16] [wallet] call wallet initialization/destruction functions through signals --- src/bitcoind.cpp | 9 ++++++++ src/init.cpp | 48 +++++++++++++++++------------------------ src/wallet/walletinit.h | 26 ++++++++++++++--------- src/walletinitinterface.cpp | 52 ++++++++++++++++++++++----------------------- src/walletinitinterface.h | 6 +++--- 5 files changed, 73 insertions(+), 68 deletions(-) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index 374678310c6..f614c297556 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -19,6 +19,10 @@ #include "httpserver.h" #include "httprpc.h" #include "utilstrencodings.h" +#if ENABLE_WALLET +#include "walletinitinterface.h" +#include "wallet/walletinit.h" +#endif #include @@ -67,6 +71,11 @@ bool AppInit(int argc, char* argv[]) bool fRet = false; +#if ENABLE_WALLET + WalletInit wallet_init; + RegisterWalletInitInterface(&wallet_init); +#endif + // // Parameters // diff --git a/src/init.cpp b/src/init.cpp index 24a7b4ebacd..00b0574219a 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -41,10 +41,8 @@ #include "ui_interface.h" #include "util.h" #include "utilmoneystr.h" +#include "walletinitinterface.h" #include "validationinterface.h" -#ifdef ENABLE_WALLET -#include "wallet/walletinit.h" -#endif #include "warnings.h" #include #include @@ -224,9 +222,7 @@ void Shutdown() delete pblocktree; pblocktree = NULL; } -#ifdef ENABLE_WALLET - WalletInit::ShutdownWallets(); -#endif + GetWalletInitSignals().ShutdownWallets(); #if ENABLE_ZMQ if (pzmqNotificationInterface) { @@ -244,9 +240,7 @@ void Shutdown() } #endif UnregisterAllValidationInterfaces(); -#ifdef ENABLE_WALLET - WalletInit::DeleteWallets(); -#endif + GetWalletInitSignals().DeleteWallets(); globalVerifyHandle.reset(); ECC_Stop(); LogPrintf("%s: done\n", __func__); @@ -393,9 +387,8 @@ std::string HelpMessage(HelpMessageMode mode) " " + _("Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway")); 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 += WalletInit::GetWalletHelpString(showDebug); -#endif + boost::optional wallet_rpc_help_string = GetWalletInitSignals().GetWalletHelpString(showDebug); + if (wallet_rpc_help_string) strUsage += *wallet_rpc_help_string; #if ENABLE_ZMQ strUsage += HelpMessageGroup(_("ZeroMQ notification options:")); @@ -996,9 +989,7 @@ bool AppInitParameterInteraction() } RegisterAllCoreRPCCommands(tableRPC); -#ifdef ENABLE_WALLET - WalletInit::RegisterWalletRPC(tableRPC); -#endif + GetWalletInitSignals().RegisterWalletRPC(tableRPC); nConnectTimeout = GetArg("-timeout", DEFAULT_CONNECT_TIMEOUT); if (nConnectTimeout <= 0) @@ -1041,9 +1032,8 @@ bool AppInitParameterInteraction() return InitError(strprintf("acceptnonstdtxn is not currently supported for %s chain", chainparams.NetworkIDString())); nBytesPerSigOp = GetArg("-bytespersigop", nBytesPerSigOp); -#ifdef ENABLE_WALLET - if (!WalletInit::WalletParameterInteraction()) return false; -#endif + boost::optional param_interaction_success = GetWalletInitSignals().WalletParameterInteraction(); + if (param_interaction_success && !(*param_interaction_success)) return false; fIsBareMultisigStd = GetBoolArg("-permitbaremultisig", DEFAULT_PERMIT_BAREMULTISIG); fAcceptDatacarrier = GetBoolArg("-datacarrier", DEFAULT_ACCEPT_DATACARRIER); @@ -1207,9 +1197,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) int64_t nStart; // ********************************************************* Step 5: verify wallet database integrity -#ifdef ENABLE_WALLET - if (!WalletInit::VerifyWallets()) return false; -#endif + boost::optional wallet_verify_success = GetWalletInitSignals().VerifyWallets(); + if (wallet_verify_success && !(*wallet_verify_success)) return false; + // ********************************************************* Step 6: network initialization // Note that we absolutely cannot open any actual connections // until the very end ("start node") as the UTXO/block state @@ -1494,11 +1484,13 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) fFeeEstimatesInitialized = true; // ********************************************************* Step 8: load wallet -#ifdef ENABLE_WALLET - if (!WalletInit::InitLoadWallets()) return false; -#else - LogPrintf("No wallet support compiled in!\n"); -#endif + + boost::optional wallet_load_success = GetWalletInitSignals().InitLoadWallets(); + if (!wallet_load_success) { + LogPrintf("No wallet support compiled in!\n"); + } else if (!(*wallet_load_success)) { + return false; + } // ********************************************************* Step 9: data directory maintenance @@ -1624,9 +1616,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) SetRPCWarmupFinished(); uiInterface.InitMessage(_("Done loading")); -#ifdef ENABLE_WALLET - WalletInit::WalletCompleteStartup(scheduler); -#endif + GetWalletInitSignals().WalletCompleteStartup(scheduler); return !fRequestShutdown; } diff --git a/src/wallet/walletinit.h b/src/wallet/walletinit.h index 43bcfa01c8c..47f78332e36 100644 --- a/src/wallet/walletinit.h +++ b/src/wallet/walletinit.h @@ -1,3 +1,4 @@ +#include "walletinitinterface.h" #include "wallet/wallet.h" #include "wallet/rpcwallet.h" @@ -5,31 +6,36 @@ class CRPCTable; -class WalletInit { +class WalletInit : public WalletInitInterface +{ +/* public: */ + /* WalletInit(); */ + /* virtual ~WalletInit(); */ -public: +protected: //!Returns the wallets help message - static std::string GetWalletHelpString(bool showDebug); + /* static std::string GetWalletHelpString(bool showDebug) override; */ + std::string GetWalletHelpString(bool showDebug) override; //!Register Wallet RPC - static void RegisterWalletRPC(CRPCTable &t); + void RegisterWalletRPC(CRPCTable &t); //!Wallet parameter interaction - static bool WalletParameterInteraction(); + bool WalletParameterInteraction(); //! Read and validate the -wallet arguments and verify the wallet database. - static bool VerifyWallets(); + bool VerifyWallets(); //! Load walllets from file on startup - static bool InitLoadWallets(); + bool InitLoadWallets(); //! Post-init setup for wallets - static void WalletCompleteStartup(CScheduler& scheduler); + void WalletCompleteStartup(CScheduler& scheduler); //! Flush wallets - static void ShutdownWallets(); + void ShutdownWallets(); //! Delete wallets - static void DeleteWallets(); + void DeleteWallets(); }; diff --git a/src/walletinitinterface.cpp b/src/walletinitinterface.cpp index 97e747c3cd2..0394b157021 100644 --- a/src/walletinitinterface.cpp +++ b/src/walletinitinterface.cpp @@ -4,42 +4,42 @@ #include "walletinitinterface.h" -static WalletInitSignals g_signals; +WalletInitSignals wallet_init_signals; WalletInitSignals& GetWalletInitSignals() { - return g_signals; + return wallet_init_signals; } void RegisterWalletInitInterface(WalletInitInterface* wallet_interface) { - g_signals.GetWalletHelpString.connect(boost::bind(&WalletInitInterface::GetWalletHelpString, wallet_interface, _1)); - g_signals.WalletParameterInteraction.connect(boost::bind(&WalletInitInterface::WalletParameterInteraction, wallet_interface)); - g_signals.RegisterWalletRPC.connect(boost::bind(&WalletInitInterface::RegisterWalletRPC, wallet_interface, _1)); - g_signals.VerifyWallets.connect(boost::bind(&WalletInitInterface::VerifyWallets, wallet_interface)); - g_signals.InitLoadWallets.connect(boost::bind(&WalletInitInterface::InitLoadWallets, wallet_interface)); - g_signals.WalletCompleteStartup.connect(boost::bind(&WalletInitInterface::WalletCompleteStartup, wallet_interface, _1)); - g_signals.ShutdownWallets.connect(boost::bind(&WalletInitInterface::ShutdownWallets, wallet_interface)); - g_signals.DeleteWallets.connect(boost::bind(&WalletInitInterface::DeleteWallets, wallet_interface)); + wallet_init_signals.GetWalletHelpString.connect(boost::bind(&WalletInitInterface::GetWalletHelpString, wallet_interface, _1)); + wallet_init_signals.WalletParameterInteraction.connect(boost::bind(&WalletInitInterface::WalletParameterInteraction, wallet_interface)); + wallet_init_signals.RegisterWalletRPC.connect(boost::bind(&WalletInitInterface::RegisterWalletRPC, wallet_interface, _1)); + wallet_init_signals.VerifyWallets.connect(boost::bind(&WalletInitInterface::VerifyWallets, wallet_interface)); + wallet_init_signals.InitLoadWallets.connect(boost::bind(&WalletInitInterface::InitLoadWallets, wallet_interface)); + wallet_init_signals.WalletCompleteStartup.connect(boost::bind(&WalletInitInterface::WalletCompleteStartup, wallet_interface, _1)); + wallet_init_signals.ShutdownWallets.connect(boost::bind(&WalletInitInterface::ShutdownWallets, wallet_interface)); + wallet_init_signals.DeleteWallets.connect(boost::bind(&WalletInitInterface::DeleteWallets, wallet_interface)); } void UnregisterWalletInitInterface(WalletInitInterface* pwalletIn) { - g_signals.GetWalletHelpString.disconnect(boost::bind(&WalletInitInterface::GetWalletHelpString, pwalletIn, _1)); - g_signals.WalletParameterInteraction.disconnect(boost::bind(&WalletInitInterface::WalletParameterInteraction, pwalletIn)); - g_signals.RegisterWalletRPC.disconnect(boost::bind(&WalletInitInterface::RegisterWalletRPC, pwalletIn, _1)); - g_signals.VerifyWallets.disconnect(boost::bind(&WalletInitInterface::VerifyWallets, pwalletIn)); - g_signals.InitLoadWallets.disconnect(boost::bind(&WalletInitInterface::InitLoadWallets, pwalletIn)); - g_signals.WalletCompleteStartup.disconnect(boost::bind(&WalletInitInterface::WalletCompleteStartup, pwalletIn, _1)); - g_signals.ShutdownWallets.disconnect(boost::bind(&WalletInitInterface::ShutdownWallets, pwalletIn)); - g_signals.DeleteWallets.disconnect(boost::bind(&WalletInitInterface::DeleteWallets, pwalletIn)); + wallet_init_signals.GetWalletHelpString.disconnect(boost::bind(&WalletInitInterface::GetWalletHelpString, pwalletIn, _1)); + wallet_init_signals.WalletParameterInteraction.disconnect(boost::bind(&WalletInitInterface::WalletParameterInteraction, pwalletIn)); + wallet_init_signals.RegisterWalletRPC.disconnect(boost::bind(&WalletInitInterface::RegisterWalletRPC, pwalletIn, _1)); + wallet_init_signals.VerifyWallets.disconnect(boost::bind(&WalletInitInterface::VerifyWallets, pwalletIn)); + wallet_init_signals.InitLoadWallets.disconnect(boost::bind(&WalletInitInterface::InitLoadWallets, pwalletIn)); + wallet_init_signals.WalletCompleteStartup.disconnect(boost::bind(&WalletInitInterface::WalletCompleteStartup, pwalletIn, _1)); + wallet_init_signals.ShutdownWallets.disconnect(boost::bind(&WalletInitInterface::ShutdownWallets, pwalletIn)); + wallet_init_signals.DeleteWallets.disconnect(boost::bind(&WalletInitInterface::DeleteWallets, pwalletIn)); } void UnregisterAllWalletInitInterfaces() { - g_signals.GetWalletHelpString.disconnect_all_slots(); - g_signals.WalletParameterInteraction.disconnect_all_slots(); - g_signals.RegisterWalletRPC.disconnect_all_slots(); - g_signals.VerifyWallets.disconnect_all_slots(); - g_signals.InitLoadWallets.disconnect_all_slots(); - g_signals.WalletCompleteStartup.disconnect_all_slots(); - g_signals.ShutdownWallets.disconnect_all_slots(); - g_signals.DeleteWallets.disconnect_all_slots(); + wallet_init_signals.GetWalletHelpString.disconnect_all_slots(); + wallet_init_signals.WalletParameterInteraction.disconnect_all_slots(); + wallet_init_signals.RegisterWalletRPC.disconnect_all_slots(); + wallet_init_signals.VerifyWallets.disconnect_all_slots(); + wallet_init_signals.InitLoadWallets.disconnect_all_slots(); + wallet_init_signals.WalletCompleteStartup.disconnect_all_slots(); + wallet_init_signals.ShutdownWallets.disconnect_all_slots(); + wallet_init_signals.DeleteWallets.disconnect_all_slots(); } diff --git a/src/walletinitinterface.h b/src/walletinitinterface.h index 409aecd13b0..0634da2dc80 100644 --- a/src/walletinitinterface.h +++ b/src/walletinitinterface.h @@ -14,12 +14,12 @@ class WalletInitInterface { protected: virtual std::string GetWalletHelpString(bool showDebug) {return (std::string)"";} virtual bool WalletParameterInteraction() {return false;} - virtual bool RegisterWalletRPC(CRPCTable &) {return false;} + virtual void RegisterWalletRPC(CRPCTable &) {} virtual bool VerifyWallets() {return false;} virtual bool InitLoadWallets() {return false;} virtual void WalletCompleteStartup(CScheduler& scheduler) {} virtual void ShutdownWallets() {} - virtual void DeleteWallets() {} + virtual void DeleteWallets() {}; friend void ::RegisterWalletInitInterface(WalletInitInterface*); friend void ::UnregisterWalletInitInterface(WalletInitInterface*); friend void ::UnregisterAllWalletInitInterfaces(); @@ -36,7 +36,7 @@ struct WalletInitSignals { /** Callback to get wallet help string */ boost::signals2::signal GetWalletHelpString; /** Callback to check wallet parameter interaction */ - boost::signals2::signal WalletParameterInteraction; + boost::signals2::signal WalletParameterInteraction; /** Callback to register wallet RPC*/ boost::signals2::signal RegisterWalletRPC; /** Callback to verify wallets */ From df513e39ca02851f5f09f0fbc0cebf0b68ceacbd Mon Sep 17 00:00:00 2001 From: John Newbery Date: Fri, 7 Jul 2017 09:20:32 +0100 Subject: [PATCH 15/16] fixup: forward declaration of WalletInitInterface --- src/walletinitinterface.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/walletinitinterface.h b/src/walletinitinterface.h index 0634da2dc80..bf00b71da34 100644 --- a/src/walletinitinterface.h +++ b/src/walletinitinterface.h @@ -9,6 +9,14 @@ class CScheduler; class CRPCTable; +class WalletInitInterface; + +/** Register a wallet initialization/shutdown interface from bitcoin_server*/ +void RegisterWalletInitInterface(WalletInitInterface* wallet_interface); +/** unregister a wallet initialization/shutdown interface from bitcoin_server*/ +void UnregisterWalletInitInterface(WalletInitInterface* wallet_interface); +/** unregister all wallet initialization/shutdown interfaces from bitcoin_server*/ +void UnregisterAllWalletInitInterfaces(); class WalletInitInterface { protected: @@ -25,13 +33,6 @@ class WalletInitInterface { friend void ::UnregisterAllWalletInitInterfaces(); }; -/** Register a wallet initialization/shutdown interface from bitcoin_server*/ -void RegisterWalletInitInterface(WalletInitInterface* wallet_interface); -/** unregister a wallet initialization/shutdown interface from bitcoin_server*/ -void UnregisterWalletInitInterface(WalletInitInterface* wallet_interface); -/** unregister all wallet initialization/shutdown interfaces from bitcoin_server*/ -void UnregisterAllWalletInitInterfaces(); - struct WalletInitSignals { /** Callback to get wallet help string */ boost::signals2::signal GetWalletHelpString; From 306fe41767ca9501f14ca8f4ffe877bc9daf01ec Mon Sep 17 00:00:00 2001 From: John Newbery Date: Fri, 7 Jul 2017 10:10:52 +0100 Subject: [PATCH 16/16] fixup: register wallet initialization callbacks in bitcoin-qt --- src/bitcoind.cpp | 1 + src/qt/bitcoin.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp index f614c297556..90b5b136b9e 100644 --- a/src/bitcoind.cpp +++ b/src/bitcoind.cpp @@ -72,6 +72,7 @@ bool AppInit(int argc, char* argv[]) bool fRet = false; #if ENABLE_WALLET + // Register wallet initialization callbacks WalletInit wallet_init; RegisterWalletInitInterface(&wallet_init); #endif diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 8a745cadce7..e6e80cc1f97 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -34,6 +34,8 @@ #include "warnings.h" #ifdef ENABLE_WALLET +#include "walletinitinterface.h" +#include "wallet/walletinit.h" #include "wallet/wallet.h" #endif @@ -662,6 +664,10 @@ int main(int argc, char *argv[]) // Start up the payment server early, too, so impatient users that click on // bitcoin: links repeatedly have their payment requests routed to this process: app.createPaymentServer(); + + // Register wallet initialization callbacks + WalletInit wallet_init; + RegisterWalletInitInterface(&wallet_init); #endif /// 9. Main GUI initialization