diff --git a/src/chain.h b/src/chain.h --- a/src/chain.h +++ b/src/chain.h @@ -24,7 +24,7 @@ * Maximum amount of time that a block timestamp is allowed to exceed the * current network-adjusted time before the block will be accepted. */ -static const int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; +static constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60; /** * Timestamp window used as a grace period by code that compares external @@ -32,7 +32,15 @@ * to block timestamps. This should be set at least as high as * MAX_FUTURE_BLOCK_TIME. */ -static const int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME; +static constexpr int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME; + +/** + * Maximum gap between node time and block time used + * for the "Catching up..." mode in GUI. + * + * Ref: https://github.com/bitcoin/bitcoin/pull/1026 + */ +static constexpr int64_t MAX_BLOCK_TIME_GAP = 90 * 60; /** * The block chain is a tree shaped structure starting with the genesis block at diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h --- a/src/interfaces/wallet.h +++ b/src/interfaces/wallet.h @@ -168,7 +168,7 @@ //! Try to get updated status for a particular transaction, if possible //! without blocking. virtual bool tryGetTxStatus(const TxId &txid, WalletTxStatus &tx_status, - int &num_blocks) = 0; + int &num_blocks, int64_t &block_time) = 0; //! Get transaction details. virtual WalletTx getWalletTxDetails(const TxId &txid, diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -267,7 +267,7 @@ } bool tryGetTxStatus(const TxId &txid, interfaces::WalletTxStatus &tx_status, - int &num_blocks) override { + int &num_blocks, int64_t &block_time) override { TRY_LOCK(::cs_main, locked_chain); if (!locked_chain) { return false; @@ -281,6 +281,7 @@ return false; } num_blocks = ::chainActive.Height(); + block_time = ::chainActive.Tip()->GetBlockTime(); tx_status = MakeWalletTxStatus(mi->second); return true; } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -869,7 +870,7 @@ tooltip = tr("Processed %n block(s) of transaction history.", "", count); // Set icon state: spinning if catching up, tick otherwise - if (secs < 90 * 60) { + if (secs < MAX_BLOCK_TIME_GAP) { tooltip = tr("Up to date") + QString(".
") + tooltip; labelBlocksIcon->setPixmap( platformStyle->SingleColorIcon(":/icons/synced") diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h --- a/src/qt/transactionrecord.h +++ b/src/qt/transactionrecord.h @@ -144,7 +144,8 @@ /** Update status from core wallet tx. */ - void updateStatus(const interfaces::WalletTxStatus &wtx, int numBlocks); + void updateStatus(const interfaces::WalletTxStatus &wtx, int numBlocks, + int64_t block_time); /** Return whether a status update is needed. */ diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -12,6 +12,8 @@ #include #include +#include + #include /** @@ -151,7 +153,7 @@ } void TransactionRecord::updateStatus(const interfaces::WalletTxStatus &wtx, - int numBlocks) { + int numBlocks, int64_t block_time) { // Determine transaction status // Sort order, unrecorded transactions sort to the top @@ -161,7 +163,10 @@ status.depth = wtx.depth_in_main_chain; status.cur_num_blocks = numBlocks; - if (!wtx.is_final) { + const bool up_to_date = + (int64_t(QDateTime::currentMSecsSinceEpoch()) / 1000 - block_time < + MAX_BLOCK_TIME_GAP); + if (up_to_date && !wtx.is_final) { if (wtx.lock_time < LOCKTIME_THRESHOLD) { status.status = TransactionStatus::OpenUntilBlock; status.open_for = wtx.lock_time - numBlocks; diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -184,9 +184,10 @@ // simply re-use the cached status. interfaces::WalletTxStatus wtx; int numBlocks; - if (wallet.tryGetTxStatus(rec->txid, wtx, numBlocks) && + int64_t block_time; + if (wallet.tryGetTxStatus(rec->txid, wtx, numBlocks, block_time) && rec->statusUpdateNeeded(numBlocks)) { - rec->updateStatus(wtx, numBlocks); + rec->updateStatus(wtx, numBlocks, block_time); } return rec; }