Skip to content

Commit 05875a8

Browse files
committed
refactor: Move wallet methods out of chain.h and node.h
Add WalletClient interface so node interface is cleaner and don't need wallet-specific methods. The new NodeContext::wallet_client pointer will also be needed to eliminate global wallet variables like ::vpwallets, because createWallet(), loadWallet(), getWallets(), etc methods called by the GUI need a way to get a reference to the list of open wallets if it is no longer a global variable. Also tweaks splash screen registration for load wallet events to be delayed until after wallet client is created.
1 parent 9f910a0 commit 05875a8

19 files changed

+108
-105
lines changed

src/interfaces/chain.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -304,24 +304,11 @@ class ChainClient
304304

305305
//! Set mock time.
306306
virtual void setMockTime(int64_t time) = 0;
307-
308-
//! Return interfaces for accessing wallets (if any).
309-
virtual std::vector<std::unique_ptr<Wallet>> getWallets() = 0;
310307
};
311308

312309
//! Return implementation of Chain interface.
313310
std::unique_ptr<Chain> MakeChain(NodeContext& node);
314311

315-
//! Return implementation of ChainClient interface for a wallet client. This
316-
//! function will be undefined in builds where ENABLE_WALLET is false.
317-
//!
318-
//! Currently, wallets are the only chain clients. But in the future, other
319-
//! types of chain clients could be added, such as tools for monitoring,
320-
//! analysis, or fee estimation. These clients need to expose their own
321-
//! MakeXXXClient functions returning their implementations of the ChainClient
322-
//! interface.
323-
std::unique_ptr<ChainClient> MakeWalletClient(Chain& chain, std::vector<std::string> wallet_filenames);
324-
325312
} // namespace interfaces
326313

327314
#endif // BITCOIN_INTERFACES_CHAIN_H

src/interfaces/node.cpp

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,7 @@
4141

4242
#include <boost/signals2/signal.hpp>
4343

44-
class CWallet;
45-
fs::path GetWalletDir();
46-
std::vector<fs::path> ListWalletDir();
47-
std::vector<std::shared_ptr<CWallet>> GetWallets();
48-
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings);
49-
WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings, std::shared_ptr<CWallet>& result);
50-
std::unique_ptr<interfaces::Handler> HandleLoadWallet(interfaces::Node::LoadWalletFn load_wallet);
51-
5244
namespace interfaces {
53-
5445
namespace {
5546

5647
class NodeImpl : public Node
@@ -245,36 +236,10 @@ class NodeImpl : public Node
245236
LOCK(::cs_main);
246237
return ::ChainstateActive().CoinsTip().GetCoin(output, coin);
247238
}
248-
std::string getWalletDir() override
249-
{
250-
return GetWalletDir().string();
251-
}
252-
std::vector<std::string> listWalletDir() override
253-
{
254-
std::vector<std::string> paths;
255-
for (auto& path : ListWalletDir()) {
256-
paths.push_back(path.string());
257-
}
258-
return paths;
259-
}
260-
std::vector<std::unique_ptr<Wallet>> getWallets() override
239+
WalletClient& walletClient() override
261240
{
262-
std::vector<std::unique_ptr<Wallet>> wallets;
263-
for (auto& client : m_context->chain_clients) {
264-
auto client_wallets = client->getWallets();
265-
std::move(client_wallets.begin(), client_wallets.end(), std::back_inserter(wallets));
266-
}
267-
return wallets;
268-
}
269-
std::unique_ptr<Wallet> loadWallet(const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings) override
270-
{
271-
return MakeWallet(LoadWallet(*m_context->chain, name, error, warnings));
272-
}
273-
std::unique_ptr<Wallet> createWallet(const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings, WalletCreationStatus& status) override
274-
{
275-
std::shared_ptr<CWallet> wallet;
276-
status = CreateWallet(*m_context->chain, passphrase, wallet_creation_flags, name, error, warnings, wallet);
277-
return MakeWallet(wallet);
241+
assert (m_context->wallet_client);
242+
return *m_context->wallet_client;
278243
}
279244
std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
280245
{
@@ -292,10 +257,6 @@ class NodeImpl : public Node
292257
{
293258
return MakeHandler(::uiInterface.ShowProgress_connect(fn));
294259
}
295-
std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override
296-
{
297-
return HandleLoadWallet(std::move(fn));
298-
}
299260
std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
300261
{
301262
return MakeHandler(::uiInterface.NotifyNumConnectionsChanged_connect(fn));

src/interfaces/node.h

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,13 @@ class RPCTimerInterface;
2828
class UniValue;
2929
class proxyType;
3030
enum class SynchronizationState;
31-
enum class WalletCreationStatus;
3231
struct CNodeStateStats;
3332
struct NodeContext;
3433
struct bilingual_str;
3534

3635
namespace interfaces {
3736
class Handler;
38-
class Wallet;
37+
class WalletClient;
3938
struct BlockTip;
4039

4140
//! Top-level interface for a bitcoin node (bitcoind process).
@@ -195,22 +194,8 @@ class Node
195194
//! Get unspent outputs associated with a transaction.
196195
virtual bool getUnspentOutput(const COutPoint& output, Coin& coin) = 0;
197196

198-
//! Return default wallet directory.
199-
virtual std::string getWalletDir() = 0;
200-
201-
//! Return available wallets in wallet directory.
202-
virtual std::vector<std::string> listWalletDir() = 0;
203-
204-
//! Return interfaces for accessing wallets (if any).
205-
virtual std::vector<std::unique_ptr<Wallet>> getWallets() = 0;
206-
207-
//! Attempts to load a wallet from file or directory.
208-
//! The loaded wallet is also notified to handlers previously registered
209-
//! with handleLoadWallet.
210-
virtual std::unique_ptr<Wallet> loadWallet(const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings) = 0;
211-
212-
//! Create a wallet from file
213-
virtual std::unique_ptr<Wallet> createWallet(const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings, WalletCreationStatus& status) = 0;
197+
//! Get wallet client.
198+
virtual WalletClient& walletClient() = 0;
214199

215200
//! Register handler for init messages.
216201
using InitMessageFn = std::function<void(const std::string& message)>;
@@ -232,10 +217,6 @@ class Node
232217
using ShowProgressFn = std::function<void(const std::string& title, int progress, bool resume_possible)>;
233218
virtual std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) = 0;
234219

235-
//! Register handler for load wallet messages.
236-
using LoadWalletFn = std::function<void(std::unique_ptr<Wallet> wallet)>;
237-
virtual std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) = 0;
238-
239220
//! Register handler for number of connections changed messages.
240221
using NotifyNumConnectionsChangedFn = std::function<void(int new_num_connections)>;
241222
virtual std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) = 0;

src/interfaces/wallet.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,13 +477,16 @@ class WalletImpl : public Wallet
477477
std::shared_ptr<CWallet> m_wallet;
478478
};
479479

480-
class WalletClientImpl : public ChainClient
480+
class WalletClientImpl : public WalletClient
481481
{
482482
public:
483483
WalletClientImpl(Chain& chain, std::vector<std::string> wallet_filenames)
484484
: m_chain(chain), m_wallet_filenames(std::move(wallet_filenames))
485485
{
486486
}
487+
~WalletClientImpl() override { UnloadWallets(); }
488+
489+
//! ChainClient methods
487490
void registerRpcs() override
488491
{
489492
g_rpc_chain = &m_chain;
@@ -495,6 +498,30 @@ class WalletClientImpl : public ChainClient
495498
void flush() override { return FlushWallets(); }
496499
void stop() override { return StopWallets(); }
497500
void setMockTime(int64_t time) override { return SetMockTime(time); }
501+
502+
//! WalletClient methods
503+
std::unique_ptr<Wallet> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, WalletCreationStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings) override
504+
{
505+
std::shared_ptr<CWallet> wallet;
506+
status = CreateWallet(m_chain, passphrase, wallet_creation_flags, name, error, warnings, wallet);
507+
return MakeWallet(std::move(wallet));
508+
}
509+
std::unique_ptr<Wallet> loadWallet(const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings) override
510+
{
511+
return MakeWallet(LoadWallet(m_chain, WalletLocation(name), error, warnings));
512+
}
513+
std::string getWalletDir() override
514+
{
515+
return GetWalletDir().string();
516+
}
517+
std::vector<std::string> listWalletDir() override
518+
{
519+
std::vector<std::string> paths;
520+
for (auto& path : ListWalletDir()) {
521+
paths.push_back(path.string());
522+
}
523+
return paths;
524+
}
498525
std::vector<std::unique_ptr<Wallet>> getWallets() override
499526
{
500527
std::vector<std::unique_ptr<Wallet>> wallets;
@@ -503,7 +530,10 @@ class WalletClientImpl : public ChainClient
503530
}
504531
return wallets;
505532
}
506-
~WalletClientImpl() override { UnloadWallets(); }
533+
std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override
534+
{
535+
return HandleLoadWallet(std::move(fn));
536+
}
507537

508538
Chain& m_chain;
509539
std::vector<std::string> m_wallet_filenames;
@@ -514,7 +544,7 @@ class WalletClientImpl : public ChainClient
514544

515545
std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet) { return wallet ? MakeUnique<WalletImpl>(wallet) : nullptr; }
516546

517-
std::unique_ptr<ChainClient> MakeWalletClient(Chain& chain, std::vector<std::string> wallet_filenames)
547+
std::unique_ptr<WalletClient> MakeWalletClient(Chain& chain, std::vector<std::string> wallet_filenames)
518548
{
519549
return MakeUnique<WalletClientImpl>(chain, std::move(wallet_filenames));
520550
}

src/interfaces/wallet.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define BITCOIN_INTERFACES_WALLET_H
77

88
#include <amount.h> // For CAmount
9+
#include <interfaces/chain.h> // For ChainClient
910
#include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation)
1011
#include <script/standard.h> // For CTxDestination
1112
#include <support/allocators/secure.h> // For SecureString
@@ -28,9 +29,11 @@ class CWallet;
2829
enum class FeeReason;
2930
enum class OutputType;
3031
enum class TransactionError;
32+
enum class WalletCreationStatus;
3133
enum isminetype : unsigned int;
3234
struct CRecipient;
3335
struct PartiallySignedTransaction;
36+
struct WalletContext;
3437
struct bilingual_str;
3538
typedef uint8_t isminefilter;
3639

@@ -303,6 +306,31 @@ class Wallet
303306
virtual CWallet* wallet() { return nullptr; }
304307
};
305308

309+
class WalletClient : public ChainClient
310+
{
311+
public:
312+
//! Create new wallet.
313+
virtual std::unique_ptr<Wallet> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, WalletCreationStatus& status, bilingual_str& error, std::vector<bilingual_str>& warnings) = 0;
314+
315+
//! Load existing wallet.
316+
virtual std::unique_ptr<Wallet> loadWallet(const std::string& name, bilingual_str& error, std::vector<bilingual_str>& warnings) = 0;
317+
318+
//! Return default wallet directory.
319+
virtual std::string getWalletDir() = 0;
320+
321+
//! Return available wallets in wallet directory.
322+
virtual std::vector<std::string> listWalletDir() = 0;
323+
324+
//! Return interfaces for accessing wallets (if any).
325+
virtual std::vector<std::unique_ptr<Wallet>> getWallets() = 0;
326+
327+
//! Register handler for load wallet messages. This callback is triggered by
328+
//! createWallet and loadWallet above, and also triggered when wallets are
329+
//! loaded at startup or by RPC.
330+
using LoadWalletFn = std::function<void(std::unique_ptr<Wallet> wallet)>;
331+
virtual std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) = 0;
332+
};
333+
306334
//! Information about one wallet address.
307335
struct WalletAddress
308336
{
@@ -381,6 +409,10 @@ struct WalletTxOut
381409
//! dummywallet.cpp and throws if the wallet component is not compiled.
382410
std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet);
383411

412+
//! Return implementation of ChainClient interface for a wallet client. This
413+
//! function will be undefined in builds where ENABLE_WALLET is false.
414+
std::unique_ptr<WalletClient> MakeWalletClient(Chain& chain, std::vector<std::string> wallet_filenames);
415+
384416
} // namespace interfaces
385417

386418
#endif // BITCOIN_INTERFACES_WALLET_H

src/node/context.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class PeerLogicValidation;
1919
namespace interfaces {
2020
class Chain;
2121
class ChainClient;
22+
class WalletClient;
2223
} // namespace interfaces
2324

2425
//! NodeContext struct containing references to chain state and connection
@@ -39,7 +40,11 @@ struct NodeContext {
3940
std::unique_ptr<BanMan> banman;
4041
ArgsManager* args{nullptr}; // Currently a raw pointer because the memory is not managed by this struct
4142
std::unique_ptr<interfaces::Chain> chain;
43+
//! List of all chain clients (wallet processes or other client) connected to node.
4244
std::vector<std::unique_ptr<interfaces::ChainClient>> chain_clients;
45+
//! Reference to chain client that should used to load or create wallets
46+
//! opened by the gui.
47+
interfaces::WalletClient* wallet_client{nullptr};
4348
std::unique_ptr<CScheduler> scheduler;
4449

4550
//! Declare default constructor and destructor that are not inline, so code

src/qt/bitcoin.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ void BitcoinApplication::createSplashScreen(const NetworkStyle *networkStyle)
243243
// We don't hold a direct pointer to the splash screen after creation, but the splash
244244
// screen will take care of deleting itself when finish() happens.
245245
splash->show();
246+
connect(this, &BitcoinApplication::requestedInitialize, splash, &SplashScreen::handleLoadWallet);
246247
connect(this, &BitcoinApplication::splashFinished, splash, &SplashScreen::finish);
247248
connect(this, &BitcoinApplication::requestedShutdown, splash, &QWidget::close);
248249
}

src/qt/bitcoingui.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1178,7 +1178,7 @@ void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmoun
11781178
// On new transaction, make an info balloon
11791179
QString msg = tr("Date: %1\n").arg(date) +
11801180
tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true));
1181-
if (m_node.getWallets().size() > 1 && !walletName.isEmpty()) {
1181+
if (m_node.walletClient().getWallets().size() > 1 && !walletName.isEmpty()) {
11821182
msg += tr("Wallet: %1\n").arg(walletName);
11831183
}
11841184
msg += tr("Type: %1\n").arg(type);

src/qt/splashscreen.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,12 @@ void SplashScreen::subscribeToCoreSignals()
186186
// Connect signals to client
187187
m_handler_init_message = m_node.handleInitMessage(std::bind(InitMessage, this, std::placeholders::_1));
188188
m_handler_show_progress = m_node.handleShowProgress(std::bind(ShowProgress, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
189+
}
190+
191+
void SplashScreen::handleLoadWallet()
192+
{
189193
#ifdef ENABLE_WALLET
190-
m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) { ConnectWallet(std::move(wallet)); });
194+
m_handler_load_wallet = m_node.walletClient().handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) { ConnectWallet(std::move(wallet)); });
191195
#endif
192196
}
193197

src/qt/splashscreen.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public Q_SLOTS:
4242
/** Show message and progress */
4343
void showMessage(const QString &message, int alignment, const QColor &color);
4444

45+
/** Handle wallet load notifications. */
46+
void handleLoadWallet();
47+
4548
protected:
4649
bool eventFilter(QObject * obj, QEvent * ev) override;
4750

0 commit comments

Comments
 (0)