diff --git a/src/init.cpp b/src/init.cpp index 33023a1800..cc630d7337 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -198,8 +198,9 @@ void Shutdown() StopRPC(); StopHTTPServer(); #ifdef ENABLE_WALLET - if (pwalletMain) - pwalletMain->Flush(false); + for (CWalletRef pwallet : vpwallets) { + pwallet->Flush(false); + } #endif MapPort(false); UnregisterValidationInterface(peerLogic.get()); @@ -239,8 +240,9 @@ void Shutdown() pblocktree = NULL; } #ifdef ENABLE_WALLET - if (pwalletMain) - pwalletMain->Flush(true); + for (CWalletRef pwallet : vpwallets) { + pwallet->Flush(true); + } #endif #if ENABLE_ZMQ @@ -260,8 +262,10 @@ void Shutdown() #endif UnregisterAllValidationInterfaces(); #ifdef ENABLE_WALLET - delete pwalletMain; - pwalletMain = NULL; + for (CWalletRef pwallet : vpwallets) { + delete pwallet; + } + vpwallets.clear(); #endif globalVerifyHandle.reset(); ECC_Stop(); @@ -1673,8 +1677,9 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) uiInterface.InitMessage(_("Done loading")); #ifdef ENABLE_WALLET - if (pwalletMain) - pwalletMain->postInitProcess(scheduler); + for (CWalletRef pwallet : vpwallets) { + pwallet->postInitProcess(scheduler); + } #endif return !fRequestShutdown; diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 23ec3ab434..6d8760c071 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -474,9 +474,10 @@ void BitcoinApplication::initializeResult(bool success) window->setClientModel(clientModel); #ifdef ENABLE_WALLET - if(pwalletMain) + // TODO: Expose secondary wallets + if (!vpwallets.empty()) { - walletModel = new WalletModel(platformStyle, pwalletMain, optionsModel); + walletModel = new WalletModel(platformStyle, vpwallets[0], optionsModel); window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel); window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET); diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 7e1b94ffa4..906cc809bf 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -439,11 +439,6 @@ void CWalletDBWrapper::IncrementUpdateCounter() ++nUpdateCounter; } -unsigned int CWalletDBWrapper::GetUpdateCounter() -{ - return nUpdateCounter.load(); -} - void CDB::Close() { if (!pdb) diff --git a/src/wallet/db.h b/src/wallet/db.h index 1a583c3ce9..a2ede99d1b 100644 --- a/src/wallet/db.h +++ b/src/wallet/db.h @@ -93,13 +93,13 @@ class CWalletDBWrapper friend class CDB; public: /** Create dummy DB handle */ - CWalletDBWrapper(): env(nullptr) + CWalletDBWrapper() : nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(nullptr) { } /** Create DB handle to real database */ - CWalletDBWrapper(CDBEnv *env_in, const std::string &strFile_in): - env(env_in), strFile(strFile_in) + CWalletDBWrapper(CDBEnv *env_in, const std::string &strFile_in) : + nLastSeen(0), nLastFlushed(0), nLastWalletUpdate(0), env(env_in), strFile(strFile_in) { } @@ -120,13 +120,16 @@ public: void Flush(bool shutdown); void IncrementUpdateCounter(); - unsigned int GetUpdateCounter(); + + std::atomic nUpdateCounter; + unsigned int nLastSeen; + unsigned int nLastFlushed; + int64_t nLastWalletUpdate; private: /** BerkeleyDB specific */ CDBEnv *env; std::string strFile; - std::atomic nUpdateCounter; /** Return whether this database handle is a dummy for testing. * Only to be used at a low level, application should ideally not care diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3b6dfd42ca..7b9ed91947 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -33,7 +33,8 @@ CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request) { - return pwalletMain; + // TODO: Some way to access secondary wallets + return vpwallets.empty() ? nullptr : vpwallets[0]; } std::string HelpRequiringPassphrase(CWallet * const pwallet) diff --git a/src/wallet/test/wallet_test_fixture.cpp b/src/wallet/test/wallet_test_fixture.cpp index 1989bf8d9b..922fcc8e89 100644 --- a/src/wallet/test/wallet_test_fixture.cpp +++ b/src/wallet/test/wallet_test_fixture.cpp @@ -8,6 +8,8 @@ #include "wallet/db.h" #include "wallet/wallet.h" +CWallet *pwalletMain; + WalletTestingSetup::WalletTestingSetup(const std::string& chainName): TestingSetup(chainName) { diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index b30748d66b..7c48bc29ea 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -19,6 +19,8 @@ #include #include +extern CWallet* pwalletMain; + extern UniValue importmulti(const JSONRPCRequest& request); extern UniValue dumpwallet(const JSONRPCRequest& request); extern UniValue importwallet(const JSONRPCRequest& request); @@ -402,8 +404,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) // after. { CWallet wallet; - CWallet *backup = ::pwalletMain; - ::pwalletMain = &wallet; + vpwallets.insert(vpwallets.begin(), &wallet); UniValue keys; keys.setArray(); UniValue key; @@ -434,7 +435,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) "downloading and rescanning the relevant blocks (see -reindex and -rescan " "options).\"}},{\"success\":true}]", 0, oldTip->GetBlockTimeMax(), TIMESTAMP_WINDOW)); - ::pwalletMain = backup; + vpwallets.erase(vpwallets.begin()); } } @@ -444,7 +445,6 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) // than or equal to key birthday. BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) { - CWallet *pwalletMainBackup = ::pwalletMain; LOCK(cs_main); // Create two blocks with same timestamp to verify that importwallet rescan @@ -470,7 +470,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) JSONRPCRequest request; request.params.setArray(); request.params.push_back("wallet.backup"); - ::pwalletMain = &wallet; + vpwallets.insert(vpwallets.begin(), &wallet); ::dumpwallet(request); } @@ -482,7 +482,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) JSONRPCRequest request; request.params.setArray(); request.params.push_back("wallet.backup"); - ::pwalletMain = &wallet; + vpwallets[0] = &wallet; ::importwallet(request); BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3); @@ -495,7 +495,7 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup) } SetMockTime(0); - ::pwalletMain = pwalletMainBackup; + vpwallets.erase(vpwallets.begin()); } // Check that GetImmatureCredit() returns a newly calculated value instead of diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 9d49b72308..e5c9f11aa6 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -35,7 +35,7 @@ #include #include -CWallet* pwalletMain = NULL; +std::vector vpwallets; /** Transaction fee set by the user */ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; @@ -3926,7 +3926,6 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) bool CWallet::InitLoadWallet() { if (GetBoolArg("-disablewallet", DEFAULT_DISABLE_WALLET)) { - pwalletMain = NULL; LogPrintf("Wallet disabled!\n"); return true; } @@ -3943,7 +3942,7 @@ bool CWallet::InitLoadWallet() if (!pwallet) { return false; } - pwalletMain = pwallet; + vpwallets.push_back(pwallet); return true; } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 6236b5e560..b1516c6e65 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -29,7 +29,8 @@ #include #include -extern CWallet* pwalletMain; +typedef CWallet* CWalletRef; +extern std::vector vpwallets; /** * Settings diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 149d0e0c20..6f5ddece9a 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -760,24 +760,23 @@ void MaybeCompactWalletDB() return; } - CWalletDBWrapper& dbh = pwalletMain->GetDBHandle(); + for (CWalletRef pwallet : vpwallets) { + CWalletDBWrapper& dbh = pwallet->GetDBHandle(); - static unsigned int nLastSeen = dbh.GetUpdateCounter(); - static unsigned int nLastFlushed = dbh.GetUpdateCounter(); - static int64_t nLastWalletUpdate = GetTime(); + unsigned int nUpdateCounter = dbh.nUpdateCounter; - if (nLastSeen != dbh.GetUpdateCounter()) - { - nLastSeen = dbh.GetUpdateCounter(); - nLastWalletUpdate = GetTime(); - } + if (dbh.nLastSeen != nUpdateCounter) { + dbh.nLastSeen = nUpdateCounter; + dbh.nLastWalletUpdate = GetTime(); + } - if (nLastFlushed != dbh.GetUpdateCounter() && GetTime() - nLastWalletUpdate >= 2) - { - if (CDB::PeriodicFlush(dbh)) { - nLastFlushed = dbh.GetUpdateCounter(); + if (dbh.nLastFlushed != nUpdateCounter && GetTime() - dbh.nLastWalletUpdate >= 2) { + if (CDB::PeriodicFlush(dbh)) { + dbh.nLastFlushed = nUpdateCounter; + } } } + fOneThread = false; }