diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp --- a/src/interfaces/node.cpp +++ b/src/interfaces/node.cpp @@ -235,7 +235,7 @@ std::vector> getWallets() override { #ifdef ENABLE_WALLET std::vector> wallets; - for (CWallet *wallet : ::vpwallets) { + for (CWallet *wallet : GetWallets()) { wallets.emplace_back(MakeWallet(*wallet)); } return wallets; diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -148,10 +148,10 @@ SendCoinsDialog sendCoinsDialog(platformStyle.get()); auto node = interfaces::MakeNode(); OptionsModel optionsModel(*node); - vpwallets.insert(vpwallets.begin(), &wallet); - WalletModel walletModel(std::move(node->getWallets()[0]), *node, + AddWallet(&wallet); + WalletModel walletModel(std::move(node->getWallets().back()), *node, platformStyle.get(), &optionsModel); - vpwallets.erase(vpwallets.begin()); + RemoveWallet(&wallet); sendCoinsDialog.setModel(&walletModel); // Send two transactions, and verify they are added to transaction list. diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -78,7 +78,7 @@ if (isValid) { #ifdef ENABLE_WALLET - if (!::vpwallets.empty() && + if (!GetWallets().empty() && IsDeprecatedRPCEnabled(gArgs, "validateaddress")) { ret.pushKVs(getaddressinfo(config, request)); } diff --git a/src/wallet/init.cpp b/src/wallet/init.cpp --- a/src/wallet/init.cpp +++ b/src/wallet/init.cpp @@ -383,33 +383,33 @@ if (!pwallet) { return false; } - vpwallets.push_back(pwallet); + AddWallet(pwallet); } return true; } void WalletInit::Start(CScheduler &scheduler) const { - for (CWallet *pwallet : vpwallets) { + for (CWallet *pwallet : GetWallets()) { pwallet->postInitProcess(scheduler); } } void WalletInit::Flush() const { - for (CWallet *pwallet : vpwallets) { + for (CWallet *pwallet : GetWallets()) { pwallet->Flush(false); } } void WalletInit::Stop() const { - for (CWallet *pwallet : vpwallets) { + for (CWallet *pwallet : GetWallets()) { pwallet->Flush(true); } } void WalletInit::Close() const { - for (CWallet *pwallet : vpwallets) { + for (CWallet *pwallet : GetWallets()) { + RemoveWallet(pwallet); delete pwallet; } - vpwallets.clear(); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -56,16 +56,18 @@ // wallet endpoint was used std::string requestedWallet = urlDecode(request.URI.substr(WALLET_ENDPOINT_BASE.size())); - for (CWallet *pwallet : ::vpwallets) { - if (pwallet->GetName() == requestedWallet) { - return pwallet; - } + CWallet *pwallet = GetWallet(requestedWallet); + if (!pwallet) { + throw JSONRPCError( + RPC_WALLET_NOT_FOUND, + "Requested wallet does not exist or is not loaded"); } - throw JSONRPCError(RPC_WALLET_NOT_FOUND, - "Requested wallet does not exist or is not loaded"); + return pwallet; } - return ::vpwallets.size() == 1 || (request.fHelp && ::vpwallets.size() > 0) - ? ::vpwallets[0] + + std::vector wallets = GetWallets(); + return wallets.size() == 1 || (request.fHelp && wallets.size() > 0) + ? wallets[0] : nullptr; } @@ -80,12 +82,10 @@ if (pwallet) { return true; } - if (avoidException) { return false; } - - if (::vpwallets.empty()) { + if (GetWallets().empty()) { // Note: It isn't currently possible to trigger this error because // wallet RPC methods aren't registered unless a wallet is loaded. But // this error is being kept as a precaution, because it's possible in @@ -3268,7 +3268,7 @@ UniValue obj(UniValue::VARR); - for (CWallet *pwallet : vpwallets) { + for (CWallet *pwallet : GetWallets()) { if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { return NullUniValue; } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -74,7 +74,7 @@ // after. { CWallet wallet(Params(), "dummy", CWalletDBWrapper::CreateDummy()); - vpwallets.insert(vpwallets.begin(), &wallet); + AddWallet(&wallet); UniValue keys; keys.setArray(); UniValue key; @@ -113,7 +113,7 @@ "rescanning the relevant blocks (see -reindex and " "-rescan options).\"}},{\"success\":true}]", 0, oldTip->GetBlockTimeMax(), TIMESTAMP_WINDOW)); - vpwallets.erase(vpwallets.begin()); + RemoveWallet(&wallet); } } @@ -157,9 +157,9 @@ JSONRPCRequest request; request.params.setArray(); request.params.push_back((pathTemp / "wallet.backup").string()); - vpwallets.insert(vpwallets.begin(), &wallet); + AddWallet(&wallet); ::dumpwallet(GetConfig(), request); - vpwallets.erase(vpwallets.begin()); + RemoveWallet(&wallet); } // Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME @@ -170,9 +170,9 @@ JSONRPCRequest request; request.params.setArray(); request.params.push_back((pathTemp / "wallet.backup").string()); - vpwallets.insert(vpwallets.begin(), &wallet); + AddWallet(&wallet); ::importwallet(GetConfig(), request); - vpwallets.erase(vpwallets.begin()); + RemoveWallet(&wallet); LOCK(wallet.cs_wallet); BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3U); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -31,7 +31,10 @@ #include #include -extern std::vector vpwallets; +bool AddWallet(CWallet *wallet); +bool RemoveWallet(CWallet *wallet); +std::vector GetWallets(); +CWallet *GetWallet(const std::string &name); static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000; //! -paytxfee default diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -42,9 +42,44 @@ #include #include -static const size_t OUTPUT_GROUP_MAX_ENTRIES = 10; +static std::vector vpwallets; + +bool AddWallet(CWallet *wallet) { + assert(wallet); + std::vector::const_iterator i = + std::find(vpwallets.begin(), vpwallets.end(), wallet); + if (i != vpwallets.end()) { + return false; + } + vpwallets.push_back(wallet); + return true; +} + +bool RemoveWallet(CWallet *wallet) { + assert(wallet); + std::vector::iterator i = + std::find(vpwallets.begin(), vpwallets.end(), wallet); + if (i == vpwallets.end()) { + return false; + } + vpwallets.erase(i); + return true; +} -std::vector vpwallets; +std::vector GetWallets() { + return vpwallets; +} + +CWallet *GetWallet(const std::string &name) { + for (CWallet *wallet : vpwallets) { + if (wallet->GetName() == name) { + return wallet; + } + } + return nullptr; +} + +static const size_t OUTPUT_GROUP_MAX_ENTRIES = 10; OutputType g_address_type = OutputType::NONE; OutputType g_change_type = OutputType::NONE; diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -757,7 +757,7 @@ return; } - for (CWallet *pwallet : vpwallets) { + for (CWallet *pwallet : GetWallets()) { CWalletDBWrapper &dbh = pwallet->GetDBHandle(); unsigned int nUpdateCounter = dbh.nUpdateCounter;