qt: Modernize 'confirmed' terminology in shown tx status
These days we regard transactions with one confirmation to be 'Confirmed'. Waiting for 6 confirmations is a recommendation but should not keep the transaction shown as unconfirmed. Misc code sanity: - Merge maturity/status enums, they had become completely disjunct - 'confirmed' flag is now called 'countsForBalance' for clarity
This commit is contained in:
parent
7ac375d1c2
commit
f642fd9dd6
3 changed files with 111 additions and 128 deletions
|
@ -164,7 +164,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)
|
||||||
(wtx.IsCoinBase() ? 1 : 0),
|
(wtx.IsCoinBase() ? 1 : 0),
|
||||||
wtx.nTimeReceived,
|
wtx.nTimeReceived,
|
||||||
idx);
|
idx);
|
||||||
status.confirmed = wtx.IsTrusted();
|
status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0);
|
||||||
status.depth = wtx.GetDepthInMainChain();
|
status.depth = wtx.GetDepthInMainChain();
|
||||||
status.cur_num_blocks = chainActive.Height();
|
status.cur_num_blocks = chainActive.Height();
|
||||||
|
|
||||||
|
@ -181,6 +181,31 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)
|
||||||
status.open_for = wtx.nLockTime;
|
status.open_for = wtx.nLockTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// For generated transactions, determine maturity
|
||||||
|
else if(type == TransactionRecord::Generated)
|
||||||
|
{
|
||||||
|
if (wtx.GetBlocksToMaturity() > 0)
|
||||||
|
{
|
||||||
|
status.status = TransactionStatus::Immature;
|
||||||
|
|
||||||
|
if (wtx.IsInMainChain())
|
||||||
|
{
|
||||||
|
status.matures_in = wtx.GetBlocksToMaturity();
|
||||||
|
|
||||||
|
// Check if the block was requested by anyone
|
||||||
|
if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
|
||||||
|
status.status = TransactionStatus::MaturesWarning;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status.status = TransactionStatus::NotAccepted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status.status = TransactionStatus::Confirmed;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (status.depth < 0)
|
if (status.depth < 0)
|
||||||
|
@ -191,42 +216,20 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)
|
||||||
{
|
{
|
||||||
status.status = TransactionStatus::Offline;
|
status.status = TransactionStatus::Offline;
|
||||||
}
|
}
|
||||||
else if (status.depth < NumConfirmations)
|
else if (status.depth == 0)
|
||||||
{
|
{
|
||||||
status.status = TransactionStatus::Unconfirmed;
|
status.status = TransactionStatus::Unconfirmed;
|
||||||
}
|
}
|
||||||
else
|
else if (status.depth < RecommendedNumConfirmations)
|
||||||
{
|
{
|
||||||
status.status = TransactionStatus::HaveConfirmations;
|
status.status = TransactionStatus::Confirming;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For generated transactions, determine maturity
|
|
||||||
if(type == TransactionRecord::Generated)
|
|
||||||
{
|
|
||||||
int64_t nCredit = wtx.GetCredit(true);
|
|
||||||
if (nCredit == 0)
|
|
||||||
{
|
|
||||||
status.maturity = TransactionStatus::Immature;
|
|
||||||
|
|
||||||
if (wtx.IsInMainChain())
|
|
||||||
{
|
|
||||||
status.matures_in = wtx.GetBlocksToMaturity();
|
|
||||||
|
|
||||||
// Check if the block was requested by anyone
|
|
||||||
if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
|
|
||||||
status.maturity = TransactionStatus::MaturesWarning;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status.maturity = TransactionStatus::NotAccepted;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status.maturity = TransactionStatus::Mature;
|
status.status = TransactionStatus::Confirmed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TransactionRecord::statusUpdateNeeded()
|
bool TransactionRecord::statusUpdateNeeded()
|
||||||
|
|
|
@ -19,33 +19,32 @@ class TransactionStatus
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TransactionStatus():
|
TransactionStatus():
|
||||||
confirmed(false), sortKey(""), maturity(Mature),
|
countsForBalance(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)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
enum Maturity
|
|
||||||
{
|
|
||||||
Immature,
|
|
||||||
Mature,
|
|
||||||
MaturesWarning, /**< Transaction will likely not mature because no nodes have confirmed */
|
|
||||||
NotAccepted
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Status {
|
enum Status {
|
||||||
OpenUntilDate,
|
Confirmed, /**< Have 6 or more confirmations (normal tx) or fully mature (mined tx) **/
|
||||||
OpenUntilBlock,
|
/// Normal (sent/received) transactions
|
||||||
Offline,
|
OpenUntilDate, /**< Transaction not yet final, waiting for date */
|
||||||
Unconfirmed,
|
OpenUntilBlock, /**< Transaction not yet final, waiting for block */
|
||||||
HaveConfirmations,
|
Offline, /**< Not sent to any other nodes **/
|
||||||
Conflicted
|
Unconfirmed, /**< Not yet mined into a block **/
|
||||||
|
Confirming, /**< Confirmed, but waiting for the recommended number of confirmations **/
|
||||||
|
Conflicted, /**< Conflicts with other transaction or mempool **/
|
||||||
|
/// Generated (mined) transactions
|
||||||
|
Immature, /**< Mined but waiting for maturity */
|
||||||
|
MaturesWarning, /**< Transaction will likely not mature because no nodes have confirmed */
|
||||||
|
NotAccepted /**< Mined but not accepted */
|
||||||
};
|
};
|
||||||
|
|
||||||
bool confirmed;
|
/// Transaction counts towards available balance
|
||||||
|
bool countsForBalance;
|
||||||
|
/// Sorting key based on status
|
||||||
std::string sortKey;
|
std::string sortKey;
|
||||||
|
|
||||||
/** @name Generated (mined) transactions
|
/** @name Generated (mined) transactions
|
||||||
@{*/
|
@{*/
|
||||||
Maturity maturity;
|
|
||||||
int matures_in;
|
int matures_in;
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
@ -79,8 +78,8 @@ public:
|
||||||
SendToSelf
|
SendToSelf
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Number of confirmation needed for transaction */
|
/** Number of confirmation recommended for accepting a transaction */
|
||||||
static const int NumConfirmations = 6;
|
static const int RecommendedNumConfirmations = 6;
|
||||||
|
|
||||||
TransactionRecord():
|
TransactionRecord():
|
||||||
hash(), time(0), type(Other), address(""), debit(0), credit(0), idx(0)
|
hash(), time(0), type(Other), address(""), debit(0), credit(0), idx(0)
|
||||||
|
|
|
@ -285,45 +285,38 @@ QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) cons
|
||||||
{
|
{
|
||||||
QString status;
|
QString status;
|
||||||
|
|
||||||
if(wtx->type == TransactionRecord::Generated)
|
switch(wtx->status.status)
|
||||||
{
|
{
|
||||||
switch(wtx->status.maturity)
|
case TransactionStatus::OpenUntilBlock:
|
||||||
{
|
status = tr("Open for %n more block(s)","",wtx->status.open_for);
|
||||||
case TransactionStatus::Immature:
|
break;
|
||||||
status = tr("Immature (%1 confirmations, will be available after %2)").arg(wtx->status.depth).arg(wtx->status.depth + wtx->status.matures_in);
|
case TransactionStatus::OpenUntilDate:
|
||||||
break;
|
status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for));
|
||||||
case TransactionStatus::Mature:
|
break;
|
||||||
status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth);
|
case TransactionStatus::Offline:
|
||||||
break;
|
status = tr("Offline");
|
||||||
case TransactionStatus::MaturesWarning:
|
break;
|
||||||
status = tr("This block was not received by any other nodes and will probably not be accepted!");
|
case TransactionStatus::Unconfirmed:
|
||||||
break;
|
status = tr("Unconfirmed");
|
||||||
case TransactionStatus::NotAccepted:
|
break;
|
||||||
status = tr("Generated but not accepted");
|
case TransactionStatus::Confirming:
|
||||||
break;
|
status = tr("Confirming (%1 of %2 recommended confirmations)").arg(wtx->status.depth).arg(TransactionRecord::RecommendedNumConfirmations);
|
||||||
}
|
break;
|
||||||
} else {
|
case TransactionStatus::Confirmed:
|
||||||
switch(wtx->status.status)
|
status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth);
|
||||||
{
|
break;
|
||||||
case TransactionStatus::OpenUntilBlock:
|
case TransactionStatus::Conflicted:
|
||||||
status = tr("Open for %n more block(s)","",wtx->status.open_for);
|
status = tr("Conflicted");
|
||||||
break;
|
break;
|
||||||
case TransactionStatus::OpenUntilDate:
|
case TransactionStatus::Immature:
|
||||||
status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for));
|
status = tr("Immature (%1 confirmations, will be available after %2)").arg(wtx->status.depth).arg(wtx->status.depth + wtx->status.matures_in);
|
||||||
break;
|
break;
|
||||||
case TransactionStatus::Offline:
|
case TransactionStatus::MaturesWarning:
|
||||||
status = tr("Offline");
|
status = tr("This block was not received by any other nodes and will probably not be accepted!");
|
||||||
break;
|
break;
|
||||||
case TransactionStatus::Unconfirmed:
|
case TransactionStatus::NotAccepted:
|
||||||
status = tr("Unconfirmed (%1 of %2 confirmations)").arg(wtx->status.depth).arg(TransactionRecord::NumConfirmations);
|
status = tr("Generated but not accepted");
|
||||||
break;
|
break;
|
||||||
case TransactionStatus::HaveConfirmations:
|
|
||||||
status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth);
|
|
||||||
break;
|
|
||||||
case TransactionStatus::Conflicted:
|
|
||||||
status = tr("Conflicted");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -441,7 +434,7 @@ QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool
|
||||||
QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit);
|
QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit);
|
||||||
if(showUnconfirmed)
|
if(showUnconfirmed)
|
||||||
{
|
{
|
||||||
if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature)
|
if(!wtx->status.countsForBalance)
|
||||||
{
|
{
|
||||||
str = QString("[") + str + QString("]");
|
str = QString("[") + str + QString("]");
|
||||||
}
|
}
|
||||||
|
@ -451,46 +444,36 @@ QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool
|
||||||
|
|
||||||
QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) const
|
QVariant TransactionTableModel::txStatusDecoration(const TransactionRecord *wtx) const
|
||||||
{
|
{
|
||||||
if(wtx->type == TransactionRecord::Generated)
|
switch(wtx->status.status)
|
||||||
{
|
{
|
||||||
switch(wtx->status.maturity)
|
case TransactionStatus::OpenUntilBlock:
|
||||||
|
case TransactionStatus::OpenUntilDate:
|
||||||
|
return QColor(64,64,255);
|
||||||
|
case TransactionStatus::Offline:
|
||||||
|
return QColor(192,192,192);
|
||||||
|
case TransactionStatus::Unconfirmed:
|
||||||
|
return QIcon(":/icons/transaction_0");
|
||||||
|
case TransactionStatus::Confirming:
|
||||||
|
switch(wtx->status.depth)
|
||||||
{
|
{
|
||||||
case TransactionStatus::Immature: {
|
case 1: return QIcon(":/icons/transaction_1");
|
||||||
int total = wtx->status.depth + wtx->status.matures_in;
|
case 2: return QIcon(":/icons/transaction_2");
|
||||||
int part = (wtx->status.depth * 4 / total) + 1;
|
case 3: return QIcon(":/icons/transaction_3");
|
||||||
return QIcon(QString(":/icons/transaction_%1").arg(part));
|
case 4: return QIcon(":/icons/transaction_4");
|
||||||
}
|
default: return QIcon(":/icons/transaction_5");
|
||||||
case TransactionStatus::Mature:
|
};
|
||||||
return QIcon(":/icons/transaction_confirmed");
|
case TransactionStatus::Confirmed:
|
||||||
case TransactionStatus::MaturesWarning:
|
return QIcon(":/icons/transaction_confirmed");
|
||||||
case TransactionStatus::NotAccepted:
|
case TransactionStatus::Conflicted:
|
||||||
return QIcon(":/icons/transaction_0");
|
return QIcon(":/icons/transaction_conflicted");
|
||||||
}
|
case TransactionStatus::Immature: {
|
||||||
}
|
int total = wtx->status.depth + wtx->status.matures_in;
|
||||||
else
|
int part = (wtx->status.depth * 4 / total) + 1;
|
||||||
{
|
return QIcon(QString(":/icons/transaction_%1").arg(part));
|
||||||
switch(wtx->status.status)
|
|
||||||
{
|
|
||||||
case TransactionStatus::OpenUntilBlock:
|
|
||||||
case TransactionStatus::OpenUntilDate:
|
|
||||||
return QColor(64,64,255);
|
|
||||||
case TransactionStatus::Offline:
|
|
||||||
return QColor(192,192,192);
|
|
||||||
case TransactionStatus::Unconfirmed:
|
|
||||||
switch(wtx->status.depth)
|
|
||||||
{
|
|
||||||
case 0: return QIcon(":/icons/transaction_0");
|
|
||||||
case 1: return QIcon(":/icons/transaction_1");
|
|
||||||
case 2: return QIcon(":/icons/transaction_2");
|
|
||||||
case 3: return QIcon(":/icons/transaction_3");
|
|
||||||
case 4: return QIcon(":/icons/transaction_4");
|
|
||||||
default: return QIcon(":/icons/transaction_5");
|
|
||||||
};
|
|
||||||
case TransactionStatus::HaveConfirmations:
|
|
||||||
return QIcon(":/icons/transaction_confirmed");
|
|
||||||
case TransactionStatus::Conflicted:
|
|
||||||
return QIcon(":/icons/transaction_conflicted");
|
|
||||||
}
|
}
|
||||||
|
case TransactionStatus::MaturesWarning:
|
||||||
|
case TransactionStatus::NotAccepted:
|
||||||
|
return QIcon(":/icons/transaction_0");
|
||||||
}
|
}
|
||||||
return QColor(0,0,0);
|
return QColor(0,0,0);
|
||||||
}
|
}
|
||||||
|
@ -557,8 +540,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
|
||||||
case Qt::TextAlignmentRole:
|
case Qt::TextAlignmentRole:
|
||||||
return column_alignments[index.column()];
|
return column_alignments[index.column()];
|
||||||
case Qt::ForegroundRole:
|
case Qt::ForegroundRole:
|
||||||
// Non-confirmed transactions are grey
|
// Non-confirmed (but not immature) as transactions are grey
|
||||||
if(!rec->status.confirmed)
|
if(!rec->status.countsForBalance && rec->status.status != TransactionStatus::Immature)
|
||||||
{
|
{
|
||||||
return COLOR_UNCONFIRMED;
|
return COLOR_UNCONFIRMED;
|
||||||
}
|
}
|
||||||
|
@ -586,9 +569,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
|
||||||
case TxIDRole:
|
case TxIDRole:
|
||||||
return rec->getTxID();
|
return rec->getTxID();
|
||||||
case ConfirmedRole:
|
case ConfirmedRole:
|
||||||
// Return True if transaction counts for balance
|
return rec->status.countsForBalance;
|
||||||
return rec->status.confirmed && !(rec->type == TransactionRecord::Generated &&
|
|
||||||
rec->status.maturity != TransactionStatus::Mature);
|
|
||||||
case FormattedAmountRole:
|
case FormattedAmountRole:
|
||||||
return formatTxAmount(rec, false);
|
return formatTxAmount(rec, false);
|
||||||
case StatusRole:
|
case StatusRole:
|
||||||
|
|
Loading…
Reference in a new issue