From edf186da0d1414b444514211898344a70117a2c7 Mon Sep 17 00:00:00 2001 From: SomberNight Date: Thu, 5 Sep 2019 18:32:45 +0200 Subject: [PATCH] channeldb.load_data: attempt at fixing race closes #5525 --- electrum/channel_db.py | 4 ++++ electrum/lnpeer.py | 1 + electrum/lnworker.py | 1 + 3 files changed, 6 insertions(+) diff --git a/electrum/channel_db.py b/electrum/channel_db.py index e9744dcfc..7e9639e0b 100644 --- a/electrum/channel_db.py +++ b/electrum/channel_db.py @@ -30,6 +30,7 @@ from collections import defaultdict from typing import Sequence, List, Tuple, Optional, Dict, NamedTuple, TYPE_CHECKING, Set import binascii import base64 +import asyncio from .sql_db import SqlDB, sql @@ -250,6 +251,7 @@ class ChannelDB(SqlDB): self._nodes = {} self._addresses = defaultdict(set) self._channels_for_node = defaultdict(set) + self.data_loaded = asyncio.Event() def update_counts(self): self.num_channels = len(self._channels) @@ -278,6 +280,7 @@ class ChannelDB(SqlDB): return LNPeerAddr(host, port, node_id) def get_recent_peers(self): + assert self.data_loaded.is_set(), "channelDB load_data did not finish yet!" r = [self.get_last_good_address(x) for x in self._addresses.keys()] r = r[-self.NUM_MAX_RECENT_PEERS:] return r @@ -546,6 +549,7 @@ class ChannelDB(SqlDB): self.logger.info(f'load data {len(self._channels)} {len(self._policies)} {len(self._channels_for_node)}') self.update_counts() self.count_incomplete_channels() + self.data_loaded.set() def count_incomplete_channels(self): out = set() diff --git a/electrum/lnpeer.py b/electrum/lnpeer.py index ad5d6fff5..4c7e39310 100644 --- a/electrum/lnpeer.py +++ b/electrum/lnpeer.py @@ -241,6 +241,7 @@ class Peer(Logger): await group.spawn(self.process_gossip()) async def process_gossip(self): + await self.channel_db.data_loaded.wait() # verify in peer's TaskGroup so that we fail the connection while True: await asyncio.sleep(5) diff --git a/electrum/lnworker.py b/electrum/lnworker.py index d5c5d4f3a..724f80edf 100644 --- a/electrum/lnworker.py +++ b/electrum/lnworker.py @@ -154,6 +154,7 @@ class LNWorker(Logger): async def _get_next_peers_to_try(self) -> Sequence[LNPeerAddr]: now = time.time() + await self.channel_db.data_loaded.wait() recent_peers = self.channel_db.get_recent_peers() # maintenance for last tried times # due to this, below we can just test membership in _last_tried_peer