LBRY-Vault/electrum/gui/qt/channel_details.py
2019-08-20 09:03:11 +02:00

109 lines
5 KiB
Python

from typing import TYPE_CHECKING
import PyQt5.QtGui as QtGui
import PyQt5.QtWidgets as QtWidgets
import PyQt5.QtCore as QtCore
from electrum.i18n import _
from electrum.lnchan import UpdateAddHtlc
from electrum.util import bh2u, format_time
from electrum.lnchan import HTLCOwner
from electrum.lnaddr import LnAddr, lndecode
if TYPE_CHECKING:
from .main_window import ElectrumWindow
class HTLCItem(QtGui.QStandardItem):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setEditable(False)
class ChannelDetailsDialog(QtWidgets.QDialog):
def make_inflight(self, lnaddr, i: UpdateAddHtlc):
it = HTLCItem(_('HTLC with ID ') + str(i.htlc_id))
it.appendRow([HTLCItem(_('Amount')),HTLCItem(self.format(i.amount_msat))])
it.appendRow([HTLCItem(_('CLTV expiry')),HTLCItem(str(i.cltv_expiry))])
it.appendRow([HTLCItem(_('Payment hash')),HTLCItem(bh2u(i.payment_hash))])
invoice = HTLCItem(_('Invoice'))
invoice.appendRow([HTLCItem(_('Remote node public key')), HTLCItem(bh2u(lnaddr.pubkey.serialize()))])
invoice.appendRow([HTLCItem(_('Amount in BTC')), HTLCItem(str(lnaddr.amount))])
invoice.appendRow([HTLCItem(_('Description')), HTLCItem(dict(lnaddr.tags).get('d', _('N/A')))])
invoice.appendRow([HTLCItem(_('Date')), HTLCItem(format_time(lnaddr.date))])
it.appendRow([invoice])
return it
def make_model(self, htlcs):
model = QtGui.QStandardItemModel(0, 2)
model.setHorizontalHeaderLabels(['HTLC', 'Property value'])
parentItem = model.invisibleRootItem()
folder_types = {'settled': _('Fulfilled HTLCs'), 'inflight': _('HTLCs in current commitment transaction')}
self.folders = {}
self.keyname_rows = {}
for keyname, i in folder_types.items():
myFont=QtGui.QFont()
myFont.setBold(True)
folder = HTLCItem(i)
folder.setFont(myFont)
parentItem.appendRow(folder)
self.folders[keyname] = folder
mapping = {}
num = 0
if keyname == 'inflight':
for lnaddr, i in htlcs[keyname]:
it = self.make_inflight(lnaddr, i)
self.folders[keyname].appendRow(it)
mapping[i.payment_hash] = num
num += 1
elif keyname == 'settled':
for date, direction, i, preimage in htlcs[keyname]:
it = HTLCItem(_('HTLC with ID ') + str(i.htlc_id))
it.appendRow([HTLCItem(_('Amount')),HTLCItem(self.format(i.amount_msat))])
it.appendRow([HTLCItem(_('CLTV expiry')),HTLCItem(str(i.cltv_expiry))])
it.appendRow([HTLCItem(_('Payment hash')),HTLCItem(bh2u(i.payment_hash))])
# NOTE no invoices because user can delete invoices after settlement
self.folders[keyname].appendRow(it)
mapping[i.payment_hash] = num
num += 1
self.keyname_rows[keyname] = mapping
return model
def move(self, fro: str, to: str, payment_hash: bytes):
assert fro != to
row_idx = self.keyname_rows[fro].pop(payment_hash)
row = self.folders[fro].takeRow(row_idx)
self.folders[to].appendRow(row)
dest_mapping = self.keyname_rows[to]
dest_mapping[payment_hash] = len(dest_mapping)
ln_payment_completed = QtCore.pyqtSignal(str, float, HTLCOwner, UpdateAddHtlc, bytes, bytes)
htlc_added = QtCore.pyqtSignal(str, UpdateAddHtlc, LnAddr, HTLCOwner)
@QtCore.pyqtSlot(str, UpdateAddHtlc, LnAddr, HTLCOwner)
def do_htlc_added(self, evtname, htlc, lnaddr, direction):
mapping = self.keyname_rows['inflight']
mapping[htlc.payment_hash] = len(mapping)
self.folders['inflight'].appendRow(self.make_inflight(lnaddr, htlc))
@QtCore.pyqtSlot(str, float, HTLCOwner, UpdateAddHtlc, bytes, bytes)
def do_ln_payment_completed(self, evtname, date, direction, htlc, preimage, chan_id):
self.move('inflight', 'settled', htlc.payment_hash)
def __init__(self, window: 'ElectrumWindow', chan_id: bytes):
super().__init__(window)
self.ln_payment_completed.connect(self.do_ln_payment_completed)
self.htlc_added.connect(self.do_htlc_added)
htlcs = window.wallet.lnworker._list_invoices(chan_id)
self.format = lambda msat: window.format_amount_and_units(msat / 1000)
window.network.register_callback(self.ln_payment_completed.emit, ['ln_payment_completed'])
window.network.register_callback(self.htlc_added.emit, ['htlc_added'])
self.setWindowTitle(_('Channel Details'))
self.setMinimumSize(800, 400)
vbox = QtWidgets.QVBoxLayout(self)
w = QtWidgets.QTreeView(self)
w.setModel(self.make_model(htlcs))
#w.header().setStretchLastSection(False)
w.header().setSectionResizeMode(0, QtWidgets.QHeaderView.ResizeToContents)
vbox.addWidget(w)