diff --git a/electrum/commands.py b/electrum/commands.py index 5528143e..6adb02aa 100644 --- a/electrum/commands.py +++ b/electrum/commands.py @@ -698,6 +698,12 @@ class Commands: lightning.lightningCall(self.wallet.network.lightningrpc, lcmd)(*lightningargs) return q.get(block=True, timeout=600) + @command("wn") + def lnbase_test(self): + if not self.network.config.get("lnbase", False): + return "You need to pass --lnbase to the daemon starting command to run the lnbase test" + return self.wallet.lnworker.blocking_test_run() + param_descriptions = { 'privkey': 'Private key. Type \'?\' to get a prompt.', 'destination': 'Bitcoin address, contact or alias', diff --git a/electrum/network.py b/electrum/network.py index 680f19a9..f6b09011 100644 --- a/electrum/network.py +++ b/electrum/network.py @@ -269,6 +269,7 @@ class Network(util.DaemonThread): self.socket_queue = queue.Queue() self.start_network(deserialize_server(self.default_server)[2], deserialize_proxy(self.config.get('proxy'))) + self.asyncio_loop = loop = asyncio.new_event_loop() def with_interface_lock(func): def func_wrapper(self, *args, **kwargs): @@ -1089,17 +1090,16 @@ class Network(util.DaemonThread): b.update_size() def run(self): + asyncio.set_event_loop(self.asyncio_loop) self.init_headers_file() self.futures = [] - self.asyncio_loop = loop = asyncio.new_event_loop() networkAndWalletLock = QLock() + self.lightninglock.acquire() def asyncioThread(): - asyncio.set_event_loop(loop) if self.config.get("lightning", False): - self.lightninglock.acquire() if self.lightningrpc is not None and self.lightningworker is not None: task = asyncio.ensure_future(asyncio.gather(self.lightningrpc.run(networkAndWalletLock), self.lightningworker.run(networkAndWalletLock))) - loop.run_forever() + self.asyncio_loop.run_forever() threading.Thread(target=asyncioThread).start() networkAndWalletLock.acquire() @@ -1113,10 +1113,10 @@ class Network(util.DaemonThread): networkAndWalletLock.acquire() # cancel tasks [f.cancel() for f in self.futures] - loop.stop() - if loop.is_running(): time.sleep(0.1) + self.asyncio_loop.stop() + if self.asyncio_loop.is_running(): time.sleep(0.1) try: - loop.close() + self.asyncio_loop.close() except: pass self.stop_network() diff --git a/electrum/wallet.py b/electrum/wallet.py index f3e63e72..7d725b9c 100644 --- a/electrum/wallet.py +++ b/electrum/wallet.py @@ -26,7 +26,7 @@ # - Standard_Wallet: one keystore, P2PKH # - Multisig_Wallet: several keystores, P2SH - +import asyncio import os import threading import random @@ -1306,8 +1306,9 @@ class Abstract_Wallet(PrintError): if network.config.get("lightning", False): network.lightningworker = LightningWorker(self, network, network.config) network.lightningrpc = LightningRPC() - network.lightninglock.release() + network.lightninglock.release() if network.config.get("lnbase", False): + asyncio.set_event_loop(network.asyncio_loop) from .lnbase import LNWorker self.lnworker = LNWorker(self, network) else: diff --git a/lib/lnbase.py b/lib/lnbase.py index 079a08db..4af0b74f 100644 --- a/lib/lnbase.py +++ b/lib/lnbase.py @@ -331,8 +331,8 @@ class Peer(PrintError): #def open_channel(self, funding_sat, push_msat): # self.send_message(gen_msg('open_channel', funding_satoshis=funding_sat, push_msat=push_msat)) - async def main_loop(self, loop): - self.reader, self.writer = await asyncio.open_connection(self.host, self.port, loop=loop) + async def main_loop(self): + self.reader, self.writer = await asyncio.open_connection(self.host, self.port) await self.handshake() # send init self.send_message(gen_msg("init", gflen=0, lflen=0)) @@ -350,7 +350,7 @@ class Peer(PrintError): self.print_error('closing lnbase') self.writer.close() - async def channel_establishment_flow(self): + async def channel_establishment_flow(self, wallet): await self.init_message_received_future pubkeys = get_unused_public_keys() temp_channel_id = os.urandom(32) @@ -359,11 +359,11 @@ class Peer(PrintError): self.send_message(msg) try: accept_channel = await self.temporary_channel_id_to_incoming_accept_channel[temp_channel_id] - except LightningError: - return finally: del self.temporary_channel_id_to_incoming_accept_channel[temp_channel_id] + raise Exception("TODO: create funding transaction using wallet") + # replacement for lightningCall class LNWorker: @@ -371,19 +371,29 @@ class LNWorker: def __init__(self, wallet, network): self.wallet = wallet self.network = network - self.loop = network.asyncio_loop host, port, pubkey = ('ecdsa.net', '9735', '038370f0e7a03eded3e1d41dc081084a87f0afa1c5b22090b4f3abb391eb15d8ff') pubkey = binascii.unhexlify(pubkey) port = int(port) privkey = b"\x21"*32 + b"\x01" self.peer = Peer(privkey, host, port, pubkey) - self.network.futures.append(asyncio.run_coroutine_threadsafe(self.peer.main_loop(self.loop), self.loop)) + self.network.futures.append(asyncio.run_coroutine_threadsafe(self.peer.main_loop(), asyncio.get_event_loop())) def openchannel(self): # todo: get utxo from wallet # submit coro to asyncio main loop self.peer.open_channel() + def blocking_test_run(self): + start = time.time() + fut = asyncio.ensure_future(self._test()) + asyncio.get_event_loop().run_until_complete(fut) + fut.exception() + return "blocking test run took: " + str(time.time() - start) + + async def _test(self): + await self.peer.channel_establishment_flow(self.wallet) + + node_list = [ ('ecdsa.net', '9735', '038370f0e7a03eded3e1d41dc081084a87f0afa1c5b22090b4f3abb391eb15d8ff'), @@ -405,8 +415,5 @@ if __name__ == "__main__": port = int(port) privkey = b"\x21"*32 + b"\x01" peer = Peer(privkey, host, port, pubkey) - loop = asyncio.get_event_loop() - async def asynctest(): - await peer.channel_establishment_flow() - loop.run_until_complete(asyncio.gather(asynctest(), peer.main_loop(loop))) + loop.run_until_complete(peer.main_loop()) loop.close()