commit 4c7095668778c1d3f98a2bf9669a5aa4eeeede87
parent 625f985f22a6b09bb106159b400843df491a3833
Author: SomberNight <somber.night@protonmail.com>
Date: Fri, 19 Jun 2020 04:11:35 +0200
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)
Diffstat:
6 files changed, 49 insertions(+), 31 deletions(-)
diff --git a/electrum/gui/kivy/main_window.py b/electrum/gui/kivy/main_window.py
@@ -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())
diff --git a/electrum/gui/qt/channel_details.py b/electrum/gui/qt/channel_details.py
@@ -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)
diff --git a/electrum/gui/qt/channels_list.py b/electrum/gui/qt/channels_list.py
@@ -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()):
diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
@@ -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):
diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
@@ -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:
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
@@ -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