diff --git a/electrum/gui/qt/invoice_list.py b/electrum/gui/qt/invoice_list.py index 829f3f245..e9540d151 100644 --- a/electrum/gui/qt/invoice_list.py +++ b/electrum/gui/qt/invoice_list.py @@ -27,19 +27,20 @@ from enum import IntEnum from PyQt5.QtCore import Qt, QItemSelectionModel from PyQt5.QtGui import QStandardItemModel, QStandardItem, QFont -from PyQt5.QtWidgets import QHeaderView, QMenu, QVBoxLayout, QGridLayout, QLabel +from PyQt5.QtWidgets import QHeaderView, QMenu, QVBoxLayout, QGridLayout, QLabel, QTreeWidget, QTreeWidgetItem from electrum.i18n import _ from electrum.util import format_time, PR_UNPAID, PR_PAID, PR_INFLIGHT from electrum.util import get_request_status from electrum.util import PR_TYPE_ONCHAIN, PR_TYPE_LN -from electrum.lnutil import lndecode, RECEIVED +from electrum.lnutil import format_short_channel_id from electrum.bitcoin import COIN from electrum import constants from .util import (MyTreeView, read_QIcon, MONOSPACE_FONT, import_meta_gui, export_meta_gui, pr_icons) from .util import CloseButton, Buttons +from .util import WindowModalDialog @@ -168,22 +169,24 @@ class InvoiceList(MyTreeView): menu.exec_(self.viewport().mapToGlobal(position)) def show_log(self, key): - from .util import WindowModalDialog log = self.logs.get(key) d = WindowModalDialog(self, _("Payment log")) vbox = QVBoxLayout(d) - grid = QGridLayout() - grid.addWidget(QLabel(_("Node ID")), 0, 0) - grid.addWidget(QLabel(_("Message")), 0, 1) + log_w = QTreeWidget() + log_w.setHeaderLabels([_('Route'), _('Channel ID'), _('Message')]) for i, (route, success, failure_data) in enumerate(log): - print(route[0].node_id) + route_str = '%d'%len(route) if not success: - failure_node_id, failure_msg = failure_data - code, data = failure_msg.code, failure_msg.data - grid.addWidget(QLabel(failure_node_id.hex()), i+1, 0) - grid.addWidget(QLabel(repr(code)), i+1, 1) + sender_idx, failure_msg = failure_data + short_channel_id = route[sender_idx].short_channel_id + data = failure_msg.data + message = repr(failure_msg.code) else: - pass - vbox.addLayout(grid) + short_channel_id = route[-1].short_channel_id + message = _('Success') + chan_str = format_short_channel_id(short_channel_id) + x = QTreeWidgetItem([route_str, chan_str, message]) + log_w.addTopLevelItem(x) + vbox.addWidget(log_w) vbox.addLayout(Buttons(CloseButton(d))) d.exec_() diff --git a/electrum/gui/qt/util.py b/electrum/gui/qt/util.py index f9577a7ea..14106d104 100644 --- a/electrum/gui/qt/util.py +++ b/electrum/gui/qt/util.py @@ -24,7 +24,7 @@ from PyQt5.QtWidgets import (QPushButton, QLabel, QMessageBox, QHBoxLayout, from electrum.i18n import _, languages from electrum.util import FileImportFailed, FileExportFailed, make_aiohttp_session, resource_path -from electrum.util import PR_UNPAID, PR_PAID, PR_EXPIRED, PR_INFLIGHT, PR_UNKNOWN +from electrum.util import PR_UNPAID, PR_PAID, PR_EXPIRED, PR_INFLIGHT, PR_UNKNOWN, PR_FAILED if TYPE_CHECKING: from .main_window import ElectrumWindow @@ -41,11 +41,12 @@ else: dialogs = [] pr_icons = { - PR_UNKNOWN:"unpaid.png", + PR_UNKNOWN:"warning.png", PR_UNPAID:"unpaid.png", PR_PAID:"confirmed.png", PR_EXPIRED:"expired.png", PR_INFLIGHT:"unconfirmed.png", + PR_FAILED:"warning.png", } diff --git a/electrum/lnworker.py b/electrum/lnworker.py index 7f90f8b04..2c92555c0 100644 --- a/electrum/lnworker.py +++ b/electrum/lnworker.py @@ -862,12 +862,12 @@ class LNWallet(LNWorker): success = False break self.network.trigger_callback('invoice_status', key, PR_INFLIGHT, log) - success, preimage, failure_node_id, failure_msg = await self._pay_to_route(route, lnaddr) + success, preimage, sender_idx, failure_msg = await self._pay_to_route(route, lnaddr) if success: log.append((route, True, preimage)) break else: - log.append((route, False, (failure_node_id, failure_msg))) + log.append((route, False, (sender_idx, failure_msg))) self.network.trigger_callback('invoice_status', key, PR_PAID if success else PR_FAILED, log) return success @@ -883,16 +883,15 @@ class LNWallet(LNWorker): self.network.trigger_callback('htlc_added', htlc, lnaddr, SENT) success, preimage, reason = await self.await_payment(lnaddr.paymenthash) if success: - failure_node_id = None failure_msg = None + sender_idx = None else: failure_msg, sender_idx = chan.decode_onion_error(reason, route, htlc.htlc_id) - failure_node_id = route[sender_idx].node_id code, data = failure_msg.code, failure_msg.data self.logger.info(f"UPDATE_FAIL_HTLC {repr(code)} {data}") self.logger.info(f"error reported by {bh2u(route[sender_idx].node_id)}") self.channel_db.handle_error_code_from_failed_htlc(code, data, sender_idx, route, peer) - return success, preimage, failure_node_id, failure_msg + return success, preimage, sender_idx, failure_msg @staticmethod def _check_invoice(invoice, amount_sat=None):