Browse Source

Generalize ChannelDetailsDialog to channel backups.

Access funding_tx and closing_tx from the dialog,
instead of from the channels_list context menu.
patch-4
ThomasV 3 years ago
parent
commit
f5b1f7d2d9
  1. 115
      electrum/gui/qt/channel_details.py
  2. 15
      electrum/gui/qt/channels_list.py
  3. 6
      electrum/gui/qt/main_window.py

115
electrum/gui/qt/channel_details.py

@ -38,6 +38,50 @@ class LinkedLabel(QtWidgets.QLabel):
class ChannelDetailsDialog(QtWidgets.QDialog, MessageBoxMixin, QtEventListener):
def __init__(self, window: 'ElectrumWindow', chan: AbstractChannel):
super().__init__(window)
# initialize instance fields
self.window = window
self.wallet = window.wallet
self.chan = chan
self.format_msat = lambda msat: window.format_amount_and_units(msat / 1000)
self.format_sat = lambda sat: window.format_amount_and_units(sat)
# register callbacks for updating
self.register_callbacks()
title = _('Lightning Channel') if not self.chan.is_backup() else _('Channel Backup')
self.setWindowTitle(title)
self.setMinimumSize(800, 400)
# activity labels. not used for backups.
self.local_balance_label = SelectableLabel()
self.remote_balance_label = SelectableLabel()
self.can_send_label = SelectableLabel()
self.can_receive_label = SelectableLabel()
# add widgets
vbox = QtWidgets.QVBoxLayout(self)
if self.chan.is_backup():
vbox.addWidget(QLabel('\n'.join([
_("This is a channel backup."),
_("It shows a channel that was opened with another instance of this wallet"),
_("A backup does not contain information about your local balance in the channel."),
_("You can use it to request a force close.")
])))
form = self.get_common_form(chan)
vbox.addLayout(form)
if not self.chan.is_closed() and not self.chan.is_backup():
hbox_stats = self.get_hbox_stats(chan)
form.addRow(QLabel(_('Channel stats')+ ':'), hbox_stats)
if not self.chan.is_backup():
# add htlc tree view to vbox (wouldn't scale correctly in QFormLayout)
vbox.addWidget(QLabel(_('Payments (HTLCs):')))
w = self.create_htlc_list(chan)
vbox.addWidget(w)
vbox.addLayout(Buttons(CloseButton(self)))
# initialize sent/received fields
self.update()
def make_htlc_item(self, i: UpdateAddHtlc, direction: Direction) -> HTLCItem:
it = HTLCItem(_('Sent HTLC with ID {}' if Direction.SENT == direction else 'Received HTLC with ID {}').format(i.htlc_id))
it.appendRow([HTLCItem(_('Amount')),HTLCItem(self.format_msat(i.amount_msat))])
@ -113,6 +157,8 @@ class ChannelDetailsDialog(QtWidgets.QDialog, MessageBoxMixin, QtEventListener):
self.update()
def update(self):
if self.chan.is_closed() or self.chan.is_backup():
return
self.can_send_label.setText(self.format_msat(self.chan.available_to_spend(LOCAL)))
self.can_receive_label.setText(self.format_msat(self.chan.available_to_spend(REMOTE)))
self.sent_label.setText(self.format_msat(self.chan.total_msat(Direction.SENT)))
@ -122,55 +168,47 @@ class ChannelDetailsDialog(QtWidgets.QDialog, MessageBoxMixin, QtEventListener):
@QtCore.pyqtSlot(str)
def show_tx(self, link_text: str):
funding_tx = self.wallet.db.get_transaction(self.chan.funding_outpoint.txid)
if not funding_tx:
self.show_error(_("Funding transaction not found."))
tx = self.wallet.adb.get_transaction(link_text)
if not tx:
self.show_error(_("Transaction not found."))
return
self.window.show_transaction(funding_tx, tx_desc=_('Funding Transaction'))
self.window.show_transaction(tx, tx_desc=_('Transaction'))
def __init__(self, window: 'ElectrumWindow', chan_id: bytes):
super().__init__(window)
# initialize instance fields
self.window = window
self.wallet = window.wallet
chan = self.chan = window.wallet.lnworker.channels[chan_id]
self.format_msat = lambda msat: window.format_amount_and_units(msat / 1000)
self.format_sat = lambda sat: window.format_amount_and_units(sat)
# register callbacks for updating
self.register_callbacks()
# set attributes of QDialog
self.setWindowTitle(_('Channel Details'))
self.setMinimumSize(800, 400)
# add layouts
vbox = QtWidgets.QVBoxLayout(self)
def get_common_form(self, chan):
form = QtWidgets.QFormLayout(None)
remote_id_e = ShowQRLineEdit(chan.node_id.hex(), self.window.config, title=_("Remote Node ID"))
form.addRow(QLabel(_('Remote Node') + ':'), remote_id_e)
channel_id_e = ShowQRLineEdit(chan.channel_id.hex(), self.window.config, title=_("Channel ID"))
form.addRow(QLabel(_('Channel ID') + ':'), channel_id_e)
funding_label_text = f'<a href=click_destination>{chan.funding_outpoint.txid}</a>:{chan.funding_outpoint.output_index}'
form.addRow(QLabel(_('Funding Outpoint') + ':'), LinkedLabel(funding_label_text, self.show_tx))
form.addRow(QLabel(_('Short Channel ID') + ':'), QLabel(str(chan.short_channel_id)))
form.addRow(QLabel(_('State') + ':'), SelectableLabel(chan.get_state_for_GUI()))
self.capacity = self.format_sat(chan.get_capacity())
form.addRow(QLabel(_('Capacity') + ':'), SelectableLabel(self.capacity))
form.addRow(QLabel(_('Channel type:')), SelectableLabel(chan.storage['channel_type'].name_minimal))
initiator = 'Local' if chan.constraints.is_initiator else 'Remote'
form.addRow(QLabel(_('Initiator:')), SelectableLabel(initiator))
vbox.addLayout(form)
if not chan.is_backup():
form.addRow(QLabel(_('Channel type:')), SelectableLabel(chan.storage['channel_type'].name_minimal))
initiator = 'Local' if chan.constraints.is_initiator else 'Remote'
form.addRow(QLabel(_('Initiator:')), SelectableLabel(initiator))
else:
form.addRow(QLabel("Backup Type"), QLabel("imported" if self.chan.is_imported else "on-chain"))
funding_txid = chan.funding_outpoint.txid
funding_label_text = f'<a href={funding_txid}>{funding_txid}</a>:{chan.funding_outpoint.output_index}'
form.addRow(QLabel(_('Funding Outpoint') + ':'), LinkedLabel(funding_label_text, self.show_tx))
if chan.is_closed():
item = chan.get_closing_height()
if item:
closing_txid, closing_height, timestamp = item
closing_label_text = f'<a href={closing_txid}>{closing_txid}</a>'
form.addRow(QLabel(_('Closing Transaction') + ':'), LinkedLabel(closing_label_text, self.show_tx))
return form
def get_hbox_stats(self, chan):
hbox_stats = QHBoxLayout()
form_layout_left = QtWidgets.QFormLayout(None)
form_layout_right = QtWidgets.QFormLayout(None)
self.local_balance_label = SelectableLabel()
self.remote_balance_label = SelectableLabel()
form_layout_left.addRow(_('Local balance') + ':', self.local_balance_label)
form_layout_right.addRow(_('Remote balance') + ':', self.remote_balance_label)
self.can_send_label = SelectableLabel()
self.can_receive_label = SelectableLabel()
form_layout_left.addRow(_('Can send') + ':', self.can_send_label)
form_layout_right.addRow(_('Can receive') + ':', self.can_receive_label)
local_reserve_label = SelectableLabel("{}".format(
@ -209,9 +247,9 @@ class ChannelDetailsDialog(QtWidgets.QDialog, MessageBoxMixin, QtEventListener):
hbox_stats.addWidget(line_separator)
# channel stats right column
hbox_stats.addLayout(form_layout_right, 50)
vbox.addLayout(hbox_stats)
# add htlc tree view to vbox (wouldn't scale correctly in QFormLayout)
vbox.addWidget(QLabel(_('Payments (HTLCs):')))
return hbox_stats
def create_htlc_list(self, chan):
w = QtWidgets.QTreeView(self)
htlc_dict = chan.get_payments()
htlc_list = []
@ -220,10 +258,7 @@ class ChannelDetailsDialog(QtWidgets.QDialog, MessageBoxMixin, QtEventListener):
htlc_list.append(htlc_with_status)
w.setModel(self.make_model(htlc_list))
w.header().setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
vbox.addWidget(w)
vbox.addLayout(Buttons(CloseButton(self)))
# initialize sent/received fields
self.update()
return w
def closeEvent(self, event):
self.unregister_callbacks()

15
electrum/gui/qt/channels_list.py

@ -233,19 +233,8 @@ class ChannelsList(MyTreeView):
if not item:
return
channel_id = idx.sibling(idx.row(), self.Columns.NODE_ALIAS).data(ROLE_CHANNEL_ID)
chan = self.lnworker.channel_backups.get(channel_id) or self.lnworker.channels[channel_id]
if not chan.is_backup():
menu.addAction(_("Details..."), lambda: self.parent.show_channel(channel_id))
funding_tx = self.parent.wallet.db.get_transaction(chan.funding_outpoint.txid)
if funding_tx:
menu.addAction(_("View funding transaction"), lambda: self.parent.show_transaction(funding_tx))
if chan.is_closed():
item = chan.get_closing_height()
if item:
txid, height, timestamp = item
closing_tx = self.parent.wallet.db.get_transaction(txid)
if closing_tx:
menu.addAction(_("View closing transaction"), lambda: self.parent.show_transaction(closing_tx))
chan = self.lnworker.channels.get(channel_id) or self.lnworker.channel_backups[channel_id]
menu.addAction(_("Details..."), lambda: self.parent.show_channel_details(chan))
menu.addSeparator()
cc = self.add_copy_menu(menu, idx)
cc.addAction(_("Node ID"), lambda: self.place_text_on_clipboard(

6
electrum/gui/qt/main_window.py

@ -1059,9 +1059,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger, QtEventListener):
d = address_dialog.AddressDialog(self, addr)
d.exec_()
def show_channel(self, channel_id):
from . import channel_details
channel_details.ChannelDetailsDialog(self, channel_id).show()
def show_channel_details(self, chan):
from .channel_details import ChannelDetailsDialog
ChannelDetailsDialog(self, chan).show()
def show_transaction(self, tx, *, tx_desc=None):
'''tx_desc is set only for txs created in the Send tab'''

Loading…
Cancel
Save