Skip to content

Commit

Permalink
wallet: Use shared pointer to retain wallet instance
Browse files Browse the repository at this point in the history
  • Loading branch information
promag committed May 22, 2018
1 parent 6916024 commit 80b4910
Show file tree
Hide file tree
Showing 15 changed files with 239 additions and 139 deletions.
6 changes: 3 additions & 3 deletions src/interfaces/node.cpp
Expand Up @@ -222,8 +222,8 @@ class NodeImpl : public Node
{
#ifdef ENABLE_WALLET
std::vector<std::unique_ptr<Wallet>> wallets;
for (CWallet* wallet : GetWallets()) {
wallets.emplace_back(MakeWallet(*wallet));
for (const std::shared_ptr<CWallet>& wallet : GetWallets()) {
wallets.emplace_back(MakeWallet(wallet));
}
return wallets;
#else
Expand All @@ -249,7 +249,7 @@ class NodeImpl : public Node
std::unique_ptr<Handler> handleLoadWallet(LoadWalletFn fn) override
{
CHECK_WALLET(
return MakeHandler(::uiInterface.LoadWallet.connect([fn](CWallet* wallet) { fn(MakeWallet(*wallet)); })));
return MakeHandler(::uiInterface.LoadWallet.connect([fn](std::shared_ptr<CWallet> wallet) { fn(MakeWallet(wallet)); })));
}
std::unique_ptr<Handler> handleNotifyNumConnectionsChanged(NotifyNumConnectionsChangedFn fn) override
{
Expand Down
5 changes: 3 additions & 2 deletions src/interfaces/wallet.cpp
Expand Up @@ -118,7 +118,7 @@ WalletTxOut MakeWalletTxOut(CWallet& wallet, const CWalletTx& wtx, int n, int de
class WalletImpl : public Wallet
{
public:
WalletImpl(CWallet& wallet) : m_wallet(wallet) {}
WalletImpl(const std::shared_ptr<CWallet>& wallet) : m_shared_wallet(wallet), m_wallet(*wallet.get()) {}

bool encryptWallet(const SecureString& wallet_passphrase) override
{
Expand Down Expand Up @@ -453,11 +453,12 @@ class WalletImpl : public Wallet
return MakeHandler(m_wallet.NotifyWatchonlyChanged.connect(fn));
}

std::shared_ptr<CWallet> m_shared_wallet;
CWallet& m_wallet;
};

} // namespace

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

} // namespace interfaces
2 changes: 1 addition & 1 deletion src/interfaces/wallet.h
Expand Up @@ -363,7 +363,7 @@ struct WalletTxOut

//! Return implementation of Wallet interface. This function will be undefined
//! in builds where ENABLE_WALLET is false.
std::unique_ptr<Wallet> MakeWallet(CWallet& wallet);
std::unique_ptr<Wallet> MakeWallet(const std::shared_ptr<CWallet>& wallet);

} // namespace interfaces

Expand Down
18 changes: 9 additions & 9 deletions src/qt/test/addressbooktests.cpp
Expand Up @@ -56,15 +56,15 @@ void EditAddressAndSubmit(
void TestAddAddressesToSendBook()
{
TestChain100Setup test;
CWallet wallet("mock", WalletDatabase::CreateMock());
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>("mock", WalletDatabase::CreateMock());
bool firstRun;
wallet.LoadWallet(firstRun);
wallet->LoadWallet(firstRun);

auto build_address = [&wallet]() {
CKey key;
key.MakeNewKey(true);
CTxDestination dest(GetDestinationForKey(
key.GetPubKey(), wallet.m_default_address_type));
key.GetPubKey(), wallet->m_default_address_type));

return std::make_pair(dest, QString::fromStdString(EncodeDestination(dest)));
};
Expand All @@ -87,13 +87,13 @@ void TestAddAddressesToSendBook()
std::tie(std::ignore, new_address) = build_address();

{
LOCK(wallet.cs_wallet);
wallet.SetAddressBook(r_key_dest, r_label.toStdString(), "receive");
wallet.SetAddressBook(s_key_dest, s_label.toStdString(), "send");
LOCK(wallet->cs_wallet);
wallet->SetAddressBook(r_key_dest, r_label.toStdString(), "receive");
wallet->SetAddressBook(s_key_dest, s_label.toStdString(), "send");
}

auto check_addbook_size = [&wallet](int expected_size) {
QCOMPARE(static_cast<int>(wallet.mapAddressBook.size()), expected_size);
QCOMPARE(static_cast<int>(wallet->mapAddressBook.size()), expected_size);
};

// We should start with the two addresses we added earlier and nothing else.
Expand All @@ -103,9 +103,9 @@ void TestAddAddressesToSendBook()
std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
auto node = interfaces::MakeNode();
OptionsModel optionsModel(*node);
AddWallet(&wallet);
AddWallet(wallet);
WalletModel walletModel(std::move(node->getWallets()[0]), *node, platformStyle.get(), &optionsModel);
RemoveWallet(&wallet);
RemoveWallet(wallet);
EditAddressDialog editAddressDialog(EditAddressDialog::NewSendingAddress);
editAddressDialog.setModel(walletModel.getAddressTableModel());

Expand Down
24 changes: 12 additions & 12 deletions src/qt/test/wallettests.cpp
Expand Up @@ -144,39 +144,39 @@ void TestGUI()
for (int i = 0; i < 5; ++i) {
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
}
CWallet wallet("mock", WalletDatabase::CreateMock());
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>("mock", WalletDatabase::CreateMock());
bool firstRun;
wallet.LoadWallet(firstRun);
wallet->LoadWallet(firstRun);
{
LOCK(wallet.cs_wallet);
wallet.SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet.m_default_address_type), "", "receive");
wallet.AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
LOCK(wallet->cs_wallet);
wallet->SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet->m_default_address_type), "", "receive");
wallet->AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
}
{
LOCK(cs_main);
WalletRescanReserver reserver(&wallet);
WalletRescanReserver reserver(wallet.get());
reserver.reserve();
wallet.ScanForWalletTransactions(chainActive.Genesis(), nullptr, reserver, true);
wallet->ScanForWalletTransactions(chainActive.Genesis(), nullptr, reserver, true);
}
wallet.SetBroadcastTransactions(true);
wallet->SetBroadcastTransactions(true);

// Create widgets for sending coins and listing transactions.
std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
SendCoinsDialog sendCoinsDialog(platformStyle.get());
TransactionView transactionView(platformStyle.get());
auto node = interfaces::MakeNode();
OptionsModel optionsModel(*node);
AddWallet(&wallet);
AddWallet(wallet);
WalletModel walletModel(std::move(node->getWallets().back()), *node, platformStyle.get(), &optionsModel);
RemoveWallet(&wallet);
RemoveWallet(wallet);
sendCoinsDialog.setModel(&walletModel);
transactionView.setModel(&walletModel);

// Send two transactions, and verify they are added to transaction list.
TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel();
QCOMPARE(transactionTableModel->rowCount({}), 105);
uint256 txid1 = SendCoins(wallet, sendCoinsDialog, CKeyID(), 5 * COIN, false /* rbf */);
uint256 txid2 = SendCoins(wallet, sendCoinsDialog, CKeyID(), 10 * COIN, true /* rbf */);
uint256 txid1 = SendCoins(*wallet.get(), sendCoinsDialog, CKeyID(), 5 * COIN, false /* rbf */);
uint256 txid2 = SendCoins(*wallet.get(), sendCoinsDialog, CKeyID(), 10 * COIN, true /* rbf */);
QCOMPARE(transactionTableModel->rowCount({}), 107);
QVERIFY(FindTx(*transactionTableModel, txid1).isValid());
QVERIFY(FindTx(*transactionTableModel, txid2).isValid());
Expand Down
3 changes: 2 additions & 1 deletion src/rpc/rawtransaction.cpp
Expand Up @@ -988,7 +988,8 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
UniValue signrawtransaction(const JSONRPCRequest& request)
{
#ifdef ENABLE_WALLET
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
#endif

if (request.fHelp || request.params.size() < 1 || request.params.size() > 4)
Expand Down
3 changes: 2 additions & 1 deletion src/ui_interface.h
Expand Up @@ -6,6 +6,7 @@
#ifndef BITCOIN_UI_INTERFACE_H
#define BITCOIN_UI_INTERFACE_H

#include <memory>
#include <stdint.h>
#include <string>

Expand Down Expand Up @@ -92,7 +93,7 @@ class CClientUIInterface
boost::signals2::signal<void ()> NotifyAlertChanged;

/** A wallet has been loaded. */
boost::signals2::signal<void (CWallet* wallet)> LoadWallet;
boost::signals2::signal<void (std::shared_ptr<CWallet> wallet)> LoadWallet;

/**
* Show progress e.g. for verifychain.
Expand Down
11 changes: 5 additions & 6 deletions src/wallet/init.cpp
Expand Up @@ -226,7 +226,7 @@ bool WalletInit::Open() const
}

for (const std::string& walletFile : gArgs.GetArgs("-wallet")) {
CWallet * const pwallet = CWallet::CreateWalletFromFile(walletFile, fs::absolute(walletFile, GetWalletDir()));
std::shared_ptr<CWallet> pwallet = CWallet::CreateWalletFromFile(walletFile, fs::absolute(walletFile, GetWalletDir()));
if (!pwallet) {
return false;
}
Expand All @@ -238,7 +238,7 @@ bool WalletInit::Open() const

void WalletInit::Start(CScheduler& scheduler) const
{
for (CWallet* pwallet : GetWallets()) {
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
pwallet->postInitProcess();
}

Expand All @@ -248,22 +248,21 @@ void WalletInit::Start(CScheduler& scheduler) const

void WalletInit::Flush() const
{
for (CWallet* pwallet : GetWallets()) {
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
pwallet->Flush(false);
}
}

void WalletInit::Stop() const
{
for (CWallet* pwallet : GetWallets()) {
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
pwallet->Flush(true);
}
}

void WalletInit::Close() const
{
for (CWallet* pwallet : GetWallets()) {
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
RemoveWallet(pwallet);
delete pwallet;
}
}
32 changes: 21 additions & 11 deletions src/wallet/rpcdump.cpp
Expand Up @@ -56,7 +56,7 @@ static std::string DecodeDumpString(const std::string &str) {
for (unsigned int pos = 0; pos < str.length(); pos++) {
unsigned char c = str[pos];
if (c == '%' && pos+2 < str.length()) {
c = (((str[pos+1]>>6)*9+((str[pos+1]-'0')&15)) << 4) |
c = (((str[pos+1]>>6)*9+((str[pos+1]-'0')&15)) << 4) |
((str[pos+2]>>6)*9+((str[pos+2]-'0')&15));
pos += 2;
}
Expand Down Expand Up @@ -89,7 +89,8 @@ static bool GetWalletAddressesForKey(CWallet * const pwallet, const CKeyID &keyi

UniValue importprivkey(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue;
}
Expand Down Expand Up @@ -185,7 +186,8 @@ UniValue importprivkey(const JSONRPCRequest& request)

UniValue abortrescan(const JSONRPCRequest& request)
{
CWallet* const pwallet = GetWalletForJSONRPCRequest(request);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue;
}
Expand Down Expand Up @@ -246,7 +248,8 @@ static void ImportAddress(CWallet* const pwallet, const CTxDestination& dest, co

UniValue importaddress(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue;
}
Expand Down Expand Up @@ -330,7 +333,8 @@ UniValue importaddress(const JSONRPCRequest& request)

UniValue importprunedfunds(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue;
}
Expand Down Expand Up @@ -392,7 +396,8 @@ UniValue importprunedfunds(const JSONRPCRequest& request)

UniValue removeprunedfunds(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue;
}
Expand Down Expand Up @@ -430,7 +435,8 @@ UniValue removeprunedfunds(const JSONRPCRequest& request)

UniValue importpubkey(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue;
}
Expand Down Expand Up @@ -506,7 +512,8 @@ UniValue importpubkey(const JSONRPCRequest& request)

UniValue importwallet(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue;
}
Expand Down Expand Up @@ -640,7 +647,8 @@ UniValue importwallet(const JSONRPCRequest& request)

UniValue dumpprivkey(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue;
}
Expand Down Expand Up @@ -683,7 +691,8 @@ UniValue dumpprivkey(const JSONRPCRequest& request)

UniValue dumpwallet(const JSONRPCRequest& request)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request);
CWallet* const pwallet = wallet.get();
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
return NullUniValue;
}
Expand Down Expand Up @@ -1127,7 +1136,8 @@ static int64_t GetImportTimestamp(const UniValue& data, int64_t now)

UniValue importmulti(const JSONRPCRequest& mainRequest)
{
CWallet * const pwallet = GetWalletForJSONRPCRequest(mainRequest);
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(mainRequest);
CWallet* const pwallet = wallet.get();
if (!EnsureWalletIsAvailable(pwallet, mainRequest.fHelp)) {
return NullUniValue;
}
Expand Down

0 comments on commit 80b4910

Please sign in to comment.