From 0509109d6164e9686555e4a7748b6f2686361833 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Wed, 29 Jun 2022 19:11:05 +0200 Subject: [PATCH] qt.util.MyTreeView: handle find_row_by_key returning None fixes https://github.com/spesmilo/electrum/issues/7780 fixes https://github.com/spesmilo/electrum/issues/7815 Re FIXME in main_window.py, in particular, adb might call `add_transaction` on the same tx multiple times. In `wallet.on_event_adb_added_tx`, maybe we should propagate `notify_GUI` to `wallet._update_request_statuses_touched_by_tx`. The issue being fixed here (above TARS reports) can be triggered in multiple ways, e.g.: - have an already paid receive request, and receive a payment to the same address again - have an already paid receive request, and *spend from* that address (in which case the history of the address will change, and address_synchronizer will call add_transaction again on the old tx that satisfied the old receive request) --- electrum/gui/qt/address_list.py | 1 + electrum/gui/qt/invoice_list.py | 1 + electrum/gui/qt/main_window.py | 1 + electrum/gui/qt/request_list.py | 1 + electrum/gui/qt/util.py | 12 +++++++++--- electrum/gui/qt/utxo_list.py | 1 + 6 files changed, 14 insertions(+), 3 deletions(-) diff --git a/electrum/gui/qt/address_list.py b/electrum/gui/qt/address_list.py index 3a8c99194..f43d1134c 100644 --- a/electrum/gui/qt/address_list.py +++ b/electrum/gui/qt/address_list.py @@ -215,6 +215,7 @@ class AddressList(MyTreeView): self.proxy.setDynamicSortFilter(True) def refresh_row(self, key, row): + assert row is not None address = key label = self.wallet.get_label(address) num = self.wallet.adb.get_address_history_len(address) diff --git a/electrum/gui/qt/invoice_list.py b/electrum/gui/qt/invoice_list.py index c9a9cb861..821316dbb 100644 --- a/electrum/gui/qt/invoice_list.py +++ b/electrum/gui/qt/invoice_list.py @@ -75,6 +75,7 @@ class InvoiceList(MyTreeView): self.setSelectionMode(QAbstractItemView.ExtendedSelection) def refresh_row(self, key, row): + assert row is not None invoice = self.parent.wallet.invoices.get(key) if invoice is None: return diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py index e4f561352..c00e92ea2 100644 --- a/electrum/gui/qt/main_window.py +++ b/electrum/gui/qt/main_window.py @@ -1817,6 +1817,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener): if req is None: return if status == PR_PAID: + # FIXME notification should only be shown if request was not PAID before msg = _('Payment received:') amount = req.get_amount_sat() if amount: diff --git a/electrum/gui/qt/request_list.py b/electrum/gui/qt/request_list.py index 25c020bd9..808737e61 100644 --- a/electrum/gui/qt/request_list.py +++ b/electrum/gui/qt/request_list.py @@ -105,6 +105,7 @@ class RequestList(MyTreeView): self.selectionModel().clearCurrentIndex() def refresh_row(self, key, row): + assert row is not None model = self.std_model request = self.wallet.get_request(key) if request is None: diff --git a/electrum/gui/qt/util.py b/electrum/gui/qt/util.py index 5c6028d89..06f8c9100 100644 --- a/electrum/gui/qt/util.py +++ b/electrum/gui/qt/util.py @@ -794,7 +794,7 @@ class MyTreeView(QTreeView): self._pending_update = defer return defer - def find_row_by_key(self, key): + def find_row_by_key(self, key) -> Optional[int]: for row in range(0, self.std_model.rowCount()): item = self.std_model.item(row, 0) if item.data(self.key_role) == key: @@ -806,15 +806,21 @@ class MyTreeView(QTreeView): key = item.data(self.key_role) self.refresh_row(key, row) + def refresh_row(self, key: str, row: int) -> None: + pass + def refresh_item(self, key): row = self.find_row_by_key(key) - self.refresh_row(key, row) + if row is not None: + self.refresh_row(key, row) def delete_item(self, key): row = self.find_row_by_key(key) - self.std_model.takeRow(row) + if row is not None: + self.std_model.takeRow(row) self.hide_if_empty() + class MySortModel(QSortFilterProxyModel): def __init__(self, parent, *, sort_role): super().__init__(parent) diff --git a/electrum/gui/qt/utxo_list.py b/electrum/gui/qt/utxo_list.py index 1f8a136bf..ca692ca27 100644 --- a/electrum/gui/qt/utxo_list.py +++ b/electrum/gui/qt/utxo_list.py @@ -114,6 +114,7 @@ class UTXOList(MyTreeView): self.parent.set_coincontrol_msg(None) def refresh_row(self, key, row): + assert row is not None utxo = self._utxo_dict[key] utxo_item = [self.std_model.item(row, col) for col in self.Columns] address = utxo.address