Skip to content

Commit

Permalink
GUI: Remove cs_main lock from balance polling timer
Browse files Browse the repository at this point in the history
And avoid recomputing wallet balances and txes status unless a tx changed or a block tip notification was received.
  • Loading branch information
furszy committed Mar 10, 2021
1 parent 5e06330 commit 3dede64
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 9 deletions.
15 changes: 15 additions & 0 deletions src/qt/clientmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,21 @@ QString ClientModel::getLastBlockHash() const
return QString::fromStdString(nHash.GetHex());
}

uint256 ClientModel::getLastBlockProcessed() const
{
return cacheTip == nullptr ? Params().GenesisBlock().GetHash() : cacheTip->GetBlockHash();
}

int ClientModel::getLastBlockProcessedHeight() const
{
return cacheTip == nullptr ? 0 : cacheTip->nHeight;
}

int64_t ClientModel::getLastBlockProcessedTime() const
{
return cacheTip == nullptr ? Params().GenesisBlock().GetBlockTime() : cacheTip->GetBlockTime();
}

double ClientModel::getVerificationProgress() const
{
return Checkpoints::GuessVerificationProgress(cacheTip);
Expand Down
3 changes: 3 additions & 0 deletions src/qt/clientmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class ClientModel : public QObject
int getNumBlocks();
QDateTime getLastBlockDate() const;
QString getLastBlockHash() const;
uint256 getLastBlockProcessed() const;
int getLastBlockProcessedHeight() const;
int64_t getLastBlockProcessedTime() const;
double getVerificationProgress() const;

quint64 getTotalBytesRecv() const;
Expand Down
1 change: 1 addition & 0 deletions src/qt/pivx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,7 @@ void BitcoinApplication::initializeResult(int retval)
#ifdef ENABLE_WALLET
if (pwalletMain) {
walletModel = new WalletModel(pwalletMain, optionsModel);
walletModel->setClientModel(clientModel);

window->addWallet(PIVXGUI::DEFAULT_WALLET, walletModel);
window->setCurrentWallet(PIVXGUI::DEFAULT_WALLET);
Expand Down
39 changes: 30 additions & 9 deletions src/qt/walletmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "walletmodel.h"

#include "addresstablemodel.h"
#include "qt/clientmodel.h"
#include "guiconstants.h"
#include "optionsmodel.h"
#include "recentrequeststablemodel.h"
Expand Down Expand Up @@ -208,29 +209,33 @@ void WalletModel::pollBalanceChanged()
waitLonger = 0;
}

// Avoid recomputing wallet balances unless a tx changed or
// BlockTip notification was received.
if (!fForceCheckBalanceChanged && m_cached_best_block_hash == getLastBlockProcessed()) return;

// Get required locks upfront. This avoids the GUI from getting stuck on
// periodical polls if the core is holding the locks for a longer time -
// for example, during a wallet rescan.
TRY_LOCK(cs_main, lockMain);
if (!lockMain)
return;
TRY_LOCK(wallet->cs_wallet, lockWallet);
if (!lockWallet)
return;
int chainHeight = m_client_model->getLastBlockProcessedHeight();
const uint256& blockHash = m_client_model->getLastBlockProcessed();
int64_t blockTime = m_client_model->getLastBlockProcessedTime();

// Don't continue processing if the chain tip time is less than the first
// key creation time as there is no need to iterate over the transaction
// table model in this case.
auto tip = chainActive.Tip();
if (tip->GetBlockTime() < getCreationTime())
if (blockTime < getCreationTime())
return;

TRY_LOCK(wallet->cs_wallet, lockWallet);
if (!lockWallet)
return;

int chainHeight = tip->nHeight;
if (fForceCheckBalanceChanged || chainHeight != cachedNumBlocks) {
fForceCheckBalanceChanged = false;

// Balance and number of transactions might have changed
cachedNumBlocks = chainHeight;
m_cached_best_block_hash = blockHash;

checkBalanceChanged(walletWrapper.getBalances());
if (transactionTableModel) {
Expand Down Expand Up @@ -1093,3 +1098,19 @@ Optional<QString> WalletModel::getShieldedAddressFromSpendDesc(const uint256& tx
Optional<libzcash::SaplingPaymentAddress> opAddr = wallet->GetSaplingScriptPubKeyMan()->GetAddressFromInputIfPossible(txHash, index);
return opAddr ? Optional<QString>(QString::fromStdString(KeyIO::EncodePaymentAddress(*opAddr))) : nullopt;
}

void WalletModel::setClientModel(ClientModel* client_model)
{
m_client_model = client_model;
}

uint256 WalletModel::getLastBlockProcessed() const
{
return m_client_model ? m_client_model->getLastBlockProcessed() : UINT256_ZERO;
}

int WalletModel::getLastBlockProcessedNum() const
{
return m_client_model ? m_client_model->getLastBlockProcessedHeight() : 0;
}

9 changes: 9 additions & 0 deletions src/qt/walletmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <QObject>

class AddressTableModel;
class ClientModel;
class OptionsModel;
class RecentRequestsTableModel;
class TransactionTableModel;
Expand Down Expand Up @@ -327,6 +328,12 @@ class WalletModel : public QObject
void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
bool saveReceiveRequest(const std::string& sAddress, const int64_t nId, const std::string& sRequest);

ClientModel& clientModel() const { return *m_client_model; }
void setClientModel(ClientModel* client_model);

uint256 getLastBlockProcessed() const;
int getLastBlockProcessedNum() const;

private:
CWallet* wallet;
// Simple Wallet interface.
Expand All @@ -341,6 +348,7 @@ class WalletModel : public QObject
std::unique_ptr<interfaces::Handler> m_handler_show_progress;
std::unique_ptr<interfaces::Handler> m_handler_notify_watch_only_changed;
std::unique_ptr<interfaces::Handler> m_handler_notify_walletbacked;
ClientModel* m_client_model;

bool fHaveWatchOnly;
bool fForceCheckBalanceChanged;
Expand All @@ -358,6 +366,7 @@ class WalletModel : public QObject

EncryptionStatus cachedEncryptionStatus;
int cachedNumBlocks;
uint256 m_cached_best_block_hash;

QTimer* pollTimer;

Expand Down

0 comments on commit 3dede64

Please sign in to comment.