Skip to content

Commit 65d7083

Browse files
committed
Merge #13017: Add wallets management functions
3c058fd wallet: Add HasWallets (João Barbosa) 373aee2 wallet: Add AddWallet, RemoveWallet, GetWallet and GetWallets (João Barbosa) 6efd964 refactor: Drop CWalletRef typedef (João Barbosa) Pull request description: This is a small step towards dynamic wallet load/unload. The wallets *registry* `vpwallets` is used in several places. With these new functions all `vpwallets` usage are removed and `vpwallets` is now a static variable (no external linkage). The typedef `CWalletRef` is also removed as it is narrowly used. Tree-SHA512: 2ea19da2e17b521ad678bfe10f3257e497ccaf7ab9fd0b6647f9d829f1d6131cfa68db8e8492421711c6da399859432b963a568bdd4ca40a77dd95b597839423
2 parents 3e60b9c + 3c058fd commit 65d7083

File tree

9 files changed

+80
-41
lines changed

9 files changed

+80
-41
lines changed

src/interfaces/node.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ class NodeImpl : public Node
236236
{
237237
#ifdef ENABLE_WALLET
238238
std::vector<std::unique_ptr<Wallet>> wallets;
239-
for (CWalletRef wallet : ::vpwallets) {
239+
for (CWallet* wallet : GetWallets()) {
240240
wallets.emplace_back(MakeWallet(*wallet));
241241
}
242242
return wallets;

src/qt/test/wallettests.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ void TestGUI()
180180
TransactionView transactionView(platformStyle.get());
181181
auto node = interfaces::MakeNode();
182182
OptionsModel optionsModel(*node);
183-
vpwallets.insert(vpwallets.begin(), &wallet);
184-
WalletModel walletModel(std::move(node->getWallets()[0]), *node, platformStyle.get(), &optionsModel);
185-
vpwallets.erase(vpwallets.begin());
183+
AddWallet(&wallet);
184+
WalletModel walletModel(std::move(node->getWallets().back()), *node, platformStyle.get(), &optionsModel);
185+
RemoveWallet(&wallet);
186186
sendCoinsDialog.setModel(&walletModel);
187187
transactionView.setModel(&walletModel);
188188

src/rpc/misc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ UniValue validateaddress(const JSONRPCRequest& request)
6969
{
7070

7171
#ifdef ENABLE_WALLET
72-
if (!::vpwallets.empty() && IsDeprecatedRPCEnabled("validateaddress")) {
72+
if (HasWallets() && IsDeprecatedRPCEnabled("validateaddress")) {
7373
ret.pushKVs(getaddressinfo(request));
7474
}
7575
#endif

src/wallet/init.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -315,37 +315,37 @@ bool WalletInit::Open() const
315315
if (!pwallet) {
316316
return false;
317317
}
318-
vpwallets.push_back(pwallet);
318+
AddWallet(pwallet);
319319
}
320320

321321
return true;
322322
}
323323

324324
void WalletInit::Start(CScheduler& scheduler) const
325325
{
326-
for (CWalletRef pwallet : vpwallets) {
326+
for (CWallet* pwallet : GetWallets()) {
327327
pwallet->postInitProcess(scheduler);
328328
}
329329
}
330330

331331
void WalletInit::Flush() const
332332
{
333-
for (CWalletRef pwallet : vpwallets) {
333+
for (CWallet* pwallet : GetWallets()) {
334334
pwallet->Flush(false);
335335
}
336336
}
337337

338338
void WalletInit::Stop() const
339339
{
340-
for (CWalletRef pwallet : vpwallets) {
340+
for (CWallet* pwallet : GetWallets()) {
341341
pwallet->Flush(true);
342342
}
343343
}
344344

345345
void WalletInit::Close() const
346346
{
347-
for (CWalletRef pwallet : vpwallets) {
347+
for (CWallet* pwallet : GetWallets()) {
348+
RemoveWallet(pwallet);
348349
delete pwallet;
349350
}
350-
vpwallets.clear();
351351
}

src/wallet/rpcwallet.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,13 @@ CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
4646
if (request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
4747
// wallet endpoint was used
4848
std::string requestedWallet = urlDecode(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
49-
for (CWalletRef pwallet : ::vpwallets) {
50-
if (pwallet->GetName() == requestedWallet) {
51-
return pwallet;
52-
}
53-
}
54-
throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
49+
CWallet* pwallet = GetWallet(requestedWallet);
50+
if (!pwallet) throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
51+
return pwallet;
5552
}
56-
return ::vpwallets.size() == 1 || (request.fHelp && ::vpwallets.size() > 0) ? ::vpwallets[0] : nullptr;
53+
54+
std::vector<CWallet*> wallets = GetWallets();
55+
return wallets.size() == 1 || (request.fHelp && wallets.size() > 0) ? wallets[0] : nullptr;
5756
}
5857

5958
std::string HelpRequiringPassphrase(CWallet * const pwallet)
@@ -67,7 +66,7 @@ bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException)
6766
{
6867
if (pwallet) return true;
6968
if (avoidException) return false;
70-
if (::vpwallets.empty()) {
69+
if (!HasWallets()) {
7170
// Note: It isn't currently possible to trigger this error because
7271
// wallet RPC methods aren't registered unless a wallet is loaded. But
7372
// this error is being kept as a precaution, because it's possible in
@@ -2862,8 +2861,7 @@ UniValue listwallets(const JSONRPCRequest& request)
28622861

28632862
UniValue obj(UniValue::VARR);
28642863

2865-
for (CWalletRef pwallet : vpwallets) {
2866-
2864+
for (CWallet* pwallet : GetWallets()) {
28672865
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
28682866
return NullUniValue;
28692867
}

src/wallet/test/wallet_tests.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
7474
// after.
7575
{
7676
CWallet wallet("dummy", WalletDatabase::CreateDummy());
77-
vpwallets.insert(vpwallets.begin(), &wallet);
77+
AddWallet(&wallet);
7878
UniValue keys;
7979
keys.setArray();
8080
UniValue key;
@@ -105,7 +105,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
105105
"downloading and rescanning the relevant blocks (see -reindex and -rescan "
106106
"options).\"}},{\"success\":true}]",
107107
0, oldTip->GetBlockTimeMax(), TIMESTAMP_WINDOW));
108-
vpwallets.erase(vpwallets.begin());
108+
RemoveWallet(&wallet);
109109
}
110110
}
111111

@@ -140,9 +140,9 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
140140
JSONRPCRequest request;
141141
request.params.setArray();
142142
request.params.push_back((pathTemp / "wallet.backup").string());
143-
vpwallets.insert(vpwallets.begin(), &wallet);
143+
AddWallet(&wallet);
144144
::dumpwallet(request);
145-
vpwallets.erase(vpwallets.begin());
145+
RemoveWallet(&wallet);
146146
}
147147

148148
// Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME
@@ -153,9 +153,9 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
153153
JSONRPCRequest request;
154154
request.params.setArray();
155155
request.params.push_back((pathTemp / "wallet.backup").string());
156-
vpwallets.insert(vpwallets.begin(), &wallet);
156+
AddWallet(&wallet);
157157
::importwallet(request);
158-
vpwallets.erase(vpwallets.begin());
158+
RemoveWallet(&wallet);
159159

160160
LOCK(wallet.cs_wallet);
161161
BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3U);

src/wallet/wallet.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,50 @@
2828
#include <utilmoneystr.h>
2929
#include <wallet/fees.h>
3030

31+
#include <algorithm>
3132
#include <assert.h>
3233
#include <future>
3334

3435
#include <boost/algorithm/string/replace.hpp>
3536

36-
std::vector<CWalletRef> vpwallets;
37+
static std::vector<CWallet*> vpwallets;
38+
39+
bool AddWallet(CWallet* wallet)
40+
{
41+
assert(wallet);
42+
std::vector<CWallet*>::const_iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
43+
if (i != vpwallets.end()) return false;
44+
vpwallets.push_back(wallet);
45+
return true;
46+
}
47+
48+
bool RemoveWallet(CWallet* wallet)
49+
{
50+
assert(wallet);
51+
std::vector<CWallet*>::iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
52+
if (i == vpwallets.end()) return false;
53+
vpwallets.erase(i);
54+
return true;
55+
}
56+
57+
bool HasWallets()
58+
{
59+
return !vpwallets.empty();
60+
}
61+
62+
std::vector<CWallet*> GetWallets()
63+
{
64+
return vpwallets;
65+
}
66+
67+
CWallet* GetWallet(const std::string& name)
68+
{
69+
for (CWallet* wallet : vpwallets) {
70+
if (wallet->GetName() == name) return wallet;
71+
}
72+
return nullptr;
73+
}
74+
3775
/** Transaction fee set by the user */
3876
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
3977
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;

src/wallet/wallet.h

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@
3232
#include <utility>
3333
#include <vector>
3434

35-
typedef CWallet* CWalletRef;
36-
extern std::vector<CWalletRef> vpwallets;
35+
bool AddWallet(CWallet* wallet);
36+
bool RemoveWallet(CWallet* wallet);
37+
bool HasWallets();
38+
std::vector<CWallet*> GetWallets();
39+
CWallet* GetWallet(const std::string& name);
3740

3841
/**
3942
* Settings
@@ -268,7 +271,7 @@ class CMerkleTx
268271
//Get the marginal bytes of spending the specified output
269272
int CalculateMaximumSignedInputSize(const CTxOut& txout, const CWallet* pwallet);
270273

271-
/**
274+
/**
272275
* A transaction with a bunch of additional info that only the owner cares about.
273276
* It includes any unrecorded transactions needed to link it back to the block chain.
274277
*/
@@ -653,7 +656,7 @@ struct CoinEligibilityFilter
653656
};
654657

655658
class WalletRescanReserver; //forward declarations for ScanForWalletTransactions/RescanFromTime
656-
/**
659+
/**
657660
* A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
658661
* and provides the ability to create new transactions.
659662
*/
@@ -903,7 +906,7 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
903906
void GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const;
904907
unsigned int ComputeTimeSmart(const CWalletTx& wtx) const;
905908

906-
/**
909+
/**
907910
* Increment the next transaction order id
908911
* @return next transaction order id
909912
*/
@@ -1032,7 +1035,7 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
10321035
}
10331036

10341037
void GetScriptForMining(std::shared_ptr<CReserveScript> &script);
1035-
1038+
10361039
unsigned int GetKeyPoolSize()
10371040
{
10381041
AssertLockHeld(cs_wallet); // set{Ex,In}ternalKeyPool
@@ -1057,7 +1060,7 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
10571060
//! Flush wallet (bitdb flush)
10581061
void Flush(bool shutdown=false);
10591062

1060-
/**
1063+
/**
10611064
* Address book entry changed.
10621065
* @note called with lock cs_wallet held.
10631066
*/
@@ -1066,7 +1069,7 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
10661069
const std::string &purpose,
10671070
ChangeType status)> NotifyAddressBookChanged;
10681071

1069-
/**
1072+
/**
10701073
* Wallet transaction added, removed or updated.
10711074
* @note called with lock cs_wallet held.
10721075
*/
@@ -1113,7 +1116,7 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
11131116

11141117
/* Generates a new HD master key (will not be activated) */
11151118
CPubKey GenerateNewHDMasterKey();
1116-
1119+
11171120
/* Set the current HD master key (will reset the chain child index counters)
11181121
Sets the master key's version based on the current wallet version (so the
11191122
caller must ensure the current wallet version is correct before calling
@@ -1184,7 +1187,7 @@ class CReserveKey final : public CReserveScript
11841187
};
11851188

11861189

1187-
/**
1190+
/**
11881191
* DEPRECATED Account information.
11891192
* Stored in wallet with key "acc"+string account name.
11901193
*/
@@ -1230,10 +1233,10 @@ std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key);
12301233
class WalletRescanReserver
12311234
{
12321235
private:
1233-
CWalletRef m_wallet;
1236+
CWallet* m_wallet;
12341237
bool m_could_reserve;
12351238
public:
1236-
explicit WalletRescanReserver(CWalletRef w) : m_wallet(w), m_could_reserve(false) {}
1239+
explicit WalletRescanReserver(CWallet* w) : m_wallet(w), m_could_reserve(false) {}
12371240

12381241
bool reserve()
12391242
{

src/wallet/walletdb.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ void MaybeCompactWalletDB()
756756
return;
757757
}
758758

759-
for (CWalletRef pwallet : vpwallets) {
759+
for (CWallet* pwallet : GetWallets()) {
760760
WalletDatabase& dbh = pwallet->GetDBHandle();
761761

762762
unsigned int nUpdateCounter = dbh.nUpdateCounter;

0 commit comments

Comments
 (0)