filter callbacks to wallet: channel, payment_succeeded, payment_failed

It is ugly that the 'channel' callback takes a wallet I guess,
but with channel backups in one wallet, and active channels in another,
it was causing problems... (when open simultaneously)
This commit is contained in:
SomberNight 2020-06-19 04:11:35 +02:00
parent 625f985f22
commit 4c70956687
No known key found for this signature in database
GPG key ID: B33B5F232C6271E9
6 changed files with 49 additions and 31 deletions

View file

@ -249,12 +249,12 @@ class ElectrumWindow(App):
if self.invoice_popup and self.invoice_popup.key == key:
self.invoice_popup.update_status()
def on_payment_succeeded(self, event, key):
def on_payment_succeeded(self, event, wallet, key):
description = self.wallet.get_label(key)
self.show_info(_('Payment succeeded') + '\n\n' + description)
self._trigger_update_history()
def on_payment_failed(self, event, key, reason):
def on_payment_failed(self, event, wallet, key, reason):
self.show_info(_('Payment failed') + '\n\n' + reason)
def _get_bu(self):
@ -723,7 +723,7 @@ class ElectrumWindow(App):
self._channels_dialog = LightningChannelsDialog(self)
self._channels_dialog.open()
def on_channel(self, evt, chan):
def on_channel(self, evt, wallet, chan):
if self._channels_dialog:
Clock.schedule_once(lambda dt: self._channels_dialog.update())

View file

@ -9,9 +9,10 @@ from electrum import util
from electrum.i18n import _
from electrum.util import bh2u, format_time
from electrum.lnutil import format_short_channel_id, LOCAL, REMOTE, UpdateAddHtlc, Direction
from electrum.lnchannel import htlcsum, Channel
from electrum.lnchannel import htlcsum, Channel, AbstractChannel
from electrum.lnaddr import LnAddr, lndecode
from electrum.bitcoin import COIN
from electrum.wallet import Abstract_Wallet
from .util import Buttons, CloseButton, ButtonsLineEdit
@ -80,10 +81,12 @@ class ChannelDetailsDialog(QtWidgets.QDialog):
ln_payment_completed = QtCore.pyqtSignal(str, bytes, bytes)
ln_payment_failed = QtCore.pyqtSignal(str, bytes, bytes)
htlc_added = QtCore.pyqtSignal(str, UpdateAddHtlc, LnAddr, Direction)
state_changed = QtCore.pyqtSignal(str, Channel)
state_changed = QtCore.pyqtSignal(str, Abstract_Wallet, AbstractChannel)
@QtCore.pyqtSlot(str, Channel)
def do_state_changed(self, chan):
@QtCore.pyqtSlot(str, Abstract_Wallet, AbstractChannel)
def do_state_changed(self, wallet, chan):
if wallet != self.wallet:
return
if chan == self.chan:
self.update()
@ -115,7 +118,7 @@ class ChannelDetailsDialog(QtWidgets.QDialog):
@QtCore.pyqtSlot(str)
def show_tx(self, link_text: str):
funding_tx = self.window.wallet.db.get_transaction(self.chan.funding_outpoint.txid)
funding_tx = self.wallet.db.get_transaction(self.chan.funding_outpoint.txid)
self.window.show_transaction(funding_tx, tx_desc=_('Funding Transaction'))
def __init__(self, window: 'ElectrumWindow', chan_id: bytes):
@ -123,6 +126,7 @@ class ChannelDetailsDialog(QtWidgets.QDialog):
# 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)

View file

@ -26,7 +26,7 @@ ROLE_CHANNEL_ID = Qt.UserRole
class ChannelsList(MyTreeView):
update_rows = QtCore.pyqtSignal(Abstract_Wallet)
update_single_row = QtCore.pyqtSignal(AbstractChannel)
update_single_row = QtCore.pyqtSignal(Abstract_Wallet, AbstractChannel)
gossip_db_loaded = QtCore.pyqtSignal()
class Columns(IntEnum):
@ -202,9 +202,11 @@ class ChannelsList(MyTreeView):
menu.addAction(_("Delete"), lambda: self.remove_channel(channel_id))
menu.exec_(self.viewport().mapToGlobal(position))
@QtCore.pyqtSlot(AbstractChannel)
def do_update_single_row(self, chan: AbstractChannel):
lnworker = self.parent.wallet.lnworker
@QtCore.pyqtSlot(Abstract_Wallet, AbstractChannel)
def do_update_single_row(self, wallet: Abstract_Wallet, chan: AbstractChannel):
if wallet != self.parent.wallet:
return
lnworker = wallet.lnworker
if not lnworker:
return
for row in range(self.model().rowCount()):

View file

@ -427,18 +427,26 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
elif event == 'gossip_db_loaded':
self.channels_list.gossip_db_loaded.emit(*args)
elif event == 'channels_updated':
self.channels_list.update_rows.emit(*args)
wallet = args[0]
if wallet == self.wallet:
self.channels_list.update_rows.emit(*args)
elif event == 'channel':
self.channels_list.update_single_row.emit(*args)
self.update_status()
wallet = args[0]
if wallet == self.wallet:
self.channels_list.update_single_row.emit(*args)
self.update_status()
elif event == 'request_status':
self.on_request_status(*args)
elif event == 'invoice_status':
self.on_invoice_status(*args)
elif event == 'payment_succeeded':
self.on_payment_succeeded(*args)
wallet = args[0]
if wallet == self.wallet:
self.on_payment_succeeded(*args)
elif event == 'payment_failed':
self.on_payment_failed(*args)
wallet = args[0]
if wallet == self.wallet:
self.on_payment_failed(*args)
elif event == 'status':
self.update_status()
elif event == 'banner':
@ -1498,12 +1506,12 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
return
self.invoice_list.update_item(key, req)
def on_payment_succeeded(self, key):
def on_payment_succeeded(self, wallet, key):
description = self.wallet.get_label(key)
self.notify(_('Payment succeeded') + '\n\n' + description)
self.need_update.set()
def on_payment_failed(self, key, reason):
def on_payment_failed(self, wallet, key, reason):
self.show_error(_('Payment failed') + '\n\n' + reason)
def read_invoice(self):

View file

@ -787,7 +787,7 @@ class Peer(Logger):
f'already in peer_state {chan.peer_state!r}')
return
chan.peer_state = PeerState.REESTABLISHING
util.trigger_callback('channel', chan)
util.trigger_callback('channel', self.lnworker.wallet, chan)
# BOLT-02: "A node [...] upon disconnection [...] MUST reverse any uncommitted updates sent by the other side"
chan.hm.discard_unsigned_remote_updates()
# ctns
@ -940,7 +940,7 @@ class Peer(Logger):
# checks done
if chan.is_funded() and chan.config[LOCAL].funding_locked_received:
self.mark_open(chan)
util.trigger_callback('channel', chan)
util.trigger_callback('channel', self.lnworker.wallet, chan)
# if we have sent a previous shutdown, it must be retransmitted (Bolt2)
if chan.get_state() == ChannelState.SHUTDOWN:
await self.send_shutdown(chan)
@ -1029,7 +1029,7 @@ class Peer(Logger):
return
assert chan.config[LOCAL].funding_locked_received
chan.set_state(ChannelState.OPEN)
util.trigger_callback('channel', chan)
util.trigger_callback('channel', self.lnworker.wallet, chan)
# peer may have sent us a channel update for the incoming direction previously
pending_channel_update = self.orphan_channel_updates.get(chan.short_channel_id)
if pending_channel_update:

View file

@ -480,7 +480,7 @@ class LNGossip(LNWorker):
class LNWallet(LNWorker):
lnwatcher: 'LNWalletWatcher'
lnwatcher: Optional['LNWalletWatcher']
def __init__(self, wallet: 'Abstract_Wallet', xprv):
Logger.__init__(self)
@ -488,6 +488,7 @@ class LNWallet(LNWorker):
self.db = wallet.db
self.config = wallet.config
LNWorker.__init__(self, xprv)
self.lnwatcher = None
self.features |= LnFeatures.OPTION_DATA_LOSS_PROTECT_REQ
self.features |= LnFeatures.OPTION_STATIC_REMOTEKEY_REQ
self.payments = self.db.get_dict('lightning_payments') # RHASH -> amount, direction, is_paid
@ -583,7 +584,7 @@ class LNWallet(LNWorker):
def peer_closed(self, peer):
for chan in self.channels_for_peer(peer.pubkey).values():
chan.peer_state = PeerState.DISCONNECTED
util.trigger_callback('channel', chan)
util.trigger_callback('channel', self.wallet, chan)
super().peer_closed(peer)
def get_settled_payments(self):
@ -716,14 +717,14 @@ class LNWallet(LNWorker):
def channel_state_changed(self, chan):
self.save_channel(chan)
util.trigger_callback('channel', chan)
util.trigger_callback('channel', self.wallet, chan)
def save_channel(self, chan):
assert type(chan) is Channel
if chan.config[REMOTE].next_per_commitment_point == chan.config[REMOTE].current_per_commitment_point:
raise Exception("Tried to save channel with next_point == current_point, this should not happen")
self.wallet.save_db()
util.trigger_callback('channel', chan)
util.trigger_callback('channel', self.wallet, chan)
def channel_by_txo(self, txo):
for chan in self.channels.values():
@ -869,9 +870,9 @@ class LNWallet(LNWorker):
reason = _('Failed after {} attempts').format(attempts)
util.trigger_callback('invoice_status', key)
if success:
util.trigger_callback('payment_succeeded', key)
util.trigger_callback('payment_succeeded', self.wallet, key)
else:
util.trigger_callback('payment_failed', key, reason)
util.trigger_callback('payment_failed', self.wallet, key, reason)
return success, log
async def _pay_to_route(self, route: LNPaymentRoute, lnaddr: LnAddr) -> PaymentAttemptLog:
@ -1193,7 +1194,7 @@ class LNWallet(LNWorker):
chan.logger.info('received unexpected payment_failed, probably from previous session')
key = payment_hash.hex()
util.trigger_callback('invoice_status', key)
util.trigger_callback('payment_failed', key, '')
util.trigger_callback('payment_failed', self.wallet, key, '')
util.trigger_callback('ln_payment_failed', payment_hash, chan.channel_id)
def payment_sent(self, chan, payment_hash: bytes):
@ -1209,7 +1210,7 @@ class LNWallet(LNWorker):
chan.logger.info('received unexpected payment_sent, probably from previous session')
key = payment_hash.hex()
util.trigger_callback('invoice_status', key)
util.trigger_callback('payment_succeeded', key)
util.trigger_callback('payment_succeeded', self.wallet, key)
util.trigger_callback('ln_payment_completed', payment_hash, chan.channel_id)
def payment_received(self, chan, payment_hash: bytes):
@ -1405,6 +1406,8 @@ class LNWallet(LNWorker):
class LNBackups(Logger):
lnwatcher: Optional['LNWalletWatcher']
def __init__(self, wallet: 'Abstract_Wallet'):
Logger.__init__(self)
self.features = LnFeatures(0)
@ -1414,6 +1417,7 @@ class LNBackups(Logger):
self.lock = threading.RLock()
self.wallet = wallet
self.db = wallet.db
self.lnwatcher = None
self.channel_backups = {}
for channel_id, cb in random_shuffled_copy(self.db.get_dict("channel_backups").items()):
self.channel_backups[bfh(channel_id)] = ChannelBackup(cb, sweep_address=self.sweep_address, lnworker=self)
@ -1424,7 +1428,7 @@ class LNBackups(Logger):
return self.wallet.get_new_sweep_address_for_channel()
def channel_state_changed(self, chan):
util.trigger_callback('channel', chan)
util.trigger_callback('channel', self.wallet, chan)
def peer_closed(self, chan):
pass