ln: do not add_peer in open_channel, but add_peer in gui when opening channel to unknown peer
This commit is contained in:
parent
0b7f4eb83c
commit
839c2fa46d
@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
from PyQt5.QtWidgets import *
|
||||
import concurrent.futures
|
||||
|
||||
from electrum.util import inv_dict, bh2u, bfh
|
||||
from electrum.i18n import _
|
||||
@ -84,7 +85,7 @@ class ChannelsList(MyTreeWidget):
|
||||
push_amt_inp.setAmount(0)
|
||||
h.addWidget(QLabel(_('Your Node ID')), 0, 0)
|
||||
h.addWidget(local_nodeid, 0, 1)
|
||||
h.addWidget(QLabel(_('Remote Node ID')), 1, 0)
|
||||
h.addWidget(QLabel(_('Remote Node ID or connection string')), 1, 0)
|
||||
h.addWidget(remote_nodeid, 1, 1)
|
||||
h.addWidget(QLabel('Local amount'), 2, 0)
|
||||
h.addWidget(local_amt_inp, 2, 1)
|
||||
@ -94,20 +95,80 @@ class ChannelsList(MyTreeWidget):
|
||||
vbox.addLayout(Buttons(CancelButton(d), OkButton(d)))
|
||||
if not d.exec_():
|
||||
return
|
||||
nodeid_hex = str(remote_nodeid.text())
|
||||
local_amt = local_amt_inp.get_amount()
|
||||
push_amt = push_amt_inp.get_amount()
|
||||
connect_contents = str(remote_nodeid.text())
|
||||
rest = None
|
||||
try:
|
||||
nodeid_hex, rest = connect_contents.split("@")
|
||||
except ValueError:
|
||||
nodeid_hex = connect_contents
|
||||
try:
|
||||
node_id = bfh(nodeid_hex)
|
||||
assert len(node_id) == 33
|
||||
except:
|
||||
self.parent.show_error(_('Invalid node ID'))
|
||||
self.parent.show_error(_('Invalid node ID, must be 33 bytes and hexadecimal'))
|
||||
return
|
||||
if node_id not in self.parent.wallet.lnworker.peers and node_id not in self.parent.network.lightning_nodes:
|
||||
|
||||
local_amt = local_amt_inp.get_amount()
|
||||
push_amt = push_amt_inp.get_amount()
|
||||
|
||||
if local_amt < 200000:
|
||||
self.parent.show_error(_('You must specify an decent amount (>=2 mBTC) for ' + \
|
||||
'the initial local balance of the channel.'))
|
||||
return
|
||||
|
||||
known = node_id in self.parent.network.lightning_nodes
|
||||
connected = node_id in self.parent.wallet.lnworker.peers
|
||||
|
||||
open_channel_info = (node_id, local_amt, push_amt)
|
||||
|
||||
if connected:
|
||||
peer = self.parent.wallet.lnworker.peers[node_id]
|
||||
if not peer.initialized.done():
|
||||
self.parent.show_error(_('Peer not initialized'))
|
||||
return
|
||||
self.gui_open_channel(None, peer, open_channel_info)
|
||||
return
|
||||
|
||||
if rest is not None: # perfer ip/port from input field
|
||||
try:
|
||||
host, port = rest.split(":")
|
||||
except ValueError:
|
||||
self.parent.show_error(_('Connection strings must be in <node_pubkey>@<host>:<port> format'))
|
||||
|
||||
elif known: # then use config file
|
||||
node = self.network.lightning_nodes.get(node_id)
|
||||
host, port = node['addresses'][0]
|
||||
else:
|
||||
self.parent.show_error(_('Unknown node:') + ' ' + nodeid_hex)
|
||||
return
|
||||
assert local_amt >= 200000
|
||||
assert local_amt >= push_amt
|
||||
self.main_window.protect(self.open_channel, (node_id, local_amt, push_amt))
|
||||
|
||||
try:
|
||||
int(port)
|
||||
except:
|
||||
self.parent.show_error(_('Port number must be decimal'))
|
||||
return
|
||||
|
||||
peer, coro = self.parent.wallet.lnworker.add_peer(host, port, node_id, aiosafe=False)
|
||||
q = QtCore.QTimer()
|
||||
q.singleShot(3000, lambda: self.gui_open_channel(coro, peer, open_channel_info))
|
||||
|
||||
def gui_open_channel(self, coro, peer, open_channel_info):
|
||||
if coro is not None:
|
||||
try:
|
||||
raise coro.exception(timeout=0)
|
||||
except concurrent.futures.TimeoutError:
|
||||
pass
|
||||
except concurrent.futures.CancelledError:
|
||||
print("Ignoring CancelledError, probably shutting down since main_loop cancelled...")
|
||||
return
|
||||
except Exception as e:
|
||||
self.parent.show_error(_('LN main loop threw:') + ' ' + str(e))
|
||||
return
|
||||
|
||||
if not peer.initialized.done():
|
||||
self.parent.show_error(_('Peer not initialized within 3 seconds'))
|
||||
return
|
||||
self.main_window.protect(self.open_channel, open_channel_info)
|
||||
|
||||
def open_channel(self, *args, **kwargs):
|
||||
self.parent.wallet.lnworker.open_channel(*args, **kwargs)
|
||||
|
||||
@ -479,6 +479,9 @@ class Peer(PrintError):
|
||||
|
||||
@aiosafe
|
||||
async def main_loop(self):
|
||||
return await self._main_loop()
|
||||
|
||||
async def _main_loop(self):
|
||||
self.reader, self.writer = await asyncio.open_connection(self.host, self.port)
|
||||
await self.handshake()
|
||||
# send init
|
||||
|
||||
@ -52,11 +52,16 @@ class LNWorker(PrintError):
|
||||
assert type(node_id) is bytes
|
||||
return {x: y for (x, y) in self.channels.items() if y.node_id == node_id}
|
||||
|
||||
def add_peer(self, host, port, node_id):
|
||||
def add_peer(self, host, port, node_id, aiosafe=True):
|
||||
peer = Peer(self, host, int(port), node_id, request_initial_sync=self.config.get("request_initial_sync", True))
|
||||
self.network.futures.append(asyncio.run_coroutine_threadsafe(peer.main_loop(), asyncio.get_event_loop()))
|
||||
if not aiosafe:
|
||||
method = peer._main_loop
|
||||
else:
|
||||
method = peer.main_loop
|
||||
coro = asyncio.run_coroutine_threadsafe(method(), asyncio.get_event_loop())
|
||||
self.network.futures.append(coro)
|
||||
self.peers[node_id] = peer
|
||||
self.lock = threading.Lock()
|
||||
return peer, coro
|
||||
|
||||
def save_channel(self, openchannel):
|
||||
assert type(openchannel) is HTLCStateMachine
|
||||
@ -115,15 +120,10 @@ class LNWorker(PrintError):
|
||||
conf = self.wallet.get_tx_height(chan.funding_outpoint.txid)[1]
|
||||
peer.on_network_update(chan, conf)
|
||||
|
||||
async def _open_channel_coroutine(self, node_id, amount_sat, push_sat, password):
|
||||
if node_id not in self.peers:
|
||||
node = self.network.lightning_nodes.get(node_id)
|
||||
if node is None:
|
||||
return "node not found, peers available are: " + str(self.network.lightning_nodes.keys())
|
||||
host, port = node['addresses'][0]
|
||||
self.add_peer(host, port, node_id)
|
||||
async def _open_channel_coroutine(self, node_id, local_amount_sat, push_sat, password):
|
||||
|
||||
peer = self.peers[node_id]
|
||||
openingchannel = await peer.channel_establishment_flow(self.wallet, self.config, password, amount_sat, push_sat * 1000, temp_channel_id=os.urandom(32))
|
||||
openingchannel = await peer.channel_establishment_flow(self.wallet, self.config, password, local_amount_sat + push_sat, push_sat * 1000, temp_channel_id=os.urandom(32))
|
||||
self.save_channel(openingchannel)
|
||||
self.on_channels_updated()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user