diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index b9737010cdac..1c71d1fdf310 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -63,6 +63,12 @@ struct TxLessThan { } }; +struct ConvertTxToVectorResult +{ + QList records; + qint64 nFirstLoadedTxTime{0}; +}; + // Private implementation class TransactionTablePriv { @@ -82,6 +88,12 @@ class TransactionTablePriv QList cachedWallet; bool hasZcTxes = false; + /** + * Time of the oldest transaction loaded into the model. + * It can or not be the first tx in the wallet, the model only loads the last 20k txs. + */ + qint64 nFirstLoadedTxTime{0}; + /* Query entire wallet anew from core. */ void refreshWallet() @@ -116,7 +128,7 @@ class TransactionTablePriv // Size of the tx subsets std::size_t const subsetSize = txesSize / (threadsCount + 1); std::size_t totalSumSize = 0; - QList>> tasks; + QList> tasks; // Subsets + run task for (std::size_t i = 0; i < threadsCount; ++i) { @@ -136,20 +148,27 @@ class TransactionTablePriv auto res = convertTxToRecords(this, wallet, std::vector(walletTxes.end() - remainingSize, walletTxes.end()) ); - cachedWallet.append(res); + cachedWallet.append(res.records); + nFirstLoadedTxTime = res.nFirstLoadedTxTime; for (auto &future : tasks) { future.waitForFinished(); - cachedWallet.append(future.result()); + ConvertTxToVectorResult convertRes = future.result(); + cachedWallet.append(convertRes.records); + if (nFirstLoadedTxTime > convertRes.nFirstLoadedTxTime) { + nFirstLoadedTxTime = convertRes.nFirstLoadedTxTime; + } } } else { // Single thread flow - cachedWallet.append(convertTxToRecords(this, wallet, walletTxes)); + ConvertTxToVectorResult convertRes = convertTxToRecords(this, wallet, walletTxes); + cachedWallet.append(convertRes.records); + nFirstLoadedTxTime = convertRes.nFirstLoadedTxTime; } } - static QList convertTxToRecords(TransactionTablePriv* tablePriv, const CWallet* wallet, const std::vector& walletTxes) { - QList cachedWallet; + static ConvertTxToVectorResult convertTxToRecords(TransactionTablePriv* tablePriv, const CWallet* wallet, const std::vector& walletTxes) { + ConvertTxToVectorResult res; bool hasZcTxes = tablePriv->hasZcTxes; for (const auto &tx : walletTxes) { @@ -162,13 +181,20 @@ class TransactionTablePriv } } - cachedWallet.append(records); + if (!records.isEmpty()) { + qint64 time = records.first().time; + if (res.nFirstLoadedTxTime == 0 || res.nFirstLoadedTxTime > time) { + res.nFirstLoadedTxTime = time; + } + } + + res.records.append(records); } if (hasZcTxes) // Only update it if it's true, multi-thread operation. tablePriv->hasZcTxes = true; - return cachedWallet; + return res; } static bool HasZcTxesIfNeeded(const TransactionRecord& record) { @@ -221,9 +247,17 @@ class TransactionTablePriv qWarning() << "TransactionTablePriv::updateWallet : Warning: Got CT_NEW, but transaction is not in wallet"; break; } + const CWalletTx& wtx = mi->second; + + // As old transactions are still getting updated (+20k range), + // do not add them if we deliberately didn't load them at startup. + if (cachedWallet.size() >= MAX_AMOUNT_LOADED_RECORDS && wtx.GetTxTime() < nFirstLoadedTxTime) { + return; + } + // Added -- insert at the right position QList toInsert = - TransactionRecord::decomposeTransaction(wallet, mi->second); + TransactionRecord::decomposeTransaction(wallet, wtx); if (!toInsert.isEmpty()) { /* only if something to insert */ parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex + toInsert.size() - 1); int insert_idx = lowerIndex;