URI: 
       tChannelDB: fix get_recent_peers - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 5ac01ff6ae9e82a18df0be6297ea9e81dcb239ad
   DIR parent 968eeebdc07b692a4ae6ffdc06875fdfd3c78994
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Mon,  2 Mar 2020 02:19:13 +0100
       
       ChannelDB: fix get_recent_peers
       
       Diffstat:
         M electrum/channel_db.py              |      23 ++++++++++++++++-------
       
       1 file changed, 16 insertions(+), 7 deletions(-)
       ---
   DIR diff --git a/electrum/channel_db.py b/electrum/channel_db.py
       t@@ -262,6 +262,7 @@ class ChannelDB(SqlDB):
                # node_id -> (host, port, ts)
                self._addresses = defaultdict(set)  # type: Dict[bytes, Set[Tuple[str, int, int]]]
                self._channels_for_node = defaultdict(set)  # type: Dict[bytes, Set[ShortChannelID]]
       +        self._recent_peers = []  # type: List[bytes]  # list of node_ids
        
                self.data_loaded = asyncio.Event()
                self.network = network # only for callback
       t@@ -282,6 +283,11 @@ class ChannelDB(SqlDB):
                node_id = peer.pubkey
                with self.lock:
                    self._addresses[node_id].add((peer.host, peer.port, now))
       +            # list is ordered
       +            if node_id in self._recent_peers:
       +                self._recent_peers.remove(node_id)
       +            self._recent_peers.insert(0, node_id)
       +            self._recent_peers = self._recent_peers[:self.NUM_MAX_RECENT_PEERS]
                self.save_node_address(node_id, peer, now)
        
            def get_200_randomly_sorted_nodes_not_in(self, node_ids):
       t@@ -302,14 +308,10 @@ class ChannelDB(SqlDB):
        
            def get_recent_peers(self):
                assert self.data_loaded.is_set(), "channelDB load_data did not finish yet!"
       -        # FIXME this does not reliably return "recent" peers...
       -        #       Also, the list() cast over the whole dict (thousands of elements),
       -        #       is really inefficient.
                with self.lock:
       -            _addresses_keys = list(self._addresses.keys())
       -        r = [self.get_last_good_address(node_id)
       -             for node_id in _addresses_keys[-self.NUM_MAX_RECENT_PEERS:]]
       -        return list(reversed(r))
       +            ret = [self.get_last_good_address(node_id)
       +                   for node_id in self._recent_peers]
       +            return ret
        
            # note: currently channel announcements are trusted by default (trusted=True);
            #       they are not verified. Verifying them would make the gossip sync
       t@@ -573,6 +575,13 @@ class ChannelDB(SqlDB):
                for x in c:
                    node_id, host, port, timestamp = x
                    self._addresses[node_id].add((str(host), int(port), int(timestamp or 0)))
       +        def newest_ts_for_node_id(node_id):
       +            newest_ts = 0
       +            for host, port, ts in self._addresses[node_id]:
       +                newest_ts = max(newest_ts, ts)
       +            return newest_ts
       +        sorted_node_ids = sorted(self._addresses.keys(), key=newest_ts_for_node_id, reverse=True)
       +        self._recent_peers = sorted_node_ids[:self.NUM_MAX_RECENT_PEERS]
                c.execute("""SELECT * FROM channel_info""")
                for short_channel_id, msg in c:
                    ci = ChannelInfo.from_raw_msg(msg)