From b711a7a26ace52f4d88a4eb980692c7635dc7964 Mon Sep 17 00:00:00 2001 From: furszy Date: Thu, 16 Jul 2020 11:30:54 -0300 Subject: [PATCH] Solving old, not loaded at startup, transactions notification issue. Problem: we are still signaling updates from really old transactions from the backend and, at the same time, the GUI is not loading more than 20k transactions into the transactionTableModel. So, old transactions that are not being shown in the GUI deliberately are re appearing due the signaling update process. This commits solves it, not showing transactions that appeared before the first tx time loaded into the model. Ofc this is only applied if the wallet is exceeding the maximum loaded transactions limit in the GUI (20,000 transactions) --- src/qt/transactiontablemodel.cpp | 52 ++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 9 deletions(-) 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;