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
This commit is contained in:
commit
65d7083f15
9 changed files with 80 additions and 41 deletions
|
@ -236,7 +236,7 @@ class NodeImpl : public Node
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
std::vector<std::unique_ptr<Wallet>> wallets;
|
std::vector<std::unique_ptr<Wallet>> wallets;
|
||||||
for (CWalletRef wallet : ::vpwallets) {
|
for (CWallet* wallet : GetWallets()) {
|
||||||
wallets.emplace_back(MakeWallet(*wallet));
|
wallets.emplace_back(MakeWallet(*wallet));
|
||||||
}
|
}
|
||||||
return wallets;
|
return wallets;
|
||||||
|
|
|
@ -180,9 +180,9 @@ void TestGUI()
|
||||||
TransactionView transactionView(platformStyle.get());
|
TransactionView transactionView(platformStyle.get());
|
||||||
auto node = interfaces::MakeNode();
|
auto node = interfaces::MakeNode();
|
||||||
OptionsModel optionsModel(*node);
|
OptionsModel optionsModel(*node);
|
||||||
vpwallets.insert(vpwallets.begin(), &wallet);
|
AddWallet(&wallet);
|
||||||
WalletModel walletModel(std::move(node->getWallets()[0]), *node, platformStyle.get(), &optionsModel);
|
WalletModel walletModel(std::move(node->getWallets().back()), *node, platformStyle.get(), &optionsModel);
|
||||||
vpwallets.erase(vpwallets.begin());
|
RemoveWallet(&wallet);
|
||||||
sendCoinsDialog.setModel(&walletModel);
|
sendCoinsDialog.setModel(&walletModel);
|
||||||
transactionView.setModel(&walletModel);
|
transactionView.setModel(&walletModel);
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,7 @@ UniValue validateaddress(const JSONRPCRequest& request)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
if (!::vpwallets.empty() && IsDeprecatedRPCEnabled("validateaddress")) {
|
if (HasWallets() && IsDeprecatedRPCEnabled("validateaddress")) {
|
||||||
ret.pushKVs(getaddressinfo(request));
|
ret.pushKVs(getaddressinfo(request));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -315,7 +315,7 @@ bool WalletInit::Open() const
|
||||||
if (!pwallet) {
|
if (!pwallet) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
vpwallets.push_back(pwallet);
|
AddWallet(pwallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -323,29 +323,29 @@ bool WalletInit::Open() const
|
||||||
|
|
||||||
void WalletInit::Start(CScheduler& scheduler) const
|
void WalletInit::Start(CScheduler& scheduler) const
|
||||||
{
|
{
|
||||||
for (CWalletRef pwallet : vpwallets) {
|
for (CWallet* pwallet : GetWallets()) {
|
||||||
pwallet->postInitProcess(scheduler);
|
pwallet->postInitProcess(scheduler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalletInit::Flush() const
|
void WalletInit::Flush() const
|
||||||
{
|
{
|
||||||
for (CWalletRef pwallet : vpwallets) {
|
for (CWallet* pwallet : GetWallets()) {
|
||||||
pwallet->Flush(false);
|
pwallet->Flush(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalletInit::Stop() const
|
void WalletInit::Stop() const
|
||||||
{
|
{
|
||||||
for (CWalletRef pwallet : vpwallets) {
|
for (CWallet* pwallet : GetWallets()) {
|
||||||
pwallet->Flush(true);
|
pwallet->Flush(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalletInit::Close() const
|
void WalletInit::Close() const
|
||||||
{
|
{
|
||||||
for (CWalletRef pwallet : vpwallets) {
|
for (CWallet* pwallet : GetWallets()) {
|
||||||
|
RemoveWallet(pwallet);
|
||||||
delete pwallet;
|
delete pwallet;
|
||||||
}
|
}
|
||||||
vpwallets.clear();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,14 +46,13 @@ CWallet *GetWalletForJSONRPCRequest(const JSONRPCRequest& request)
|
||||||
if (request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
|
if (request.URI.substr(0, WALLET_ENDPOINT_BASE.size()) == WALLET_ENDPOINT_BASE) {
|
||||||
// wallet endpoint was used
|
// wallet endpoint was used
|
||||||
std::string requestedWallet = urlDecode(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
|
std::string requestedWallet = urlDecode(request.URI.substr(WALLET_ENDPOINT_BASE.size()));
|
||||||
for (CWalletRef pwallet : ::vpwallets) {
|
CWallet* pwallet = GetWallet(requestedWallet);
|
||||||
if (pwallet->GetName() == requestedWallet) {
|
if (!pwallet) throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
|
||||||
return pwallet;
|
return pwallet;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
|
std::vector<CWallet*> wallets = GetWallets();
|
||||||
}
|
return wallets.size() == 1 || (request.fHelp && wallets.size() > 0) ? wallets[0] : nullptr;
|
||||||
return ::vpwallets.size() == 1 || (request.fHelp && ::vpwallets.size() > 0) ? ::vpwallets[0] : nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HelpRequiringPassphrase(CWallet * const pwallet)
|
std::string HelpRequiringPassphrase(CWallet * const pwallet)
|
||||||
|
@ -67,7 +66,7 @@ bool EnsureWalletIsAvailable(CWallet * const pwallet, bool avoidException)
|
||||||
{
|
{
|
||||||
if (pwallet) return true;
|
if (pwallet) return true;
|
||||||
if (avoidException) return false;
|
if (avoidException) return false;
|
||||||
if (::vpwallets.empty()) {
|
if (!HasWallets()) {
|
||||||
// Note: It isn't currently possible to trigger this error because
|
// Note: It isn't currently possible to trigger this error because
|
||||||
// wallet RPC methods aren't registered unless a wallet is loaded. But
|
// wallet RPC methods aren't registered unless a wallet is loaded. But
|
||||||
// this error is being kept as a precaution, because it's possible in
|
// this error is being kept as a precaution, because it's possible in
|
||||||
|
@ -2862,8 +2861,7 @@ UniValue listwallets(const JSONRPCRequest& request)
|
||||||
|
|
||||||
UniValue obj(UniValue::VARR);
|
UniValue obj(UniValue::VARR);
|
||||||
|
|
||||||
for (CWalletRef pwallet : vpwallets) {
|
for (CWallet* pwallet : GetWallets()) {
|
||||||
|
|
||||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
|
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
|
||||||
// after.
|
// after.
|
||||||
{
|
{
|
||||||
CWallet wallet("dummy", WalletDatabase::CreateDummy());
|
CWallet wallet("dummy", WalletDatabase::CreateDummy());
|
||||||
vpwallets.insert(vpwallets.begin(), &wallet);
|
AddWallet(&wallet);
|
||||||
UniValue keys;
|
UniValue keys;
|
||||||
keys.setArray();
|
keys.setArray();
|
||||||
UniValue key;
|
UniValue key;
|
||||||
|
@ -105,7 +105,7 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
|
||||||
"downloading and rescanning the relevant blocks (see -reindex and -rescan "
|
"downloading and rescanning the relevant blocks (see -reindex and -rescan "
|
||||||
"options).\"}},{\"success\":true}]",
|
"options).\"}},{\"success\":true}]",
|
||||||
0, oldTip->GetBlockTimeMax(), TIMESTAMP_WINDOW));
|
0, oldTip->GetBlockTimeMax(), TIMESTAMP_WINDOW));
|
||||||
vpwallets.erase(vpwallets.begin());
|
RemoveWallet(&wallet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,9 +140,9 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
|
||||||
JSONRPCRequest request;
|
JSONRPCRequest request;
|
||||||
request.params.setArray();
|
request.params.setArray();
|
||||||
request.params.push_back((pathTemp / "wallet.backup").string());
|
request.params.push_back((pathTemp / "wallet.backup").string());
|
||||||
vpwallets.insert(vpwallets.begin(), &wallet);
|
AddWallet(&wallet);
|
||||||
::dumpwallet(request);
|
::dumpwallet(request);
|
||||||
vpwallets.erase(vpwallets.begin());
|
RemoveWallet(&wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME
|
// Call importwallet RPC and verify all blocks with timestamps >= BLOCK_TIME
|
||||||
|
@ -153,9 +153,9 @@ BOOST_FIXTURE_TEST_CASE(importwallet_rescan, TestChain100Setup)
|
||||||
JSONRPCRequest request;
|
JSONRPCRequest request;
|
||||||
request.params.setArray();
|
request.params.setArray();
|
||||||
request.params.push_back((pathTemp / "wallet.backup").string());
|
request.params.push_back((pathTemp / "wallet.backup").string());
|
||||||
vpwallets.insert(vpwallets.begin(), &wallet);
|
AddWallet(&wallet);
|
||||||
::importwallet(request);
|
::importwallet(request);
|
||||||
vpwallets.erase(vpwallets.begin());
|
RemoveWallet(&wallet);
|
||||||
|
|
||||||
LOCK(wallet.cs_wallet);
|
LOCK(wallet.cs_wallet);
|
||||||
BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3U);
|
BOOST_CHECK_EQUAL(wallet.mapWallet.size(), 3U);
|
||||||
|
|
|
@ -28,12 +28,50 @@
|
||||||
#include <utilmoneystr.h>
|
#include <utilmoneystr.h>
|
||||||
#include <wallet/fees.h>
|
#include <wallet/fees.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
|
||||||
std::vector<CWalletRef> vpwallets;
|
static std::vector<CWallet*> vpwallets;
|
||||||
|
|
||||||
|
bool AddWallet(CWallet* wallet)
|
||||||
|
{
|
||||||
|
assert(wallet);
|
||||||
|
std::vector<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)
|
||||||
|
{
|
||||||
|
assert(wallet);
|
||||||
|
std::vector<CWallet*>::iterator i = std::find(vpwallets.begin(), vpwallets.end(), wallet);
|
||||||
|
if (i == vpwallets.end()) return false;
|
||||||
|
vpwallets.erase(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasWallets()
|
||||||
|
{
|
||||||
|
return !vpwallets.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<CWallet*> GetWallets()
|
||||||
|
{
|
||||||
|
return vpwallets;
|
||||||
|
}
|
||||||
|
|
||||||
|
CWallet* GetWallet(const std::string& name)
|
||||||
|
{
|
||||||
|
for (CWallet* wallet : vpwallets) {
|
||||||
|
if (wallet->GetName() == name) return wallet;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/** Transaction fee set by the user */
|
/** Transaction fee set by the user */
|
||||||
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
|
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
|
||||||
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
|
unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
|
||||||
|
|
|
@ -32,8 +32,11 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
typedef CWallet* CWalletRef;
|
bool AddWallet(CWallet* wallet);
|
||||||
extern std::vector<CWalletRef> vpwallets;
|
bool RemoveWallet(CWallet* wallet);
|
||||||
|
bool HasWallets();
|
||||||
|
std::vector<CWallet*> GetWallets();
|
||||||
|
CWallet* GetWallet(const std::string& name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings
|
* Settings
|
||||||
|
@ -1230,10 +1233,10 @@ std::vector<CTxDestination> GetAllDestinationsForKey(const CPubKey& key);
|
||||||
class WalletRescanReserver
|
class WalletRescanReserver
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
CWalletRef m_wallet;
|
CWallet* m_wallet;
|
||||||
bool m_could_reserve;
|
bool m_could_reserve;
|
||||||
public:
|
public:
|
||||||
explicit WalletRescanReserver(CWalletRef w) : m_wallet(w), m_could_reserve(false) {}
|
explicit WalletRescanReserver(CWallet* w) : m_wallet(w), m_could_reserve(false) {}
|
||||||
|
|
||||||
bool reserve()
|
bool reserve()
|
||||||
{
|
{
|
||||||
|
|
|
@ -756,7 +756,7 @@ void MaybeCompactWalletDB()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CWalletRef pwallet : vpwallets) {
|
for (CWallet* pwallet : GetWallets()) {
|
||||||
WalletDatabase& dbh = pwallet->GetDBHandle();
|
WalletDatabase& dbh = pwallet->GetDBHandle();
|
||||||
|
|
||||||
unsigned int nUpdateCounter = dbh.nUpdateCounter;
|
unsigned int nUpdateCounter = dbh.nUpdateCounter;
|
||||||
|
|
Loading…
Reference in a new issue