From 36a6fd63112033c2db0c15c73ff5cb6330ae3ae8 Mon Sep 17 00:00:00 2001 From: ThomasV Date: Fri, 8 Jul 2022 16:44:03 +0200 Subject: [PATCH] request_force_close_from_backup: - for an onchain backups, if the channel is with a hardcoded trampoline, try first without gossip DB. - for imported backups, fallback to gossip DB if we fail to connect with the provided network address. --- electrum/lnworker.py | 57 ++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/electrum/lnworker.py b/electrum/lnworker.py index 7f8c02029..84bc671ab 100644 --- a/electrum/lnworker.py +++ b/electrum/lnworker.py @@ -2526,29 +2526,46 @@ class LNWallet(LNWorker): node_id = cb.node_id privkey = cb.privkey addresses = [(cb.host, cb.port, 0)] - # TODO also try network addresses from gossip db (as it might have changed) else: assert isinstance(cb, OnchainChannelBackupStorage) - if not self.channel_db: - raise Exception('Enable gossip first') - node_id = self.network.channel_db.get_node_by_prefix(cb.node_id_prefix) privkey = self.node_keypair.privkey - addresses = self.network.channel_db.get_node_addresses(node_id) - if not addresses: - raise Exception('Peer not found in gossip database') - for host, port, timestamp in addresses: - peer_addr = LNPeerAddr(host, port, node_id) - transport = LNTransport(privkey, peer_addr, proxy=self.network.proxy) - peer = Peer(self, node_id, transport, is_channel_backup=True) - try: - async with OldTaskGroup(wait=any) as group: - await group.spawn(peer._message_loop()) - await group.spawn(peer.request_force_close(channel_id)) - return - except Exception as e: - self.logger.info(f'failed to connect {host} {e}') - continue - else: + for pubkey, peer_addr in trampolines_by_id().items(): + if pubkey.startswith(cb.node_id_prefix): + node_id = pubkey + addresses = [(peer_addr.host, peer_addr.port, 0)] + break + else: + # we will try with gossip (see below) + addresses = [] + + async def _request_fclose(addresses): + for host, port, timestamp in addresses: + peer_addr = LNPeerAddr(host, port, node_id) + transport = LNTransport(privkey, peer_addr, proxy=self.network.proxy) + peer = Peer(self, node_id, transport, is_channel_backup=True) + try: + async with OldTaskGroup(wait=any) as group: + await group.spawn(peer._message_loop()) + await group.spawn(peer.request_force_close(channel_id)) + return True + except Exception as e: + self.logger.info(f'failed to connect {host} {e}') + continue + else: + return False + # try first without gossip db + success = await _request_fclose(addresses) + if success: + return + # try with gossip db + if not self.channel_db: + raise Exception(_('Please enable gossip')) + node_id = self.network.channel_db.get_node_by_prefix(cb.node_id_prefix) + addresses_from_gossip = self.network.channel_db.get_node_addresses(node_id) + if not addresses_from_gossip: + raise Exception('Peer not found in gossip database') + success = await _request_fclose(addresses_from_gossip) + if not success: raise Exception('failed to connect') def maybe_add_backup_from_tx(self, tx):