lnpeer: await init in main_loop
Because `LNPeer.initialized` was awaited in
`LNPeer._query_gossip()` instead of the main loop the other tasks got
spawned concurrently and each task on its own has to wait for the
initialization. In `LNPeer._send_own_gossip()` this was missing, instead
there is a fixed 10 sec sleep. If the connection was not initialized but
the 10 sec are exceeded `_send_own_gossip()` tries to send gossip and
causes this exception as the `LNTransport` is not ready:
```
2.13 | E | lnpeer.Peer.[LNWallet, 0288fa27c0-bc1900c8] | Exception in main_loop: AttributeError("'LNTransport' object has no attribute 'sk'")
Traceback (most recent call last):
File "/home/user/code/electrum-fork/electrum/util.py", line 1232, in wrapper
return await func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/code/electrum-fork/electrum/lnpeer.py", line 511, in wrapper_func
return await func(self, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/user/code/electrum-fork/electrum/lnpeer.py", line 525, in main_loop
async with self.taskgroup as group:
^^^^^^^^^^^^^^
File "/home/user/code/electrum-fork/env/lib/python3.14/site-packages/aiorpcx/curio.py", line 304, in __aexit__
await self.join()
File "/home/user/code/electrum-fork/electrum/util.py", line 1420, in join
task.result()
~~~~~~~~~~~^^
File "/home/user/code/electrum-fork/electrum/lnpeer.py", line 573, in _send_own_gossip
self.send_node_announcement(alias, color)
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
File "/home/user/code/electrum-fork/electrum/lnpeer.py", line 1830, in send_node_announcement
self.transport.send_bytes(raw_msg)
~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^
File "/home/user/code/electrum-fork/electrum/lntransport.py", line 225, in send_bytes
lc = aead_encrypt(self.sk, self.sn(), b'', l)
^^^^^^^
AttributeError: 'LNTransport' object has no attribute 'sk'. Did you mean: 'sn'?
```
By awaiting the initialization directly in the `main_loop` it is more
clear that the task getting spawned subsequently depend on the transport
being available and separates the initialization more clearly these
other functions.
This commit is contained in:
@@ -523,7 +523,11 @@ class Peer(Logger, EventListener):
|
||||
@handle_disconnect
|
||||
async def main_loop(self):
|
||||
async with self.taskgroup as group:
|
||||
await group.spawn(self._message_loop())
|
||||
await group.spawn(self._message_loop()) # initializes connection
|
||||
try:
|
||||
await util.wait_for2(self.initialized, LN_P2P_NETWORK_TIMEOUT)
|
||||
except Exception as e:
|
||||
raise GracefulDisconnect(f"Failed to initialize: {e!r}") from e
|
||||
await group.spawn(self._query_gossip())
|
||||
await group.spawn(self._process_gossip())
|
||||
await group.spawn(self._send_own_gossip())
|
||||
@@ -563,6 +567,7 @@ class Peer(Logger, EventListener):
|
||||
async def _send_own_gossip(self):
|
||||
if self.lnworker == self.lnworker.network.lngossip:
|
||||
return
|
||||
assert self.is_initialized()
|
||||
await asyncio.sleep(10)
|
||||
while True:
|
||||
public_channels = [chan for chan in self.lnworker.channels.values() if chan.is_public()]
|
||||
@@ -583,6 +588,7 @@ class Peer(Logger, EventListener):
|
||||
return False
|
||||
|
||||
async def _forward_gossip(self):
|
||||
assert self.is_initialized()
|
||||
if not self._should_forward_gossip():
|
||||
return
|
||||
|
||||
@@ -632,10 +638,7 @@ class Peer(Logger, EventListener):
|
||||
return amount_sent
|
||||
|
||||
async def _query_gossip(self):
|
||||
try:
|
||||
await util.wait_for2(self.initialized, LN_P2P_NETWORK_TIMEOUT)
|
||||
except Exception as e:
|
||||
raise GracefulDisconnect(f"Failed to initialize: {e!r}") from e
|
||||
assert self.is_initialized()
|
||||
if self.lnworker == self.lnworker.network.lngossip:
|
||||
if not self.their_features.supports(LnFeatures.GOSSIP_QUERIES_OPT):
|
||||
raise GracefulDisconnect("remote does not support gossip_queries, which we need")
|
||||
|
||||
Reference in New Issue
Block a user