From fb0c934d1b2d58b165e13d2b301e54870c5dc60f Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 9 Sep 2016 08:15:01 +0000 Subject: [PATCH 1/2] Wallet: Let the interval-flushing thread figure out the filename --- src/wallet/wallet.cpp | 6 +++++- src/wallet/wallet.h | 3 +++ src/wallet/walletdb.cpp | 3 ++- src/wallet/walletdb.h | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c2bac6e33..36b7ddbbc 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3549,6 +3549,8 @@ bool CWallet::InitLoadWallet() return true; } +std::atomic CWallet::fFlushThreadRunning(false); + void CWallet::postInitProcess(boost::thread_group& threadGroup) { // Add wallet transactions that aren't already in a block to mempool @@ -3556,7 +3558,9 @@ void CWallet::postInitProcess(boost::thread_group& threadGroup) ReacceptWalletTransactions(); // Run a thread to flush wallet periodically - threadGroup.create_thread(boost::bind(&ThreadFlushWalletDB, boost::ref(this->strWalletFile))); + if (!CWallet::fFlushThreadRunning.exchange(true)) { + threadGroup.create_thread(ThreadFlushWalletDB); + } } bool CWallet::ParameterInteraction() diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index a527c6d84..1814870c5 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -18,6 +18,7 @@ #include "wallet/rpcwallet.h" #include +#include #include #include #include @@ -550,6 +551,8 @@ private: class CWallet : public CCryptoKeyStore, public CValidationInterface { private: + static std::atomic fFlushThreadRunning; + /** * Select a set of coins such that nValueRet >= nTargetValue and at least * all coins from coinControl are selected; Never select unconfirmed coins diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 43fd6a20a..9496c4404 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -768,7 +768,7 @@ DBErrors CWalletDB::ZapWalletTx(CWallet* pwallet, vector& vWtx) return DB_LOAD_OK; } -void ThreadFlushWalletDB(const string& strFile) +void ThreadFlushWalletDB() { // Make this thread recognisable as the wallet flushing thread RenameThread("bitcoin-wallet"); @@ -810,6 +810,7 @@ void ThreadFlushWalletDB(const string& strFile) if (nRefCount == 0) { boost::this_thread::interruption_point(); + const std::string& strFile = pwalletMain->strWalletFile; map::iterator _mi = bitdb.mapFileUseCount.find(strFile); if (_mi != bitdb.mapFileUseCount.end()) { diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index eb25ac613..efb5e5478 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -182,6 +182,6 @@ private: }; -void ThreadFlushWalletDB(const std::string& strFile); +void ThreadFlushWalletDB(); #endif // BITCOIN_WALLET_WALLETDB_H From 5394b3940dec1fd35952d344e6373fb7115c5490 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 9 Sep 2016 08:44:47 +0000 Subject: [PATCH 2/2] Wallet: Split main logic from InitLoadWallet into CreateWalletFromFile --- src/wallet/wallet.cpp | 81 ++++++++++++++++++++++++++++--------------- src/wallet/wallet.h | 1 + 2 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 36b7ddbbc..f88da978d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3374,16 +3374,8 @@ std::string CWallet::GetWalletHelpString(bool showDebug) return strUsage; } -bool CWallet::InitLoadWallet() +CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) { - if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { - pwalletMain = NULL; - LogPrintf("Wallet disabled!\n"); - return true; - } - - std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); - // needed to restore wallet transaction meta data after -zapwallettxes std::vector vWtx; @@ -3393,7 +3385,8 @@ bool CWallet::InitLoadWallet() CWallet *tempWallet = new CWallet(walletFile); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DB_LOAD_OK) { - return InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); + InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); + return NULL; } delete tempWallet; @@ -3408,23 +3401,29 @@ bool CWallet::InitLoadWallet() DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); if (nLoadWalletRet != DB_LOAD_OK) { - if (nLoadWalletRet == DB_CORRUPT) - return InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); + if (nLoadWalletRet == DB_CORRUPT) { + InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); + return NULL; + } else if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { InitWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data" " or address book entries might be missing or incorrect."), walletFile)); } - else if (nLoadWalletRet == DB_TOO_NEW) - return InitError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), - walletFile, _(PACKAGE_NAME))); + else if (nLoadWalletRet == DB_TOO_NEW) { + InitError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, _(PACKAGE_NAME))); + return NULL; + } else if (nLoadWalletRet == DB_NEED_REWRITE) { - return InitError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME))); + InitError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME))); + return NULL; + } + else { + InitError(strprintf(_("Error loading %s"), walletFile)); + return NULL; } - else - return InitError(strprintf(_("Error loading %s"), walletFile)); } if (GetBoolArg("-upgradewallet", fFirstRun)) @@ -3440,7 +3439,8 @@ bool CWallet::InitLoadWallet() LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion); if (nMaxVersion < walletInstance->GetVersion()) { - return InitError(_("Cannot downgrade wallet")); + InitError(_("Cannot downgrade wallet")); + return NULL; } walletInstance->SetMaxVersion(nMaxVersion); } @@ -3457,18 +3457,24 @@ bool CWallet::InitLoadWallet() CPubKey newDefaultKey; if (walletInstance->GetKeyFromPool(newDefaultKey)) { walletInstance->SetDefaultKey(newDefaultKey); - if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive")) - return InitError(_("Cannot write default address") += "\n"); + if (!walletInstance->SetAddressBook(walletInstance->vchDefaultKey.GetID(), "", "receive")) { + InitError(_("Cannot write default address") += "\n"); + return NULL; + } } walletInstance->SetBestChain(chainActive.GetLocator()); } else if (mapArgs.count("-usehd")) { bool useHD = GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET); - if (walletInstance->IsHDEnabled() && !useHD) - return InitError(strprintf(_("Error loading %s: You can't disable HD on a already existing HD wallet"), walletFile)); - if (!walletInstance->IsHDEnabled() && useHD) - return InitError(strprintf(_("Error loading %s: You can't enable HD on a already existing non-HD wallet"), walletFile)); + if (walletInstance->IsHDEnabled() && !useHD) { + InitError(strprintf(_("Error loading %s: You can't disable HD on a already existing HD wallet"), walletFile)); + return NULL; + } + if (!walletInstance->IsHDEnabled() && useHD) { + InitError(strprintf(_("Error loading %s: You can't enable HD on a already existing non-HD wallet"), walletFile)); + return NULL; + } } LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart); @@ -3498,8 +3504,10 @@ bool CWallet::InitLoadWallet() while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA) && block->pprev->nTx > 0 && pindexRescan != block) block = block->pprev; - if (pindexRescan != block) - return InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)")); + if (pindexRescan != block) { + InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)")); + return NULL; + } } uiInterface.InitMessage(_("Rescanning...")); @@ -3544,7 +3552,24 @@ bool CWallet::InitLoadWallet() LogPrintf("mapAddressBook.size() = %u\n", walletInstance->mapAddressBook.size()); } - pwalletMain = walletInstance; + return walletInstance; +} + +bool CWallet::InitLoadWallet() +{ + if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { + pwalletMain = NULL; + LogPrintf("Wallet disabled!\n"); + return true; + } + + std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); + + CWallet * const pwallet = CreateWalletFromFile(walletFile); + if (!pwallet) { + return false; + } + pwalletMain = pwallet; return true; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 1814870c5..f536dbe5c 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -917,6 +917,7 @@ public: 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(); /**