Generalize ChannelDetailsDialog to channel backups.
Access funding_tx and closing_tx from the dialog, instead of from the channels_list context menu.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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'''
|
||||
|
||||
Reference in New Issue
Block a user