From f642fd9dd6924472aba42ca324be9515690c59ad Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 20 Feb 2014 14:09:09 +0100 Subject: [PATCH] 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 --- src/qt/transactionrecord.cpp | 59 +++++++------ src/qt/transactionrecord.h | 37 ++++---- src/qt/transactiontablemodel.cpp | 143 ++++++++++++++----------------- 3 files changed, 111 insertions(+), 128 deletions(-) diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 8cfaed27c..703a2b4e7 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -164,7 +164,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) (wtx.IsCoinBase() ? 1 : 0), wtx.nTimeReceived, idx); - status.confirmed = wtx.IsTrusted(); + status.countsForBalance = wtx.IsTrusted() && !(wtx.GetBlocksToMaturity() > 0); status.depth = wtx.GetDepthInMainChain(); status.cur_num_blocks = chainActive.Height(); @@ -181,6 +181,31 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) 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 { if (status.depth < 0) @@ -191,42 +216,20 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) { status.status = TransactionStatus::Offline; } - else if (status.depth < NumConfirmations) + else if (status.depth == 0) { status.status = TransactionStatus::Unconfirmed; } - else + else if (status.depth < RecommendedNumConfirmations) { - status.status = TransactionStatus::HaveConfirmations; - } - } - - // 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; - } + status.status = TransactionStatus::Confirming; } else { - status.maturity = TransactionStatus::Mature; + status.status = TransactionStatus::Confirmed; } } + } bool TransactionRecord::statusUpdateNeeded() diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h index d7be0bc43..af6fd403b 100644 --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -19,33 +19,32 @@ class TransactionStatus { public: TransactionStatus(): - confirmed(false), sortKey(""), maturity(Mature), + countsForBalance(false), sortKey(""), 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 { - OpenUntilDate, - OpenUntilBlock, - Offline, - Unconfirmed, - HaveConfirmations, - Conflicted + Confirmed, /**< Have 6 or more confirmations (normal tx) or fully mature (mined tx) **/ + /// Normal (sent/received) transactions + OpenUntilDate, /**< Transaction not yet final, waiting for date */ + OpenUntilBlock, /**< Transaction not yet final, waiting for block */ + Offline, /**< Not sent to any other nodes **/ + 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; /** @name Generated (mined) transactions @{*/ - Maturity maturity; int matures_in; /**@}*/ @@ -79,8 +78,8 @@ public: SendToSelf }; - /** Number of confirmation needed for transaction */ - static const int NumConfirmations = 6; + /** Number of confirmation recommended for accepting a transaction */ + static const int RecommendedNumConfirmations = 6; TransactionRecord(): hash(), time(0), type(Other), address(""), debit(0), credit(0), idx(0) diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 7d76204ba..959987461 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -285,45 +285,38 @@ QString TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) cons { QString status; - if(wtx->type == TransactionRecord::Generated) + switch(wtx->status.status) { - switch(wtx->status.maturity) - { - case TransactionStatus::Immature: - status = tr("Immature (%1 confirmations, will be available after %2)").arg(wtx->status.depth).arg(wtx->status.depth + wtx->status.matures_in); - break; - case TransactionStatus::Mature: - status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth); - break; - case TransactionStatus::MaturesWarning: - status = tr("This block was not received by any other nodes and will probably not be accepted!"); - break; - case TransactionStatus::NotAccepted: - status = tr("Generated but not accepted"); - break; - } - } else { - switch(wtx->status.status) - { - case TransactionStatus::OpenUntilBlock: - status = tr("Open for %n more block(s)","",wtx->status.open_for); - break; - case TransactionStatus::OpenUntilDate: - status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for)); - break; - case TransactionStatus::Offline: - status = tr("Offline"); - break; - case TransactionStatus::Unconfirmed: - status = tr("Unconfirmed (%1 of %2 confirmations)").arg(wtx->status.depth).arg(TransactionRecord::NumConfirmations); - break; - case TransactionStatus::HaveConfirmations: - status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth); - break; - case TransactionStatus::Conflicted: - status = tr("Conflicted"); - break; - } + case TransactionStatus::OpenUntilBlock: + status = tr("Open for %n more block(s)","",wtx->status.open_for); + break; + case TransactionStatus::OpenUntilDate: + status = tr("Open until %1").arg(GUIUtil::dateTimeStr(wtx->status.open_for)); + break; + case TransactionStatus::Offline: + status = tr("Offline"); + break; + case TransactionStatus::Unconfirmed: + status = tr("Unconfirmed"); + break; + case TransactionStatus::Confirming: + status = tr("Confirming (%1 of %2 recommended confirmations)").arg(wtx->status.depth).arg(TransactionRecord::RecommendedNumConfirmations); + break; + case TransactionStatus::Confirmed: + status = tr("Confirmed (%1 confirmations)").arg(wtx->status.depth); + break; + case TransactionStatus::Conflicted: + status = tr("Conflicted"); + break; + case TransactionStatus::Immature: + status = tr("Immature (%1 confirmations, will be available after %2)").arg(wtx->status.depth).arg(wtx->status.depth + wtx->status.matures_in); + break; + case TransactionStatus::MaturesWarning: + status = tr("This block was not received by any other nodes and will probably not be accepted!"); + break; + case TransactionStatus::NotAccepted: + status = tr("Generated but not accepted"); + break; } return status; @@ -441,7 +434,7 @@ QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool QString str = BitcoinUnits::format(walletModel->getOptionsModel()->getDisplayUnit(), wtx->credit + wtx->debit); if(showUnconfirmed) { - if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature) + if(!wtx->status.countsForBalance) { str = QString("[") + str + QString("]"); } @@ -451,46 +444,36 @@ QString TransactionTableModel::formatTxAmount(const TransactionRecord *wtx, bool 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: { - int total = wtx->status.depth + wtx->status.matures_in; - int part = (wtx->status.depth * 4 / total) + 1; - return QIcon(QString(":/icons/transaction_%1").arg(part)); - } - case TransactionStatus::Mature: - return QIcon(":/icons/transaction_confirmed"); - case TransactionStatus::MaturesWarning: - case TransactionStatus::NotAccepted: - return QIcon(":/icons/transaction_0"); - } - } - else - { - 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 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::Confirmed: + return QIcon(":/icons/transaction_confirmed"); + case TransactionStatus::Conflicted: + return QIcon(":/icons/transaction_conflicted"); + case TransactionStatus::Immature: { + int total = wtx->status.depth + wtx->status.matures_in; + int part = (wtx->status.depth * 4 / total) + 1; + return QIcon(QString(":/icons/transaction_%1").arg(part)); } + case TransactionStatus::MaturesWarning: + case TransactionStatus::NotAccepted: + return QIcon(":/icons/transaction_0"); } return QColor(0,0,0); } @@ -557,8 +540,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case Qt::TextAlignmentRole: return column_alignments[index.column()]; case Qt::ForegroundRole: - // Non-confirmed transactions are grey - if(!rec->status.confirmed) + // Non-confirmed (but not immature) as transactions are grey + if(!rec->status.countsForBalance && rec->status.status != TransactionStatus::Immature) { return COLOR_UNCONFIRMED; } @@ -586,9 +569,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const case TxIDRole: return rec->getTxID(); case ConfirmedRole: - // Return True if transaction counts for balance - return rec->status.confirmed && !(rec->type == TransactionRecord::Generated && - rec->status.maturity != TransactionStatus::Mature); + return rec->status.countsForBalance; case FormattedAmountRole: return formatTxAmount(rec, false); case StatusRole: