Skip to content

Commit 526f67a

Browse files
committed
Merge bitcoin-core#704: Correctly limit overview transaction list
08209c0 Correctly limit overview transaction list (John Moffett) Pull request description: Fixes bitcoin-core#703 The way the main overview page limits the number of transactions displayed (currently 5) is not an appropriate use of Qt. Our subclassed transaction sort/filter proxy model returns a maximum of `5` in `rowCount()`. However, the model itself actually may hold significantly more. While this has _worked_, it breaks the contract of `rowCount()`. If `bitcoin-qt` is run with a DEBUG build of Qt, it'll result in an assert-crash in certain relatively common situations (see bitcoin-core#703 for details). Instead of artificially limiting the `rowCount()` in the subclassed filter, we can hide/unhide the rows in the displaying `QListView` upon any changes in the sorted proxy filter. I loaded a wallet with 20,000 transactions and did not notice any performance differences between master and this branch. For reference, this is the list I'm referring to: <img width="934" alt="image" src="https://user-images.githubusercontent.com/116917595/214947304-3f289380-3510-487b-80e8-d19428cf2f0f.png"> ACKs for top commit: Sjors: tACK 08209c0 hebasto: ACK 08209c0, tested on Ubuntu 22.04. Tree-SHA512: c2a7b1a2a6e6ff30694830d7c722274c4c47494a81ce9ef25f8e5587c24871b02343969f4437507693d4fd40ba7a212702b159cf54b3357d8d76c02bc8245113
2 parents 21138fe + 08209c0 commit 526f67a

File tree

4 files changed

+15
-24
lines changed

4 files changed

+15
-24
lines changed

src/qt/overviewpage.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,6 @@ void OverviewPage::setWalletModel(WalletModel *model)
262262
// Set up transaction list
263263
filter.reset(new TransactionFilterProxy());
264264
filter->setSourceModel(model->getTransactionTableModel());
265-
filter->setLimit(NUM_ITEMS);
266265
filter->setDynamicSortFilter(true);
267266
filter->setSortRole(Qt::EditRole);
268267
filter->setShowInactive(false);
@@ -271,6 +270,10 @@ void OverviewPage::setWalletModel(WalletModel *model)
271270
ui->listTransactions->setModel(filter.get());
272271
ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);
273272

273+
connect(filter.get(), &TransactionFilterProxy::rowsInserted, this, &OverviewPage::LimitTransactionRows);
274+
connect(filter.get(), &TransactionFilterProxy::rowsRemoved, this, &OverviewPage::LimitTransactionRows);
275+
connect(filter.get(), &TransactionFilterProxy::rowsMoved, this, &OverviewPage::LimitTransactionRows);
276+
LimitTransactionRows();
274277
// Keep up to date with wallet
275278
setBalance(model->getCachedBalance());
276279
connect(model, &WalletModel::balanceChanged, this, &OverviewPage::setBalance);
@@ -299,6 +302,16 @@ void OverviewPage::changeEvent(QEvent* e)
299302
QWidget::changeEvent(e);
300303
}
301304

305+
// Only show most recent NUM_ITEMS rows
306+
void OverviewPage::LimitTransactionRows()
307+
{
308+
if (filter && ui->listTransactions && ui->listTransactions->model() && filter.get() == ui->listTransactions->model()) {
309+
for (int i = 0; i < filter->rowCount(); ++i) {
310+
ui->listTransactions->setRowHidden(i, i >= NUM_ITEMS);
311+
}
312+
}
313+
}
314+
302315
void OverviewPage::updateDisplayUnit()
303316
{
304317
if (walletModel && walletModel->getOptionsModel()) {

src/qt/overviewpage.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public Q_SLOTS:
6060
std::unique_ptr<TransactionFilterProxy> filter;
6161

6262
private Q_SLOTS:
63+
void LimitTransactionRows();
6364
void updateDisplayUnit();
6465
void handleTransactionClicked(const QModelIndex &index);
6566
void updateAlerts(const QString &warnings);

src/qt/transactionfilterproxy.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,25 +88,8 @@ void TransactionFilterProxy::setWatchOnlyFilter(WatchOnlyFilter filter)
8888
invalidateFilter();
8989
}
9090

91-
void TransactionFilterProxy::setLimit(int limit)
92-
{
93-
this->limitRows = limit;
94-
}
95-
9691
void TransactionFilterProxy::setShowInactive(bool _showInactive)
9792
{
9893
this->showInactive = _showInactive;
9994
invalidateFilter();
10095
}
101-
102-
int TransactionFilterProxy::rowCount(const QModelIndex &parent) const
103-
{
104-
if(limitRows != -1)
105-
{
106-
return std::min(QSortFilterProxyModel::rowCount(parent), limitRows);
107-
}
108-
else
109-
{
110-
return QSortFilterProxyModel::rowCount(parent);
111-
}
112-
}

src/qt/transactionfilterproxy.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,9 @@ class TransactionFilterProxy : public QSortFilterProxyModel
4242
void setMinAmount(const CAmount& minimum);
4343
void setWatchOnlyFilter(WatchOnlyFilter filter);
4444

45-
/** Set maximum number of rows returned, -1 if unlimited. */
46-
void setLimit(int limit);
47-
4845
/** Set whether to show conflicted transactions. */
4946
void setShowInactive(bool showInactive);
5047

51-
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
52-
5348
protected:
5449
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const override;
5550

@@ -60,7 +55,6 @@ class TransactionFilterProxy : public QSortFilterProxyModel
6055
quint32 typeFilter;
6156
WatchOnlyFilter watchOnlyFilter{WatchOnlyFilter_All};
6257
CAmount minAmount{0};
63-
int limitRows{-1};
6458
bool showInactive{true};
6559
};
6660

0 commit comments

Comments
 (0)