Skip to content

Commit 6196e93

Browse files
committed
Merge #16963: wallet: Fix unique_ptr usage in boost::signals2
6d6a7a8 gui: Fix duplicate wallet showing up (João Barbosa) 81ea66c Drop signal CClientUIInterface::LoadWallet (Russell Yanofsky) Pull request description: This PR includes 2 fixes: - prevent GUI LoadWallet handlers from crashing on startup when multiple handlers are attached, because the first handler takes ownership of the wallet unique pointer. Now every handler will receive its own unique pointer; - prevent showing a wallet twice in the GUI on startup due to a race with `loadwallet`. Fixes #16937 ACKs for top commit: fjahr: code review ACK 6d6a7a8 ryanofsky: Code review ACK 6d6a7a8. No changes since last ACK other than rebase due to #17070 kallewoof: Code review ACK 6d6a7a8 Tree-SHA512: 7f0658c9011f81dfa176a094c2263448ee1d14fda7dc94e8b55ee9c8b81538bd2d1e4bf8a8dbfcd029ebfc9feb6d3cda9dee3f911122df0a4b1e0ca75f653ba4
2 parents 295211e + 6d6a7a8 commit 6196e93

File tree

13 files changed

+53
-26
lines changed

13 files changed

+53
-26
lines changed

src/dummywallet.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ enum class WalletCreationStatus;
1111

1212
namespace interfaces {
1313
class Chain;
14+
class Handler;
15+
class Wallet;
1416
}
1517

1618
class DummyWalletInit : public WalletInitInterface {
@@ -80,9 +82,13 @@ WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString&
8082
throw std::logic_error("Wallet function called in non-wallet build.");
8183
}
8284

83-
namespace interfaces {
85+
using LoadWalletFn = std::function<void(std::unique_ptr<interfaces::Wallet> wallet)>;
86+
std::unique_ptr<interfaces::Handler> HandleLoadWallet(LoadWalletFn load_wallet)
87+
{
88+
throw std::logic_error("Wallet function called in non-wallet build.");
89+
}
8490

85-
class Wallet;
91+
namespace interfaces {
8692

8793
std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet)
8894
{

src/interfaces/chain.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,6 @@ class ChainImpl : public Chain
338338
void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }
339339
void initWarning(const std::string& message) override { InitWarning(message); }
340340
void initError(const std::string& message) override { InitError(message); }
341-
void loadWallet(std::unique_ptr<Wallet> wallet) override { ::uiInterface.LoadWallet(wallet); }
342341
void showProgress(const std::string& title, int progress, bool resume_possible) override
343342
{
344343
::uiInterface.ShowProgress(title, progress, resume_possible);

src/interfaces/chain.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class Wallet;
4343
//! asynchronously
4444
//! (https://github.com/bitcoin/bitcoin/pull/10973#issuecomment-380101269).
4545
//!
46-
//! * The initMessages() and loadWallet() methods which the wallet uses to send
46+
//! * The initMessage() and showProgress() methods which the wallet uses to send
4747
//! notifications to the GUI should go away when GUI and wallet can directly
4848
//! communicate with each other without going through the node
4949
//! (https://github.com/bitcoin/bitcoin/pull/15288#discussion_r253321096).
@@ -209,9 +209,6 @@ class Chain
209209
//! Send init error.
210210
virtual void initError(const std::string& message) = 0;
211211

212-
//! Send wallet load notification to the GUI.
213-
virtual void loadWallet(std::unique_ptr<Wallet> wallet) = 0;
214-
215212
//! Send progress indicator.
216213
virtual void showProgress(const std::string& title, int progress, bool resume_possible) = 0;
217214

src/interfaces/handler.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,25 @@ class HandlerImpl : public Handler
2222
boost::signals2::scoped_connection m_connection;
2323
};
2424

25+
class CleanupHandler : public Handler
26+
{
27+
public:
28+
explicit CleanupHandler(std::function<void()> cleanup) : m_cleanup(std::move(cleanup)) {}
29+
~CleanupHandler() override { if (!m_cleanup) return; m_cleanup(); m_cleanup = nullptr; }
30+
void disconnect() override { if (!m_cleanup) return; m_cleanup(); m_cleanup = nullptr; }
31+
std::function<void()> m_cleanup;
32+
};
33+
2534
} // namespace
2635

2736
std::unique_ptr<Handler> MakeHandler(boost::signals2::connection connection)
2837
{
2938
return MakeUnique<HandlerImpl>(std::move(connection));
3039
}
3140

41+
std::unique_ptr<Handler> MakeHandler(std::function<void()> cleanup)
42+
{
43+
return MakeUnique<CleanupHandler>(std::move(cleanup));
44+
}
45+
3246
} // namespace interfaces

src/interfaces/handler.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#ifndef BITCOIN_INTERFACES_HANDLER_H
66
#define BITCOIN_INTERFACES_HANDLER_H
77

8+
#include <functional>
89
#include <memory>
910

1011
namespace boost {
@@ -30,6 +31,9 @@ class Handler
3031
//! Return handler wrapping a boost signal connection.
3132
std::unique_ptr<Handler> MakeHandler(boost::signals2::connection connection);
3233

34+
//! Return handler wrapping a cleanup function.
35+
std::unique_ptr<Handler> MakeHandler(std::function<void()> cleanup);
36+
3337
} // namespace interfaces
3438

3539
#endif // BITCOIN_INTERFACES_HANDLER_H

src/interfaces/node.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,10 @@ std::vector<fs::path> ListWalletDir();
4343
std::vector<std::shared_ptr<CWallet>> GetWallets();
4444
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::vector<std::string>& warnings);
4545
WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::vector<std::string>& warnings, std::shared_ptr<CWallet>& result);
46+
std::unique_ptr<interfaces::Handler> HandleLoadWallet(interfaces::Node::LoadWalletFn load_wallet);
4647

4748
namespace interfaces {
4849

49-
class Wallet;
50-
5150
namespace {
5251

5352
class NodeImpl : public Node
@@ -286,7 +285,7 @@ class NodeImpl : public Node
286285
}
287286
std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override
288287
{
289-
return MakeHandler(::uiInterface.LoadWallet_connect([fn](std::unique_ptr<Wallet>& wallet) { fn(std::move(wallet)); }));
288+
return HandleLoadWallet(std::move(fn));
290289
}
291290
std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
292291
{

src/qt/bitcoingui.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,10 +634,10 @@ void BitcoinGUI::setWalletController(WalletController* wallet_controller)
634634
void BitcoinGUI::addWallet(WalletModel* walletModel)
635635
{
636636
if (!walletFrame) return;
637+
if (!walletFrame->addWallet(walletModel)) return;
637638
const QString display_name = walletModel->getDisplayName();
638639
setWalletActionsEnabled(true);
639640
rpcConsole->addWallet(walletModel);
640-
walletFrame->addWallet(walletModel);
641641
m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
642642
if (m_wallet_selector->count() == 2) {
643643
m_wallet_selector_label_action->setVisible(true);

src/qt/walletframe.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ void WalletFrame::setClientModel(ClientModel *_clientModel)
3939
this->clientModel = _clientModel;
4040
}
4141

42-
void WalletFrame::addWallet(WalletModel *walletModel)
42+
bool WalletFrame::addWallet(WalletModel *walletModel)
4343
{
44-
if (!gui || !clientModel || !walletModel) return;
44+
if (!gui || !clientModel || !walletModel) return false;
4545

46-
if (mapWalletViews.count(walletModel) > 0) return;
46+
if (mapWalletViews.count(walletModel) > 0) return false;
4747

4848
WalletView *walletView = new WalletView(platformStyle, this);
4949
walletView->setBitcoinGUI(gui);
@@ -62,6 +62,8 @@ void WalletFrame::addWallet(WalletModel *walletModel)
6262
mapWalletViews[walletModel] = walletView;
6363

6464
connect(walletView, &WalletView::outOfSyncWarningClicked, this, &WalletFrame::outOfSyncWarningClicked);
65+
66+
return true;
6567
}
6668

6769
void WalletFrame::setCurrentWallet(WalletModel* wallet_model)

src/qt/walletframe.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class WalletFrame : public QFrame
3636

3737
void setClientModel(ClientModel *clientModel);
3838

39-
void addWallet(WalletModel *walletModel);
39+
bool addWallet(WalletModel *walletModel);
4040
void setCurrentWallet(WalletModel* wallet_model);
4141
void removeWallet(WalletModel* wallet_model);
4242
void removeAllWallets();

src/ui_interface.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ struct UISignals {
1616
boost::signals2::signal<CClientUIInterface::NotifyNumConnectionsChangedSig> NotifyNumConnectionsChanged;
1717
boost::signals2::signal<CClientUIInterface::NotifyNetworkActiveChangedSig> NotifyNetworkActiveChanged;
1818
boost::signals2::signal<CClientUIInterface::NotifyAlertChangedSig> NotifyAlertChanged;
19-
boost::signals2::signal<CClientUIInterface::LoadWalletSig> LoadWallet;
2019
boost::signals2::signal<CClientUIInterface::ShowProgressSig> ShowProgress;
2120
boost::signals2::signal<CClientUIInterface::NotifyBlockTipSig> NotifyBlockTip;
2221
boost::signals2::signal<CClientUIInterface::NotifyHeaderTipSig> NotifyHeaderTip;
@@ -36,7 +35,6 @@ ADD_SIGNALS_IMPL_WRAPPER(InitMessage);
3635
ADD_SIGNALS_IMPL_WRAPPER(NotifyNumConnectionsChanged);
3736
ADD_SIGNALS_IMPL_WRAPPER(NotifyNetworkActiveChanged);
3837
ADD_SIGNALS_IMPL_WRAPPER(NotifyAlertChanged);
39-
ADD_SIGNALS_IMPL_WRAPPER(LoadWallet);
4038
ADD_SIGNALS_IMPL_WRAPPER(ShowProgress);
4139
ADD_SIGNALS_IMPL_WRAPPER(NotifyBlockTip);
4240
ADD_SIGNALS_IMPL_WRAPPER(NotifyHeaderTip);
@@ -48,7 +46,6 @@ void CClientUIInterface::InitMessage(const std::string& message) { return g_ui_s
4846
void CClientUIInterface::NotifyNumConnectionsChanged(int newNumConnections) { return g_ui_signals.NotifyNumConnectionsChanged(newNumConnections); }
4947
void CClientUIInterface::NotifyNetworkActiveChanged(bool networkActive) { return g_ui_signals.NotifyNetworkActiveChanged(networkActive); }
5048
void CClientUIInterface::NotifyAlertChanged() { return g_ui_signals.NotifyAlertChanged(); }
51-
void CClientUIInterface::LoadWallet(std::unique_ptr<interfaces::Wallet>& wallet) { return g_ui_signals.LoadWallet(wallet); }
5249
void CClientUIInterface::ShowProgress(const std::string& title, int nProgress, bool resume_possible) { return g_ui_signals.ShowProgress(title, nProgress, resume_possible); }
5350
void CClientUIInterface::NotifyBlockTip(bool b, const CBlockIndex* i) { return g_ui_signals.NotifyBlockTip(b, i); }
5451
void CClientUIInterface::NotifyHeaderTip(bool b, const CBlockIndex* i) { return g_ui_signals.NotifyHeaderTip(b, i); }

0 commit comments

Comments
 (0)