wallet: Use shared pointer to retain wallet instance

This commit is contained in:
João Barbosa
2018-05-22 16:18:07 +01:00
parent 6916024768
commit 80b4910f7d
15 changed files with 239 additions and 139 deletions

View File

@@ -36,23 +36,23 @@
#include <boost/algorithm/string/replace.hpp>
static CCriticalSection cs_wallets;
static std::vector<CWallet*> vpwallets GUARDED_BY(cs_wallets);
static std::vector<std::shared_ptr<CWallet>> vpwallets GUARDED_BY(cs_wallets);
bool AddWallet(CWallet* wallet)
bool AddWallet(const std::shared_ptr<CWallet>& wallet)
{
LOCK(cs_wallets);
assert(wallet);
std::vector<CWallet*>::const_iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
std::vector<std::shared_ptr<CWallet>>::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)
bool RemoveWallet(const std::shared_ptr<CWallet>& wallet)
{
LOCK(cs_wallets);
assert(wallet);
std::vector<CWallet*>::iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
std::vector<std::shared_ptr<CWallet>>::iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
if (i == vpwallets.end()) return false;
vpwallets.erase(i);
return true;
@@ -64,16 +64,16 @@ bool HasWallets()
return !vpwallets.empty();
}
std::vector<CWallet*> GetWallets()
std::vector<std::shared_ptr<CWallet>> GetWallets()
{
LOCK(cs_wallets);
return vpwallets;
}
CWallet* GetWallet(const std::string& name)
std::shared_ptr<CWallet> GetWallet(const std::string& name)
{
LOCK(cs_wallets);
for (CWallet* wallet : vpwallets) {
for (const std::shared_ptr<CWallet>& wallet : vpwallets) {
if (wallet->GetName() == name) return wallet;
}
return nullptr;
@@ -3201,8 +3201,6 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
if (nLoadWalletRet != DBErrors::LOAD_OK)
return nLoadWalletRet;
uiInterface.LoadWallet(this);
return DBErrors::LOAD_OK;
}
@@ -4038,7 +4036,7 @@ bool CWallet::Verify(std::string wallet_file, bool salvage_wallet, std::string&
return WalletBatch::VerifyDatabaseFile(wallet_path, warning_string, error_string);
}
CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& path)
std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(const std::string& name, const fs::path& path)
{
const std::string& walletFile = name;
@@ -4060,10 +4058,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
int64_t nStart = GetTimeMillis();
bool fFirstRun = true;
// Make a temporary wallet unique pointer so memory doesn't get leaked if
// wallet creation fails.
auto temp_wallet = MakeUnique<CWallet>(name, WalletDatabase::Create(path));
CWallet* walletInstance = temp_wallet.get();
std::shared_ptr<CWallet> walletInstance = std::make_shared<CWallet>(name, WalletDatabase::Create(path));
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
if (nLoadWalletRet != DBErrors::LOAD_OK)
{
@@ -4092,6 +4087,8 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
}
}
uiInterface.LoadWallet(walletInstance);
int prev_version = walletInstance->nWalletVersion;
if (gArgs.GetBoolArg("-upgradewallet", fFirstRun))
{
@@ -4304,7 +4301,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
nStart = GetTimeMillis();
{
WalletRescanReserver reserver(walletInstance);
WalletRescanReserver reserver(walletInstance.get());
if (!reserver.reserve()) {
InitError(_("Failed to rescan the wallet during initialization"));
return nullptr;
@@ -4342,7 +4339,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path&
}
// Register with the validation interface. It's ok to do this after rescan since we're still holding cs_main.
RegisterValidationInterface(temp_wallet.release());
RegisterValidationInterface(walletInstance.get());
walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));