mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 12:32:48 +01:00
Merge pull request #4400 from PastaPastaPasta/backport-new-wallet-pr1
Backport 14941, 15149 and 15210
This commit is contained in:
commit
4dbe320662
5
doc/release-notes-14941.md
Normal file
5
doc/release-notes-14941.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Miscellaneous RPC changes
|
||||||
|
------------
|
||||||
|
|
||||||
|
- The `unloadwallet` RPC is now synchronous, meaning that it blocks until the
|
||||||
|
wallet is fully unloaded.
|
@ -376,6 +376,7 @@ void PrepareShutdown()
|
|||||||
LogPrintf("%s: Unable to remove PID file: %s\n", __func__, e.what());
|
LogPrintf("%s: Unable to remove PID file: %s\n", __func__, e.what());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
g_wallet_init_interface.Close();
|
||||||
UnregisterAllValidationInterfaces();
|
UnregisterAllValidationInterfaces();
|
||||||
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
||||||
GetMainSignals().UnregisterWithMempoolSignals(mempool);
|
GetMainSignals().UnregisterWithMempoolSignals(mempool);
|
||||||
@ -397,7 +398,6 @@ void Shutdown()
|
|||||||
PrepareShutdown();
|
PrepareShutdown();
|
||||||
}
|
}
|
||||||
// Shutdown part 2: delete wallet instance
|
// Shutdown part 2: delete wallet instance
|
||||||
g_wallet_init_interface.Close();
|
|
||||||
globalVerifyHandle.reset();
|
globalVerifyHandle.reset();
|
||||||
ECC_Stop();
|
ECC_Stop();
|
||||||
LogPrintf("%s: done\n", __func__);
|
LogPrintf("%s: done\n", __func__);
|
||||||
|
@ -73,7 +73,8 @@ const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
|
|||||||
|
|
||||||
BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle, QWidget* parent) :
|
BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle, QWidget* parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
m_node(node)
|
m_node(node),
|
||||||
|
m_network_style(networkStyle)
|
||||||
{
|
{
|
||||||
GUIUtil::loadTheme(true);
|
GUIUtil::loadTheme(true);
|
||||||
|
|
||||||
@ -83,22 +84,12 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle,
|
|||||||
move(QApplication::desktop()->availableGeometry().center() - frameGeometry().center());
|
move(QApplication::desktop()->availableGeometry().center() - frameGeometry().center());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString windowTitle = tr(PACKAGE_NAME) + " - ";
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
enableWallet = WalletModel::isWalletEnabled();
|
enableWallet = WalletModel::isWalletEnabled();
|
||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
if(enableWallet)
|
QApplication::setWindowIcon(m_network_style->getTrayAndWindowIcon());
|
||||||
{
|
setWindowIcon(m_network_style->getTrayAndWindowIcon());
|
||||||
windowTitle += tr("Wallet");
|
updateWindowTitle();
|
||||||
} else {
|
|
||||||
windowTitle += tr("Node");
|
|
||||||
}
|
|
||||||
QString userWindowTitle = QString::fromStdString(gArgs.GetArg("-windowtitle", ""));
|
|
||||||
if(!userWindowTitle.isEmpty()) windowTitle += " - " + userWindowTitle;
|
|
||||||
windowTitle += " " + networkStyle->getTitleAddText();
|
|
||||||
QApplication::setWindowIcon(networkStyle->getTrayAndWindowIcon());
|
|
||||||
setWindowIcon(networkStyle->getTrayAndWindowIcon());
|
|
||||||
setWindowTitle(windowTitle);
|
|
||||||
|
|
||||||
rpcConsole = new RPCConsole(node, this, enableWallet ? Qt::Window : Qt::Widget);
|
rpcConsole = new RPCConsole(node, this, enableWallet ? Qt::Window : Qt::Widget);
|
||||||
helpMessageDialog = new HelpMessageDialog(node, this, HelpMessageDialog::cmdline);
|
helpMessageDialog = new HelpMessageDialog(node, this, HelpMessageDialog::cmdline);
|
||||||
@ -131,7 +122,7 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const NetworkStyle* networkStyle,
|
|||||||
|
|
||||||
// Create system tray icon and notification
|
// Create system tray icon and notification
|
||||||
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
if (QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||||
createTrayIcon(networkStyle);
|
createTrayIcon();
|
||||||
}
|
}
|
||||||
notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
|
notificator = new Notificator(QApplication::applicationName(), trayIcon, this);
|
||||||
|
|
||||||
@ -754,10 +745,9 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
bool BitcoinGUI::addWallet(WalletModel *walletModel)
|
void BitcoinGUI::addWallet(WalletModel* walletModel)
|
||||||
{
|
{
|
||||||
if(!walletFrame)
|
if (!walletFrame) return;
|
||||||
return false;
|
|
||||||
const QString display_name = walletModel->getDisplayName();
|
const QString display_name = walletModel->getDisplayName();
|
||||||
setWalletActionsEnabled(true);
|
setWalletActionsEnabled(true);
|
||||||
m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
|
m_wallet_selector->addItem(display_name, QVariant::fromValue(walletModel));
|
||||||
@ -765,12 +755,12 @@ bool BitcoinGUI::addWallet(WalletModel *walletModel)
|
|||||||
m_wallet_selector_action->setVisible(true);
|
m_wallet_selector_action->setVisible(true);
|
||||||
}
|
}
|
||||||
rpcConsole->addWallet(walletModel);
|
rpcConsole->addWallet(walletModel);
|
||||||
return walletFrame->addWallet(walletModel);
|
walletFrame->addWallet(walletModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitcoinGUI::removeWallet(WalletModel* walletModel)
|
void BitcoinGUI::removeWallet(WalletModel* walletModel)
|
||||||
{
|
{
|
||||||
if (!walletFrame) return false;
|
if (!walletFrame) return;
|
||||||
int index = m_wallet_selector->findData(QVariant::fromValue(walletModel));
|
int index = m_wallet_selector->findData(QVariant::fromValue(walletModel));
|
||||||
m_wallet_selector->removeItem(index);
|
m_wallet_selector->removeItem(index);
|
||||||
if (m_wallet_selector->count() == 0) {
|
if (m_wallet_selector->count() == 0) {
|
||||||
@ -779,20 +769,21 @@ bool BitcoinGUI::removeWallet(WalletModel* walletModel)
|
|||||||
m_wallet_selector_action->setVisible(false);
|
m_wallet_selector_action->setVisible(false);
|
||||||
}
|
}
|
||||||
rpcConsole->removeWallet(walletModel);
|
rpcConsole->removeWallet(walletModel);
|
||||||
return walletFrame->removeWallet(walletModel);
|
walletFrame->removeWallet(walletModel);
|
||||||
|
updateWindowTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
|
void BitcoinGUI::setCurrentWallet(WalletModel* wallet_model)
|
||||||
{
|
{
|
||||||
if(!walletFrame)
|
if (!walletFrame) return;
|
||||||
return false;
|
walletFrame->setCurrentWallet(wallet_model);
|
||||||
return walletFrame->setCurrentWallet(wallet_model);
|
updateWindowTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitcoinGUI::setCurrentWalletBySelectorIndex(int index)
|
void BitcoinGUI::setCurrentWalletBySelectorIndex(int index)
|
||||||
{
|
{
|
||||||
WalletModel* wallet_model = m_wallet_selector->itemData(index).value<WalletModel*>();
|
WalletModel* wallet_model = m_wallet_selector->itemData(index).value<WalletModel*>();
|
||||||
return setCurrentWallet(wallet_model);
|
setCurrentWallet(wallet_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcoinGUI::removeAllWallets()
|
void BitcoinGUI::removeAllWallets()
|
||||||
@ -836,12 +827,12 @@ void BitcoinGUI::setWalletActionsEnabled(bool enabled)
|
|||||||
openAction->setEnabled(enabled);
|
openAction->setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle)
|
void BitcoinGUI::createTrayIcon()
|
||||||
{
|
{
|
||||||
assert(QSystemTrayIcon::isSystemTrayAvailable());
|
assert(QSystemTrayIcon::isSystemTrayAvailable());
|
||||||
|
|
||||||
trayIcon = new QSystemTrayIcon(networkStyle->getTrayAndWindowIcon(), this);
|
trayIcon = new QSystemTrayIcon(m_network_style->getTrayAndWindowIcon(), this);
|
||||||
QString toolTip = tr("%1 client").arg(tr(PACKAGE_NAME)) + " " + networkStyle->getTitleAddText();
|
QString toolTip = tr("%1 client").arg(tr(PACKAGE_NAME)) + " " + m_network_style->getTitleAddText();
|
||||||
trayIcon->setToolTip(toolTip);
|
trayIcon->setToolTip(toolTip);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1710,6 +1701,27 @@ void BitcoinGUI::updateProxyIcon()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BitcoinGUI::updateWindowTitle()
|
||||||
|
{
|
||||||
|
QString window_title = tr(PACKAGE_NAME);
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
|
if (walletFrame) {
|
||||||
|
WalletModel* const wallet_model = walletFrame->currentWalletModel();
|
||||||
|
QString userWindowTitle = QString::fromStdString(gArgs.GetArg("-windowtitle", ""));
|
||||||
|
if (!userWindowTitle.isEmpty()) {
|
||||||
|
window_title += " - " + userWindowTitle;
|
||||||
|
}
|
||||||
|
if (wallet_model && !wallet_model->getWalletName().isEmpty()) {
|
||||||
|
window_title += " - " + wallet_model->getDisplayName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!m_network_style->getTitleAddText().isEmpty()) {
|
||||||
|
window_title += " - " + m_network_style->getTitleAddText();
|
||||||
|
}
|
||||||
|
setWindowTitle(window_title);
|
||||||
|
}
|
||||||
|
|
||||||
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
|
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
|
||||||
{
|
{
|
||||||
if(!clientModel)
|
if(!clientModel)
|
||||||
|
@ -80,8 +80,8 @@ public:
|
|||||||
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
|
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
|
||||||
functionality.
|
functionality.
|
||||||
*/
|
*/
|
||||||
bool addWallet(WalletModel *walletModel);
|
void addWallet(WalletModel* walletModel);
|
||||||
bool removeWallet(WalletModel* walletModel);
|
void removeWallet(WalletModel* walletModel);
|
||||||
void removeAllWallets();
|
void removeAllWallets();
|
||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
bool enableWallet = false;
|
bool enableWallet = false;
|
||||||
@ -197,6 +197,7 @@ private:
|
|||||||
|
|
||||||
/** Timer to update custom css styling in -debug-ui mode periodically */
|
/** Timer to update custom css styling in -debug-ui mode periodically */
|
||||||
QTimer* timerCustomCss = nullptr;
|
QTimer* timerCustomCss = nullptr;
|
||||||
|
const NetworkStyle* const m_network_style;
|
||||||
|
|
||||||
/** Create the main UI actions. */
|
/** Create the main UI actions. */
|
||||||
void createActions();
|
void createActions();
|
||||||
@ -205,7 +206,7 @@ private:
|
|||||||
/** Create the toolbars */
|
/** Create the toolbars */
|
||||||
void createToolBars();
|
void createToolBars();
|
||||||
/** Create system tray icon and notification */
|
/** Create system tray icon and notification */
|
||||||
void createTrayIcon(const NetworkStyle *networkStyle);
|
void createTrayIcon();
|
||||||
/** Create system tray menu (or setup the dock menu) */
|
/** Create system tray menu (or setup the dock menu) */
|
||||||
void createIconMenu(QMenu *pmenu);
|
void createIconMenu(QMenu *pmenu);
|
||||||
|
|
||||||
@ -252,8 +253,8 @@ public Q_SLOTS:
|
|||||||
void message(const QString &title, const QString &message, unsigned int style, bool *ret = nullptr);
|
void message(const QString &title, const QString &message, unsigned int style, bool *ret = nullptr);
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
bool setCurrentWallet(WalletModel* wallet_model);
|
void setCurrentWallet(WalletModel* wallet_model);
|
||||||
bool setCurrentWalletBySelectorIndex(int index);
|
void setCurrentWalletBySelectorIndex(int index);
|
||||||
/** Set the UI status indicators based on the currently selected wallet.
|
/** Set the UI status indicators based on the currently selected wallet.
|
||||||
*/
|
*/
|
||||||
void updateWalletStatus();
|
void updateWalletStatus();
|
||||||
@ -282,6 +283,7 @@ public Q_SLOTS:
|
|||||||
private:
|
private:
|
||||||
/** Set the proxy-enabled icon as shown in the UI. */
|
/** Set the proxy-enabled icon as shown in the UI. */
|
||||||
void updateProxyIcon();
|
void updateProxyIcon();
|
||||||
|
void updateWindowTitle();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
|
@ -247,11 +247,17 @@ void WalletFrame::usedReceivingAddresses()
|
|||||||
walletView->usedReceivingAddresses();
|
walletView->usedReceivingAddresses();
|
||||||
}
|
}
|
||||||
|
|
||||||
WalletView *WalletFrame::currentWalletView()
|
WalletView* WalletFrame::currentWalletView() const
|
||||||
{
|
{
|
||||||
return qobject_cast<WalletView*>(walletStack->currentWidget());
|
return qobject_cast<WalletView*>(walletStack->currentWidget());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WalletModel* WalletFrame::currentWalletModel() const
|
||||||
|
{
|
||||||
|
WalletView* wallet_view = currentWalletView();
|
||||||
|
return wallet_view ? wallet_view->getWalletModel() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void WalletFrame::outOfSyncWarningClicked()
|
void WalletFrame::outOfSyncWarningClicked()
|
||||||
{
|
{
|
||||||
Q_EMIT requestedSyncWarningInfo();
|
Q_EMIT requestedSyncWarningInfo();
|
||||||
|
@ -59,7 +59,8 @@ private:
|
|||||||
bool bOutOfSync;
|
bool bOutOfSync;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WalletView *currentWalletView();
|
WalletView* currentWalletView() const;
|
||||||
|
WalletModel* currentWalletModel() const;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
/** Switch to overview (home) page */
|
/** Switch to overview (home) page */
|
||||||
|
@ -402,8 +402,12 @@ void WalletInit::Stop() const
|
|||||||
|
|
||||||
void WalletInit::Close() const
|
void WalletInit::Close() const
|
||||||
{
|
{
|
||||||
for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
|
auto wallets = GetWallets();
|
||||||
RemoveWallet(pwallet);
|
while (!wallets.empty()) {
|
||||||
|
auto wallet = wallets.back();
|
||||||
|
wallets.pop_back();
|
||||||
|
RemoveWallet(wallet);
|
||||||
|
UnloadWallet(std::move(wallet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3487,16 +3487,8 @@ static UniValue unloadwallet(const JSONRPCRequest& request)
|
|||||||
if (!RemoveWallet(wallet)) {
|
if (!RemoveWallet(wallet)) {
|
||||||
throw JSONRPCError(RPC_MISC_ERROR, "Requested wallet already unloaded");
|
throw JSONRPCError(RPC_MISC_ERROR, "Requested wallet already unloaded");
|
||||||
}
|
}
|
||||||
UnregisterValidationInterface(wallet.get());
|
|
||||||
|
|
||||||
// The wallet can be in use so it's not possible to explicitly unload here.
|
UnloadWallet(std::move(wallet));
|
||||||
// Just notify the unload intent so that all shared pointers are released.
|
|
||||||
// The wallet will be destroyed once the last shared pointer is released.
|
|
||||||
wallet->NotifyUnload();
|
|
||||||
|
|
||||||
// There's no point in waiting for the wallet to unload.
|
|
||||||
// At this point this method should never fail. The unloading could only
|
|
||||||
// fail due to an unexpected error which would cause a process termination.
|
|
||||||
|
|
||||||
return NullUniValue;
|
return NullUniValue;
|
||||||
}
|
}
|
||||||
|
@ -98,14 +98,52 @@ std::shared_ptr<CWallet> GetWallet(const std::string& name)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Mutex g_wallet_release_mutex;
|
||||||
|
static std::condition_variable g_wallet_release_cv;
|
||||||
|
static std::set<CWallet*> g_unloading_wallet_set;
|
||||||
|
|
||||||
// Custom deleter for shared_ptr<CWallet>.
|
// Custom deleter for shared_ptr<CWallet>.
|
||||||
static void ReleaseWallet(CWallet* wallet)
|
static void ReleaseWallet(CWallet* wallet)
|
||||||
{
|
{
|
||||||
|
// Unregister and delete the wallet right after BlockUntilSyncedToCurrentChain
|
||||||
|
// so that it's in sync with the current chainstate.
|
||||||
wallet->WalletLogPrintf("Releasing wallet\n");
|
wallet->WalletLogPrintf("Releasing wallet\n");
|
||||||
wallet->BlockUntilSyncedToCurrentChain();
|
wallet->BlockUntilSyncedToCurrentChain();
|
||||||
wallet->Flush();
|
wallet->Flush();
|
||||||
|
UnregisterValidationInterface(wallet);
|
||||||
delete wallet;
|
delete wallet;
|
||||||
|
// Wallet is now released, notify UnloadWallet, if any.
|
||||||
|
{
|
||||||
|
LOCK(g_wallet_release_mutex);
|
||||||
|
if (g_unloading_wallet_set.erase(wallet) == 0) {
|
||||||
|
// UnloadWallet was not called for this wallet, all done.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_wallet_release_cv.notify_all();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnloadWallet(std::shared_ptr<CWallet>&& wallet)
|
||||||
|
{
|
||||||
|
// Mark wallet for unloading.
|
||||||
|
CWallet* pwallet = wallet.get();
|
||||||
|
{
|
||||||
|
LOCK(g_wallet_release_mutex);
|
||||||
|
auto it = g_unloading_wallet_set.insert(pwallet);
|
||||||
|
assert(it.second);
|
||||||
|
}
|
||||||
|
// The wallet can be in use so it's not possible to explicitly unload here.
|
||||||
|
// Notify the unload intent so that all remaining shared pointers are
|
||||||
|
// released.
|
||||||
|
pwallet->NotifyUnload();
|
||||||
|
// Time to ditch our shared_ptr and wait for ReleaseWallet call.
|
||||||
|
wallet.reset();
|
||||||
|
{
|
||||||
|
WAIT_LOCK(g_wallet_release_mutex, lock);
|
||||||
|
while (g_unloading_wallet_set.count(pwallet) == 1) {
|
||||||
|
g_wallet_release_cv.wait(lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
||||||
|
@ -37,6 +37,13 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
//! Explicitly unload and delete the wallet.
|
||||||
|
// Blocks the current thread after signaling the unload intent so that all
|
||||||
|
// wallet clients release the wallet.
|
||||||
|
// Note that, when blocking is not required, the wallet is implicitly unloaded
|
||||||
|
// by the shared pointer deleter.
|
||||||
|
void UnloadWallet(std::shared_ptr<CWallet>&& wallet);
|
||||||
|
|
||||||
bool AddWallet(const std::shared_ptr<CWallet>& wallet);
|
bool AddWallet(const std::shared_ptr<CWallet>& wallet);
|
||||||
bool RemoveWallet(const std::shared_ptr<CWallet>& wallet);
|
bool RemoveWallet(const std::shared_ptr<CWallet>& wallet);
|
||||||
bool HasWallets();
|
bool HasWallets();
|
||||||
@ -891,6 +898,8 @@ public:
|
|||||||
|
|
||||||
~CWallet()
|
~CWallet()
|
||||||
{
|
{
|
||||||
|
// Should not have slots connected at this point.
|
||||||
|
assert(NotifyUnload.empty());
|
||||||
delete encrypted_batch;
|
delete encrypted_batch;
|
||||||
encrypted_batch = nullptr;
|
encrypted_batch = nullptr;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user