URI: 
       tln chan verifier: fix code rot - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 24ebc77d76cb342502a8443c4edc2a1feff8f067
   DIR parent 0ab88b821c702b6a424bae8508ce1a9e30b7fa59
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Tue, 10 Dec 2019 01:14:38 +0100
       
       ln chan verifier: fix code rot
       
       Diffstat:
         M electrum/channel_db.py              |      30 ++++++++++++++++++++++--------
         M electrum/interface.py               |       9 ++++-----
         M electrum/lnverifier.py              |      22 ++++++++++------------
       
       3 files changed, 36 insertions(+), 25 deletions(-)
       ---
   DIR diff --git a/electrum/channel_db.py b/electrum/channel_db.py
       t@@ -295,7 +295,12 @@ class ChannelDB(SqlDB):
                     for node_id in list(self._addresses.keys())[-self.NUM_MAX_RECENT_PEERS:]]
                return list(reversed(r))
        
       -    def add_channel_announcement(self, msg_payloads, trusted=True):
       +    # note: currently channel announcements are trusted by default (trusted=True);
       +    #       they are not verified. Verifying them would make the gossip sync
       +    #       even slower; especially as servers will start throttling us.
       +    #       It would probably put significant strain on servers if all clients
       +    #       verified the complete gossip.
       +    def add_channel_announcement(self, msg_payloads, *, trusted=True):
                if type(msg_payloads) is dict:
                    msg_payloads = [msg_payloads]
                added = 0
       t@@ -311,17 +316,26 @@ class ChannelDB(SqlDB):
                    except UnknownEvenFeatureBits:
                        self.logger.info("unknown feature bits")
                        continue
       -            added += 1
       -            self._channels[short_channel_id] = channel_info
       -            self._channels_for_node[channel_info.node1_id].add(channel_info.short_channel_id)
       -            self._channels_for_node[channel_info.node2_id].add(channel_info.short_channel_id)
       -            self.save_channel(channel_info)
       -            if not trusted:
       -                self.ca_verifier.add_new_channel_info(channel_info.short_channel_id, msg)
       +            if trusted:
       +                added += 1
       +                self.add_verified_channel_info(msg)
       +            else:
       +                added += self.ca_verifier.add_new_channel_info(short_channel_id, msg)
        
                self.update_counts()
                self.logger.debug('add_channel_announcement: %d/%d'%(added, len(msg_payloads)))
        
       +    def add_verified_channel_info(self, msg: dict, *, capacity_sat: int = None) -> None:
       +        try:
       +            channel_info = ChannelInfo.from_msg(msg)
       +        except UnknownEvenFeatureBits:
       +            return
       +        channel_info = channel_info._replace(capacity_sat=capacity_sat)
       +        self._channels[channel_info.short_channel_id] = channel_info
       +        self._channels_for_node[channel_info.node1_id].add(channel_info.short_channel_id)
       +        self._channels_for_node[channel_info.node2_id].add(channel_info.short_channel_id)
       +        self.save_channel(channel_info)
       +
            def print_change(self, old_policy: Policy, new_policy: Policy):
                # print what changed between policies
                if old_policy.cltv_expiry_delta != new_policy.cltv_expiry_delta:
   DIR diff --git a/electrum/interface.py b/electrum/interface.py
       t@@ -29,7 +29,7 @@ import sys
        import traceback
        import asyncio
        import socket
       -from typing import Tuple, Union, List, TYPE_CHECKING, Optional
       +from typing import Tuple, Union, List, TYPE_CHECKING, Optional, Set
        from collections import defaultdict
        from ipaddress import IPv4Network, IPv6Network, ip_address, IPv6Address
        import itertools
       t@@ -233,7 +233,7 @@ class Interface(Logger):
                assert network.config.path
                self.cert_path = _get_cert_path_for_host(config=network.config, host=self.host)
                self.blockchain = None  # type: Optional[Blockchain]
       -        self._requested_chunks = set()
       +        self._requested_chunks = set()  # type: Set[int]
                self.network = network
                self._set_proxy(proxy)
                self.session = None  # type: Optional[NotificationSession]
       t@@ -431,7 +431,7 @@ class Interface(Logger):
                res = await self.session.send_request('blockchain.block.header', [height], timeout=timeout)
                return blockchain.deserialize_header(bytes.fromhex(res), height)
        
       -    async def request_chunk(self, height, tip=None, *, can_return_early=False):
       +    async def request_chunk(self, height: int, tip=None, *, can_return_early=False):
                index = height // 2016
                if can_return_early and index in self._requested_chunks:
                    return
       t@@ -444,8 +444,7 @@ class Interface(Logger):
                    self._requested_chunks.add(index)
                    res = await self.session.send_request('blockchain.block.headers', [index * 2016, size])
                finally:
       -            try: self._requested_chunks.remove(index)
       -            except KeyError: pass
       +            self._requested_chunks.discard(index)
                conn = self.blockchain.connect_chunk(index, res['hex'])
                if not conn:
                    return conn, 0
   DIR diff --git a/electrum/lnverifier.py b/electrum/lnverifier.py
       t@@ -55,7 +55,7 @@ class LNChannelVerifier(NetworkJobOnDefaultServer):
            def __init__(self, network: 'Network', channel_db: 'ChannelDB'):
                self.channel_db = channel_db
                self.lock = threading.Lock()
       -        self.unverified_channel_info = {}  # type: Dict[ShortChannelID, dict]  # scid -> msg_payload
       +        self.unverified_channel_info = {}  # type: Dict[ShortChannelID, dict]  # scid -> msg_dict
                # channel announcements that seem to be invalid:
                self.blacklist = set()  # type: Set[ShortChannelID]
                NetworkJobOnDefaultServer.__init__(self, network)
       t@@ -65,13 +65,14 @@ class LNChannelVerifier(NetworkJobOnDefaultServer):
                self.started_verifying_channel = set()  # type: Set[ShortChannelID]
        
            # TODO make async; and rm self.lock completely
       -    def add_new_channel_info(self, short_channel_id: ShortChannelID, msg_payload):
       +    def add_new_channel_info(self, short_channel_id: ShortChannelID, msg: dict) -> bool:
                if short_channel_id in self.unverified_channel_info:
       -            return
       +            return False
                if short_channel_id in self.blacklist:
       -            return
       +            return False
                with self.lock:
       -            self.unverified_channel_info[short_channel_id] = msg_payload
       +            self.unverified_channel_info[short_channel_id] = msg
       +            return True
        
            async def _start_tasks(self):
                async with self.group as group:
       t@@ -146,10 +147,8 @@ class LNChannelVerifier(NetworkJobOnDefaultServer):
                    self.logger.info(f"received tx does not match expected txid ({tx_hash} != {tx.txid()})")
                    return
                # check funding output
       -        msg_payload = self.unverified_channel_info[short_channel_id]
       -        msg_type, chan_ann = decode_msg(msg_payload)
       -        assert msg_type == 'channel_announcement'
       -        redeem_script = funding_output_script_from_keys(chan_ann['bitcoin_key_1'], chan_ann['bitcoin_key_2'])
       +        chan_ann_msg = self.unverified_channel_info[short_channel_id]
       +        redeem_script = funding_output_script_from_keys(chan_ann_msg['bitcoin_key_1'], chan_ann_msg['bitcoin_key_2'])
                expected_address = bitcoin.redeem_script_to_address('p2wsh', redeem_script)
                try:
                    actual_output = tx.outputs()[short_channel_id.output_index]
       t@@ -162,14 +161,13 @@ class LNChannelVerifier(NetworkJobOnDefaultServer):
                    self._remove_channel_from_unverified_db(short_channel_id)
                    return
                # put channel into channel DB
       -        self.channel_db.add_verified_channel_info(short_channel_id, actual_output.value)
       +        self.channel_db.add_verified_channel_info(chan_ann_msg, capacity_sat=actual_output.value)
                self._remove_channel_from_unverified_db(short_channel_id)
        
            def _remove_channel_from_unverified_db(self, short_channel_id: ShortChannelID):
                with self.lock:
                    self.unverified_channel_info.pop(short_channel_id, None)
       -        try: self.started_verifying_channel.remove(short_channel_id)
       -        except KeyError: pass
       +        self.started_verifying_channel.discard(short_channel_id)
        
            def _blacklist_short_channel_id(self, short_channel_id: ShortChannelID) -> None:
                self.blacklist.add(short_channel_id)