URI: 
       tfilter callbacks to wallet: channel, payment_succeeded, payment_failed - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 4c7095668778c1d3f98a2bf9669a5aa4eeeede87
   DIR parent 625f985f22a6b09bb106159b400843df491a3833
  HTML 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:
         M electrum/gui/kivy/main_window.py    |       6 +++---
         M electrum/gui/qt/channel_details.py  |      14 +++++++++-----
         M electrum/gui/qt/channels_list.py    |      10 ++++++----
         M electrum/gui/qt/main_window.py      |      22 +++++++++++++++-------
         M electrum/lnpeer.py                  |       6 +++---
         M electrum/lnworker.py                |      22 +++++++++++++---------
       
       6 files changed, 49 insertions(+), 31 deletions(-)
       ---
   DIR diff --git a/electrum/gui/kivy/main_window.py b/electrum/gui/kivy/main_window.py
       t@@ -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):
       t@@ -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())
        
   DIR diff --git a/electrum/gui/qt/channel_details.py b/electrum/gui/qt/channel_details.py
       t@@ -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
        
       t@@ -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()
        
       t@@ -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):
       t@@ -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)
        
   DIR diff --git a/electrum/gui/qt/channels_list.py b/electrum/gui/qt/channels_list.py
       t@@ -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):
       t@@ -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()):
   DIR diff --git a/electrum/gui/qt/main_window.py b/electrum/gui/qt/main_window.py
       t@@ -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':
       t@@ -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):
   DIR diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py
       t@@ -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
       t@@ -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)
       t@@ -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:
   DIR diff --git a/electrum/lnworker.py b/electrum/lnworker.py
       t@@ -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)
       t@@ -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
       t@@ -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):
       t@@ -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():
       t@@ -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:
       t@@ -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):
       t@@ -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):
       t@@ -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)
       t@@ -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)
       t@@ -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