Skip to content

Commit

Permalink
Refactor IS-lock GUI notification and implement a similar one for Cha…
Browse files Browse the repository at this point in the history
…inLocks (#2875)

* Refactor IS-lock GUI notification and implement a similar one for ChainLocks

* Initialize cachedNumISLocks in TransactionStatus ctor
  • Loading branch information
UdjinM6 authored Apr 25, 2019
1 parent ed30db7 commit 5cfceab
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 29 deletions.
3 changes: 0 additions & 3 deletions src/instantx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ extern CWallet* pwalletMain;
extern CTxMemPool mempool;

bool fEnableInstantSend = true;
int nCompleteTXLocks;

std::atomic<bool> CInstantSend::isAutoLockBip9Active{false};
const double CInstantSend::AUTO_IX_MEMPOOL_THRESHOLD = 0.1;
Expand Down Expand Up @@ -531,8 +530,6 @@ void CInstantSend::UpdateLockedTransaction(const CTxLockCandidate& txLockCandida

#ifdef ENABLE_WALLET
if (pwalletMain && pwalletMain->UpdatedTransaction(txHash)) {
// bumping this to update UI
nCompleteTXLocks++;
// notify an external script once threshold is reached
std::string strCmd = GetArg("-instantsendnotify", "");
if (!strCmd.empty()) {
Expand Down
1 change: 0 additions & 1 deletion src/instantx.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ static const int INSTANTSEND_LOCK_TIMEOUT_SECONDS = 15;
static const int INSTANTSEND_FAILED_TIMEOUT_SECONDS = 60;

extern bool fEnableInstantSend;
extern int nCompleteTXLocks;

/**
* Manages InstantSend. Processes lock requests, candidates, and votes.
Expand Down
4 changes: 1 addition & 3 deletions src/llmq/quorums_instantsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include "wallet/wallet.h"
#endif

// needed for nCompleteTXLocks
// needed for AUTO_IX_MEMPOOL_THRESHOLD
#include "instantx.h"

#include <boost/algorithm/string/replace.hpp>
Expand Down Expand Up @@ -831,8 +831,6 @@ void CInstantSendManager::UpdateWalletTransaction(const uint256& txid, const CTr
}

if (pwalletMain->UpdatedTransaction(txid)) {
// bumping this to update UI
nCompleteTXLocks++;
// notify an external script once threshold is reached
std::string strCmd = GetArg("-instantsendnotify", "");
if (!strCmd.empty()) {
Expand Down
12 changes: 7 additions & 5 deletions src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ OverviewPage::OverviewPage(const PlatformStyle *platformStyle, QWidget *parent)
currentWatchOnlyBalance(-1),
currentWatchUnconfBalance(-1),
currentWatchImmatureBalance(-1),
cachedNumISLocks(-1),
txdelegate(new TxViewDelegate(platformStyle, this))
{
ui->setupUi(this);
Expand Down Expand Up @@ -230,11 +231,12 @@ void OverviewPage::setBalance(const CAmount& balance, const CAmount& unconfirmed

updatePrivateSendProgress();

static int cachedTxLocks = 0;

if(cachedTxLocks != nCompleteTXLocks){
cachedTxLocks = nCompleteTXLocks;
ui->listTransactions->update();
if (walletModel) {
int numISLocks = walletModel->getNumISLocks();
if(cachedNumISLocks != numISLocks) {
cachedNumISLocks = numISLocks;
ui->listTransactions->update();
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/qt/overviewpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public Q_SLOTS:
CAmount currentWatchImmatureBalance;
int nDisplayUnit;
bool fShowAdvancedPSUI;
int cachedNumISLocks;

TxViewDelegate *txdelegate;
std::unique_ptr<TransactionFilterProxy> filter;
Expand Down
12 changes: 7 additions & 5 deletions src/qt/transactionrecord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include "timedata.h"
#include "wallet/wallet.h"

#include "instantx.h"
#include "privatesend.h"

#include <stdint.h>
Expand Down Expand Up @@ -252,7 +251,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
return parts;
}

void TransactionRecord::updateStatus(const CWalletTx &wtx)
void TransactionRecord::updateStatus(const CWalletTx &wtx, int numISLocks, int chainLockHeight)
{
AssertLockHeld(cs_main);
// Determine transaction status
Expand All @@ -272,7 +271,8 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)
status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0);
status.depth = wtx.GetDepthInMainChain();
status.cur_num_blocks = chainActive.Height();
status.cur_num_ix_locks = nCompleteTXLocks;
status.cachedNumISLocks = numISLocks;
status.cachedChainLockHeight = chainLockHeight;

if (!CheckFinalTx(wtx))
{
Expand Down Expand Up @@ -341,10 +341,12 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)

}

bool TransactionRecord::statusUpdateNeeded()
bool TransactionRecord::statusUpdateNeeded(int numISLocks, int chainLockHeight)
{
AssertLockHeld(cs_main);
return status.cur_num_blocks != chainActive.Height() || status.cur_num_ix_locks != nCompleteTXLocks;
return status.cur_num_blocks != chainActive.Height()
|| status.cachedNumISLocks != numISLocks
|| status.cachedChainLockHeight != chainLockHeight;
}

QString TransactionRecord::getTxID() const
Expand Down
13 changes: 8 additions & 5 deletions src/qt/transactionrecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class TransactionStatus
public:
TransactionStatus():
countsForBalance(false), lockedByInstantSend(false), sortKey(""),
matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1)
matures_in(0), status(Offline), depth(0), open_for(0), cur_num_blocks(-1),
cachedNumISLocks(-1), cachedChainLockHeight(-1)
{ }

enum Status {
Expand Down Expand Up @@ -64,8 +65,10 @@ class TransactionStatus
/** Current number of blocks (to know whether cached status is still valid) */
int cur_num_blocks;

//** Know when to update transaction for ix locks **/
int cur_num_ix_locks;
//** Know when to update transaction for IS-locks **/
int cachedNumISLocks;
//** Know when to update transaction for chainlocks **/
int cachedChainLockHeight;
};

/** UI model for a transaction. A core transaction can be represented by multiple UI transactions if it has
Expand Down Expand Up @@ -145,11 +148,11 @@ class TransactionRecord

/** Update status from core wallet tx.
*/
void updateStatus(const CWalletTx &wtx);
void updateStatus(const CWalletTx &wtx, int numISLocks, int chainLockHeight);

/** Return whether a status update is needed.
*/
bool statusUpdateNeeded();
bool statusUpdateNeeded(int numISLocks, int chainLockHeight);
};

#endif // BITCOIN_QT_TRANSACTIONRECORD_H
25 changes: 23 additions & 2 deletions src/qt/transactiontablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,13 @@ class TransactionTablePriv
if(lockMain)
{
TRY_LOCK(wallet->cs_wallet, lockWallet);
if(lockWallet && rec->statusUpdateNeeded())
if(lockWallet && (rec->statusUpdateNeeded(parent->getNumISLocks(), parent->getChainLockHeight())))
{
std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);

if(mi != wallet->mapWallet.end())
{
rec->updateStatus(mi->second);
rec->updateStatus(mi->second, parent->getNumISLocks(), parent->getChainLockHeight());
}
}
}
Expand Down Expand Up @@ -283,6 +283,27 @@ void TransactionTableModel::updateConfirmations()
Q_EMIT dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress));
}

void TransactionTableModel::updateNumISLocks(int numISLocks)
{
cachedNumISLocks = numISLocks;
}

void TransactionTableModel::updateChainLockHeight(int chainLockHeight)
{
cachedChainLockHeight = chainLockHeight;
updateConfirmations();
}

int TransactionTableModel::getNumISLocks() const
{
return cachedNumISLocks;
}

int TransactionTableModel::getChainLockHeight() const
{
return cachedChainLockHeight;
}

int TransactionTableModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
Expand Down
6 changes: 6 additions & 0 deletions src/qt/transactiontablemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ class TransactionTableModel : public QAbstractTableModel
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
bool processingQueuedTransactions() { return fProcessingQueuedTransactions; }
void updateNumISLocks(int numISLocks);
void updateChainLockHeight(int chainLockHeight);
int getNumISLocks() const;
int getChainLockHeight() const;

private:
CWallet* wallet;
Expand All @@ -93,6 +97,8 @@ class TransactionTableModel : public QAbstractTableModel
TransactionTablePriv *priv;
bool fProcessingQueuedTransactions;
const PlatformStyle *platformStyle;
int cachedNumISLocks;
int cachedChainLockHeight;

void subscribeToCoreSignals();
void unsubscribeFromCoreSignals();
Expand Down
41 changes: 37 additions & 4 deletions src/qt/walletmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ WalletModel::WalletModel(const PlatformStyle *platformStyle, CWallet *_wallet, O
cachedWatchImmatureBalance(0),
cachedEncryptionStatus(Unencrypted),
cachedNumBlocks(0),
cachedTxLocks(0),
cachedNumISLocks(0),
cachedPrivateSendRounds(0)
{
fHaveWatchOnly = wallet->HaveWatchOnly();
Expand Down Expand Up @@ -145,7 +145,7 @@ void WalletModel::pollBalanceChanged()
if(!lockWallet)
return;

if(fForceCheckBalanceChanged || chainActive.Height() != cachedNumBlocks || privateSendClient.nPrivateSendRounds != cachedPrivateSendRounds || cachedTxLocks != nCompleteTXLocks)
if(fForceCheckBalanceChanged || chainActive.Height() != cachedNumBlocks || privateSendClient.nPrivateSendRounds != cachedPrivateSendRounds)
{
fForceCheckBalanceChanged = false;

Expand Down Expand Up @@ -176,14 +176,13 @@ void WalletModel::checkBalanceChanged()
}

if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance ||
cachedAnonymizedBalance != newAnonymizedBalance || cachedTxLocks != nCompleteTXLocks ||
cachedAnonymizedBalance != newAnonymizedBalance ||
cachedWatchOnlyBalance != newWatchOnlyBalance || cachedWatchUnconfBalance != newWatchUnconfBalance || cachedWatchImmatureBalance != newWatchImmatureBalance)
{
cachedBalance = newBalance;
cachedUnconfirmedBalance = newUnconfirmedBalance;
cachedImmatureBalance = newImmatureBalance;
cachedAnonymizedBalance = newAnonymizedBalance;
cachedTxLocks = nCompleteTXLocks;
cachedWatchOnlyBalance = newWatchOnlyBalance;
cachedWatchUnconfBalance = newWatchUnconfBalance;
cachedWatchImmatureBalance = newWatchImmatureBalance;
Expand All @@ -198,6 +197,25 @@ void WalletModel::updateTransaction()
fForceCheckBalanceChanged = true;
}

void WalletModel::updateNumISLocks()
{
fForceCheckBalanceChanged = true;
cachedNumISLocks++;
if (transactionTableModel)
transactionTableModel->updateNumISLocks(cachedNumISLocks);
}

void WalletModel::updateChainLockHeight(int chainLockHeight)
{
if (transactionTableModel)
transactionTableModel->updateChainLockHeight(chainLockHeight);
}

int WalletModel::getNumISLocks() const
{
return cachedNumISLocks;
}

void WalletModel::updateAddressBook(const QString &address, const QString &label,
bool isMine, const QString &purpose, int status)
{
Expand Down Expand Up @@ -552,6 +570,17 @@ static void NotifyTransactionChanged(WalletModel *walletmodel, CWallet *wallet,
QMetaObject::invokeMethod(walletmodel, "updateTransaction", Qt::QueuedConnection);
}

static void NotifyISLockReceived(WalletModel *walletmodel)
{
QMetaObject::invokeMethod(walletmodel, "updateNumISLocks", Qt::QueuedConnection);
}

static void NotifyChainLockReceived(WalletModel *walletmodel, int chainLockHeight)
{
QMetaObject::invokeMethod(walletmodel, "updateChainLockHeight", Qt::QueuedConnection,
Q_ARG(int, chainLockHeight));
}

static void ShowProgress(WalletModel *walletmodel, const std::string &title, int nProgress)
{
// emits signal "showProgress"
Expand All @@ -572,6 +601,8 @@ void WalletModel::subscribeToCoreSignals()
wallet->NotifyStatusChanged.connect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
wallet->NotifyAddressBookChanged.connect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
wallet->NotifyTransactionChanged.connect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
wallet->NotifyISLockReceived.connect(boost::bind(NotifyISLockReceived, this));
wallet->NotifyChainLockReceived.connect(boost::bind(NotifyChainLockReceived, this, _1));
wallet->ShowProgress.connect(boost::bind(ShowProgress, this, _1, _2));
wallet->NotifyWatchonlyChanged.connect(boost::bind(NotifyWatchonlyChanged, this, _1));
}
Expand All @@ -582,6 +613,8 @@ void WalletModel::unsubscribeFromCoreSignals()
wallet->NotifyStatusChanged.disconnect(boost::bind(&NotifyKeyStoreStatusChanged, this, _1));
wallet->NotifyAddressBookChanged.disconnect(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5, _6));
wallet->NotifyTransactionChanged.disconnect(boost::bind(NotifyTransactionChanged, this, _1, _2, _3));
wallet->NotifyISLockReceived.disconnect(boost::bind(NotifyISLockReceived, this));
wallet->NotifyChainLockReceived.disconnect(boost::bind(NotifyChainLockReceived, this, _1));
wallet->ShowProgress.disconnect(boost::bind(ShowProgress, this, _1, _2));
wallet->NotifyWatchonlyChanged.disconnect(boost::bind(NotifyWatchonlyChanged, this, _1));
}
Expand Down
7 changes: 6 additions & 1 deletion src/qt/walletmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ class WalletModel : public QObject
bool hdEnabled() const;

int getDefaultConfirmTarget() const;
int getNumISLocks() const;

private:
CWallet *wallet;
Expand All @@ -250,7 +251,7 @@ class WalletModel : public QObject
CAmount cachedWatchImmatureBalance;
EncryptionStatus cachedEncryptionStatus;
int cachedNumBlocks;
int cachedTxLocks;
int cachedNumISLocks;
int cachedPrivateSendRounds;

QTimer *pollTimer;
Expand Down Expand Up @@ -289,6 +290,10 @@ public Q_SLOTS:
void updateStatus();
/* New transaction, or transaction changed status */
void updateTransaction();
/* IS-Lock received */
void updateNumISLocks();
/* ChainLock received */
void updateChainLockHeight(int chainLockHeight);
/* New, updated or removed address book entry */
void updateAddressBook(const QString &address, const QString &label, bool isMine, const QString &purpose, int status);
/* Watch-only added */
Expand Down
15 changes: 15 additions & 0 deletions src/wallet/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5333,6 +5333,21 @@ bool AutoBackupWallet(CWallet* wallet, const std::string& strWalletFile_, std::s
return true;
}

void CWallet::NotifyTransactionLock(const CTransaction &tx)
{
LOCK(cs_wallet);
// Only notify UI if this transaction is in this wallet
std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(tx.GetHash());
if (mi != mapWallet.end()){
NotifyISLockReceived();
}
}

void CWallet::NotifyChainLock(const CBlockIndex* pindexChainLock)
{
NotifyChainLockReceived(pindexChainLock->nHeight);
}

CKeyPool::CKeyPool()
{
nTime = GetTime();
Expand Down
9 changes: 9 additions & 0 deletions src/wallet/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,12 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
/** Watch-only address added */
boost::signals2::signal<void (bool fHaveWatchOnly)> NotifyWatchonlyChanged;

/** IS-lock received */
boost::signals2::signal<void ()> NotifyISLockReceived;

/** ChainLock received */
boost::signals2::signal<void (int height)> NotifyChainLockReceived;

/** Inquire whether this wallet broadcasts transactions. */
bool GetBroadcastTransactions() const { return fBroadcastTransactions; }
/** Set whether this wallet broadcasts transactions. */
Expand Down Expand Up @@ -1165,6 +1171,9 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
bool SetHDChain(const CHDChain& chain, bool memonly);
bool SetCryptedHDChain(const CHDChain& chain, bool memonly);
bool GetDecryptedHDChain(CHDChain& hdChainRet);

void NotifyTransactionLock(const CTransaction &tx) override;
void NotifyChainLock(const CBlockIndex* pindexChainLock) override;
};

/** A key allocated from the key pool. */
Expand Down

0 comments on commit 5cfceab

Please sign in to comment.