Browse Source

detect conflicting channel backups, add warning before channel creation

master
ThomasV 5 years ago
parent
commit
cd4df2fd85
  1. 13
      electrum/gui/kivy/uix/dialogs/lightning_open_channel.py
  2. 6
      electrum/gui/messages.py
  3. 4
      electrum/gui/qt/main_window.py
  4. 5
      electrum/lnrater.py
  5. 7
      electrum/lnworker.py

13
electrum/gui/kivy/uix/dialogs/lightning_open_channel.py

@ -15,6 +15,7 @@ from electrum.lnutil import ln_dummy_address, extract_nodeid
from .label_dialog import LabelDialog from .label_dialog import LabelDialog
from .confirm_tx_dialog import ConfirmTxDialog from .confirm_tx_dialog import ConfirmTxDialog
from .qr_dialog import QRDialog from .qr_dialog import QRDialog
from .question import Question
if TYPE_CHECKING: if TYPE_CHECKING:
from ...main_window import ElectrumWindow from ...main_window import ElectrumWindow
@ -179,6 +180,18 @@ class LightningOpenChannelDialog(Factory.Popup, Logger):
amount = '!' if self.is_max else self.app.get_amount(self.amount) amount = '!' if self.is_max else self.app.get_amount(self.amount)
self.dismiss() self.dismiss()
lnworker = self.app.wallet.lnworker lnworker = self.app.wallet.lnworker
node_id, rest = extract_nodeid(conn_str)
if lnworker.has_conflicting_backup_with(node_id):
msg = messages.MGS_CONFLICTING_BACKUP_INSTANCE
d = Question(msg, lambda x: self._open_channel(x, conn_str, amount))
d.open()
else:
self._open_channel(True, conn_str, amount)
def _open_channel(self, x, conn_str, amount):
if not x:
return
lnworker = self.app.wallet.lnworker
coins = self.app.wallet.get_spendable_coins(None, nonlocal_only=True) coins = self.app.wallet.get_spendable_coins(None, nonlocal_only=True)
node_id, rest = extract_nodeid(conn_str) node_id, rest = extract_nodeid(conn_str)
make_tx = lambda rbf: lnworker.mktx_for_open_channel( make_tx = lambda rbf: lnworker.mktx_for_open_channel(

6
electrum/gui/messages.py

@ -31,3 +31,9 @@ Lightning payments require finding a path through the Lightning Network. You may
Downloading the network gossip uses quite some bandwidth and storage, and is not recommended on mobile devices. If you use trampoline, you can only open channels with trampoline nodes. Downloading the network gossip uses quite some bandwidth and storage, and is not recommended on mobile devices. If you use trampoline, you can only open channels with trampoline nodes.
""" """
MGS_CONFLICTING_BACKUP_INSTANCE = """
Another instance of this wallet (same seed) has an open channel with the same remote node. If you create this channel, you will not be able to use both wallets at the same time.
Are you sure?
"""

4
electrum/gui/qt/main_window.py

@ -1813,6 +1813,10 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
except ConnStringFormatError as e: except ConnStringFormatError as e:
self.show_error(str(e)) self.show_error(str(e))
return return
if self.wallet.lnworker.has_conflicting_backup_with(node_id):
msg = messages.MGS_CONFLICTING_BACKUP_INSTANCE
if not self.question(msg):
return
# use ConfirmTxDialog # use ConfirmTxDialog
# we need to know the fee before we broadcast, because the txid is required # we need to know the fee before we broadcast, because the txid is required
make_tx = self.mktx_for_open_channel(funding_sat=funding_sat, node_id=node_id) make_tx = self.mktx_for_open_channel(funding_sat=funding_sat, node_id=node_id)

5
electrum/lnrater.py

@ -243,9 +243,6 @@ class LNRater(Logger):
node_keys = list(self._node_stats.keys()) node_keys = list(self._node_stats.keys())
node_ratings = list(self._node_ratings.values()) node_ratings = list(self._node_ratings.values())
channel_peers = self.lnworker.channel_peers() 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 node_info: Optional["NodeInfo"] = None
while True: while True:
@ -264,7 +261,7 @@ class LNRater(Logger):
if pk in channel_peers: if pk in channel_peers:
continue continue
# don't want to connect to nodes we already have a channel with on another device # 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): if self.lnworker.has_conflicting_backup_with(pk):
continue continue
break break

7
electrum/lnworker.py

@ -2123,6 +2123,13 @@ class LNWallet(LNWorker):
util.trigger_callback('channels_updated', self.wallet) util.trigger_callback('channels_updated', self.wallet)
self.lnwatcher.add_channel(cb.funding_outpoint.to_str(), cb.get_funding_address()) self.lnwatcher.add_channel(cb.funding_outpoint.to_str(), cb.get_funding_address())
def has_conflicting_backup_with(self, remote_node_id: bytes):
""" Returns whether we have an active channel with this node on another device, using same local node id. """
channel_backup_peers = [
cb.node_id for cb in self.channel_backups.values()
if (not cb.is_closed() and cb.get_local_pubkey() == self.node_keypair.pubkey)]
return any(remote_node_id.startswith(cb_peer_nodeid) for cb_peer_nodeid in channel_backup_peers)
def remove_channel_backup(self, channel_id): def remove_channel_backup(self, channel_id):
chan = self.channel_backups[channel_id] chan = self.channel_backups[channel_id]
assert chan.can_be_deleted() assert chan.can_be_deleted()

Loading…
Cancel
Save