Added 'immature balance' for miners. Only displayed if the balance is greater than zero.

This adds a field labelled 'Immature' in the overview section under the 'unconfirmed' field, which shows mined
income that has not yet matured (which is currently not displayed anywhere, even though the transactions
exist in the transaction list). To do that I added a 'GetImmatureBalance' method to the wallet, and connected
that through to the GUI as per the 'GetBalance' and 'GetUnconfirmedBalance' methods. I did a small 'no-op'
change to make the code in adjacent functions a little more readable (imo); it was a change I had made in my
repo earlier...but I thought it wouldn't hurt so left it in. Immature balance comes from mined income that is
at least two blocks deep in the chain (same logic as displayed transactions).

My reasoning is:
- as a miner, it's a critical stat I want to see
- as a miner, and taking into account the label 'immature', the uncertainty is pretty clearly implied
- those numbers are already displayed in the transaction list
- this makes the overview numbers add up to what's in the transaction list
- it's not displayed if the immature balance is 0, so won't bother non-miners

I also 'cleaned' the overview UI a little, moving code to the XML and removing HTML.
This commit is contained in:
sje397 2012-02-14 22:08:00 +11:00
parent 6b8a17119e
commit 8fdb7e108f
9 changed files with 87 additions and 24 deletions

View File

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>552</width> <width>573</width>
<height>342</height> <height>342</height>
</rect> </rect>
</property> </property>
@ -141,14 +141,14 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="text"> <property name="text">
<string>Number of transactions:</string> <string>Number of transactions:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QLabel" name="labelNumTransactions"> <widget class="QLabel" name="labelNumTransactions">
<property name="toolTip"> <property name="toolTip">
<string>Total number of transactions in wallet</string> <string>Total number of transactions in wallet</string>
@ -158,6 +158,32 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QLabel" name="labelImmatureText">
<property name="text">
<string>Immature:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="labelImmature">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="toolTip">
<string>Mined balance that has not yet matured</string>
</property>
<property name="text">
<string notr="true">0 BTC</string>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>

View File

@ -94,7 +94,9 @@ OverviewPage::OverviewPage(QWidget *parent) :
ui(new Ui::OverviewPage), ui(new Ui::OverviewPage),
currentBalance(-1), currentBalance(-1),
currentUnconfirmedBalance(-1), currentUnconfirmedBalance(-1),
txdelegate(new TxViewDelegate()), filter(0) currentImmatureBalance(-1),
txdelegate(new TxViewDelegate()),
filter(0)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -125,13 +127,21 @@ OverviewPage::~OverviewPage()
delete ui; delete ui;
} }
void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance) void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
{ {
int unit = model->getOptionsModel()->getDisplayUnit(); int unit = model->getOptionsModel()->getDisplayUnit();
currentBalance = balance; currentBalance = balance;
currentUnconfirmedBalance = unconfirmedBalance; currentUnconfirmedBalance = unconfirmedBalance;
currentImmatureBalance = immatureBalance;
ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance)); ui->labelBalance->setText(BitcoinUnits::formatWithUnit(unit, balance));
ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance)); ui->labelUnconfirmed->setText(BitcoinUnits::formatWithUnit(unit, unconfirmedBalance));
ui->labelImmature->setText(BitcoinUnits::formatWithUnit(unit, immatureBalance));
// only show immature (newly mined) balance if it's non-zero, so as not to complicate things
// for the non-mining users
bool showImmature = immatureBalance != 0;
ui->labelImmature->setVisible(showImmature);
ui->labelImmatureText->setVisible(showImmature);
} }
void OverviewPage::setNumTransactions(int count) void OverviewPage::setNumTransactions(int count)
@ -156,8 +166,8 @@ void OverviewPage::setModel(WalletModel *model)
ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);
// Keep up to date with wallet // Keep up to date with wallet
setBalance(model->getBalance(), model->getUnconfirmedBalance()); setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
connect(model, SIGNAL(balanceChanged(qint64, qint64)), this, SLOT(setBalance(qint64, qint64))); connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
setNumTransactions(model->getNumTransactions()); setNumTransactions(model->getNumTransactions());
connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int))); connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int)));
@ -171,7 +181,7 @@ void OverviewPage::displayUnitChanged()
if(!model || !model->getOptionsModel()) if(!model || !model->getOptionsModel())
return; return;
if(currentBalance != -1) if(currentBalance != -1)
setBalance(currentBalance, currentUnconfirmedBalance); setBalance(currentBalance, currentUnconfirmedBalance, currentImmatureBalance);
txdelegate->unit = model->getOptionsModel()->getDisplayUnit(); txdelegate->unit = model->getOptionsModel()->getDisplayUnit();
ui->listTransactions->update(); ui->listTransactions->update();

View File

@ -27,7 +27,7 @@ public:
void showOutOfSyncWarning(bool fShow); void showOutOfSyncWarning(bool fShow);
public slots: public slots:
void setBalance(qint64 balance, qint64 unconfirmedBalance); void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
void setNumTransactions(int count); void setNumTransactions(int count);
signals: signals:
@ -38,6 +38,7 @@ private:
WalletModel *model; WalletModel *model;
qint64 currentBalance; qint64 currentBalance;
qint64 currentUnconfirmedBalance; qint64 currentUnconfirmedBalance;
qint64 currentImmatureBalance;
TxViewDelegate *txdelegate; TxViewDelegate *txdelegate;
TransactionFilterProxy *filter; TransactionFilterProxy *filter;

View File

@ -48,8 +48,8 @@ void SendCoinsDialog::setModel(WalletModel *model)
} }
if(model) if(model)
{ {
setBalance(model->getBalance(), model->getUnconfirmedBalance()); setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
connect(model, SIGNAL(balanceChanged(qint64, qint64)), this, SLOT(setBalance(qint64, qint64))); connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
} }
} }
@ -277,9 +277,10 @@ void SendCoinsDialog::handleURI(const QString &uri)
pasteEntry(rv); pasteEntry(rv);
} }
void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance) void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
{ {
Q_UNUSED(unconfirmedBalance); Q_UNUSED(unconfirmedBalance);
Q_UNUSED(immatureBalance);
if(!model || !model->getOptionsModel()) if(!model || !model->getOptionsModel())
return; return;

View File

@ -38,7 +38,7 @@ public slots:
void accept(); void accept();
SendCoinsEntry *addEntry(); SendCoinsEntry *addEntry();
void updateRemoveEnabled(); void updateRemoveEnabled();
void setBalance(qint64 balance, qint64 unconfirmedBalance); void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
private: private:
Ui::SendCoinsDialog *ui; Ui::SendCoinsDialog *ui;

View File

@ -13,7 +13,8 @@
WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) : WalletModel::WalletModel(CWallet *wallet, OptionsModel *optionsModel, QObject *parent) :
QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0),
transactionTableModel(0), transactionTableModel(0),
cachedBalance(0), cachedUnconfirmedBalance(0), cachedNumTransactions(0), cachedBalance(0), cachedUnconfirmedBalance(0), cachedImmatureBalance(0),
cachedNumTransactions(0),
cachedEncryptionStatus(Unencrypted) cachedEncryptionStatus(Unencrypted)
{ {
addressTableModel = new AddressTableModel(wallet, this); addressTableModel = new AddressTableModel(wallet, this);
@ -37,6 +38,11 @@ qint64 WalletModel::getUnconfirmedBalance() const
return wallet->GetUnconfirmedBalance(); return wallet->GetUnconfirmedBalance();
} }
qint64 WalletModel::getImmatureBalance() const
{
return wallet->GetImmatureBalance();
}
int WalletModel::getNumTransactions() const int WalletModel::getNumTransactions() const
{ {
int numTransactions = 0; int numTransactions = 0;
@ -63,15 +69,18 @@ void WalletModel::updateTransaction(const QString &hash, int status)
// Balance and number of transactions might have changed // Balance and number of transactions might have changed
qint64 newBalance = getBalance(); qint64 newBalance = getBalance();
qint64 newUnconfirmedBalance = getUnconfirmedBalance(); qint64 newUnconfirmedBalance = getUnconfirmedBalance();
qint64 newImmatureBalance = getImmatureBalance();
int newNumTransactions = getNumTransactions(); int newNumTransactions = getNumTransactions();
if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance) if(cachedBalance != newBalance || cachedUnconfirmedBalance != newUnconfirmedBalance || cachedImmatureBalance != newImmatureBalance)
emit balanceChanged(newBalance, newUnconfirmedBalance); emit balanceChanged(newBalance, newUnconfirmedBalance, newImmatureBalance);
if(cachedNumTransactions != newNumTransactions) if(cachedNumTransactions != newNumTransactions)
emit numTransactionsChanged(newNumTransactions); emit numTransactionsChanged(newNumTransactions);
cachedBalance = newBalance; cachedBalance = newBalance;
cachedUnconfirmedBalance = newUnconfirmedBalance; cachedUnconfirmedBalance = newUnconfirmedBalance;
cachedImmatureBalance = newImmatureBalance;
cachedNumTransactions = newNumTransactions; cachedNumTransactions = newNumTransactions;
} }

View File

@ -52,6 +52,7 @@ public:
qint64 getBalance() const; qint64 getBalance() const;
qint64 getUnconfirmedBalance() const; qint64 getUnconfirmedBalance() const;
qint64 getImmatureBalance() const;
int getNumTransactions() const; int getNumTransactions() const;
EncryptionStatus getEncryptionStatus() const; EncryptionStatus getEncryptionStatus() const;
@ -116,6 +117,7 @@ private:
// Cache some values to be able to detect changes // Cache some values to be able to detect changes
qint64 cachedBalance; qint64 cachedBalance;
qint64 cachedUnconfirmedBalance; qint64 cachedUnconfirmedBalance;
qint64 cachedImmatureBalance;
qint64 cachedNumTransactions; qint64 cachedNumTransactions;
EncryptionStatus cachedEncryptionStatus; EncryptionStatus cachedEncryptionStatus;
@ -123,7 +125,7 @@ private:
void unsubscribeFromCoreSignals(); void unsubscribeFromCoreSignals();
signals: signals:
// Signal that balance in wallet changed // Signal that balance in wallet changed
void balanceChanged(qint64 balance, qint64 unconfirmedBalance); void balanceChanged(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
// Number of transactions in wallet changed // Number of transactions in wallet changed
void numTransactionsChanged(int count); void numTransactionsChanged(int count);

View File

@ -567,7 +567,7 @@ void CWalletTx::GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, l
} }
void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived, void CWalletTx::GetAccountAmounts(const string& strAccount, int64& nGenerated, int64& nReceived,
int64& nSent, int64& nFee) const int64& nSent, int64& nFee) const
{ {
nGenerated = nReceived = nSent = nFee = 0; nGenerated = nReceived = nSent = nFee = 0;
@ -851,9 +851,8 @@ int64 CWallet::GetBalance() const
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{ {
const CWalletTx* pcoin = &(*it).second; const CWalletTx* pcoin = &(*it).second;
if (!pcoin->IsFinal() || !pcoin->IsConfirmed()) if (pcoin->IsFinal() && pcoin->IsConfirmed())
continue; nTotal += pcoin->GetAvailableCredit();
nTotal += pcoin->GetAvailableCredit();
} }
} }
@ -868,9 +867,23 @@ int64 CWallet::GetUnconfirmedBalance() const
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{ {
const CWalletTx* pcoin = &(*it).second; const CWalletTx* pcoin = &(*it).second;
if (pcoin->IsFinal() && pcoin->IsConfirmed()) if (!pcoin->IsFinal() || !pcoin->IsConfirmed())
continue; nTotal += pcoin->GetAvailableCredit();
nTotal += pcoin->GetAvailableCredit(); }
}
return nTotal;
}
int64 CWallet::GetImmatureBalance() const
{
int64 nTotal = 0;
{
LOCK(cs_wallet);
for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
const CWalletTx& pcoin = (*it).second;
if (pcoin.IsCoinBase() && pcoin.GetBlocksToMaturity() > 0 && pcoin.GetDepthInMainChain() >= 2)
nTotal += GetCredit(pcoin);
} }
} }
return nTotal; return nTotal;

View File

@ -144,6 +144,7 @@ public:
void ResendWalletTransactions(); void ResendWalletTransactions();
int64 GetBalance() const; int64 GetBalance() const;
int64 GetUnconfirmedBalance() const; int64 GetUnconfirmedBalance() const;
int64 GetImmatureBalance() const;
bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet); bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey); bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);