diff --git a/electrum/lnchannel.py b/electrum/lnchannel.py index bb8a81b76..18d4512c6 100644 --- a/electrum/lnchannel.py +++ b/electrum/lnchannel.py @@ -59,7 +59,7 @@ from .lnhtlc import HTLCManager from .lnmsg import encode_msg, decode_msg from .address_synchronizer import TX_HEIGHT_LOCAL from .lnutil import CHANNEL_OPENING_TIMEOUT -from .lnutil import ChannelBackupStorage, ImportedChannelBackupStorage +from .lnutil import ChannelBackupStorage, ImportedChannelBackupStorage, OnchainChannelBackupStorage from .lnutil import format_short_channel_id if TYPE_CHECKING: @@ -148,7 +148,7 @@ class AbstractChannel(Logger, ABC): _fallback_sweep_address: str channel_id: bytes funding_outpoint: Outpoint - node_id: bytes + node_id: bytes # note that it might not be the full 33 bytes; for OCB it is only the prefix _state: ChannelState def set_short_channel_id(self, short_id: ShortChannelID) -> None: @@ -391,6 +391,11 @@ class AbstractChannel(Logger, ABC): def is_static_remotekey_enabled(self) -> bool: pass + @abstractmethod + def get_local_pubkey(self) -> bytes: + """Returns our node ID.""" + pass + class ChannelBackup(AbstractChannel): """ @@ -513,6 +518,14 @@ class ChannelBackup(AbstractChannel): # their local config is not static) return False + def get_local_pubkey(self) -> bytes: + cb = self.cb + assert isinstance(cb, ChannelBackupStorage) + if isinstance(cb, ImportedChannelBackupStorage): + return ecc.ECPrivkey(cb.privkey).get_public_key_bytes(compressed=True) + if isinstance(cb, OnchainChannelBackupStorage): + return self.lnworker.node_keypair.pubkey + raise NotImplementedError(f"unexpected cb type: {type(cb)}") class Channel(AbstractChannel): diff --git a/electrum/lnrater.py b/electrum/lnrater.py index 7ffb11013..31db6b822 100644 --- a/electrum/lnrater.py +++ b/electrum/lnrater.py @@ -243,6 +243,9 @@ class LNRater(Logger): node_keys = list(self._node_stats.keys()) node_ratings = list(self._node_ratings.values()) channel_peers = self.lnworker.channel_peers() + channel_backup_peers = [ + cb.node_id for cb in self.lnworker.channel_backups.values() + if (not cb.is_closed() and cb.get_local_pubkey() == self.lnworker.node_keypair.pubkey)] node_info: Optional["NodeInfo"] = None while True: @@ -258,8 +261,12 @@ class LNRater(Logger): continue # don't want to connect to nodes we are already connected to - if pk not in channel_peers: - break + if pk in channel_peers: + continue + # don't want to connect to nodes we already have a channel with on another device + if any(pk.startswith(cb_peer_nodeid) for cb_peer_nodeid in channel_backup_peers): + continue + break alias = node_info.alias if node_info else 'unknown node alias' self.logger.info(