URI: 
       tfix lightning "init" msg assertion error - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit edc00b448f95fca71284ba65320164ea5aa67fc8
   DIR parent a6e3a244e80023ac3c42f691699b759908b22d51
  HTML Author: SomberNight <somber.night@protonmail.com>
       Date:   Sat, 15 Feb 2020 15:25:41 +0100
       
       fix lightning "init" msg assertion error
       
       closes #5962
       
       Diffstat:
         M electrum/lnmsg.py                   |      29 +++++++++++++++--------------
       
       1 file changed, 15 insertions(+), 14 deletions(-)
       ---
   DIR diff --git a/electrum/lnmsg.py b/electrum/lnmsg.py
       t@@ -44,12 +44,12 @@ def _eval_exp_with_ctx(exp, ctx: dict) -> int:
                return result
            return sum(_eval_length_term(x, ctx) for x in exp.split("+"))
        
       -def _make_handler(k: str, v: dict) -> Callable[[bytes], Tuple[str, dict]]:
       +def _make_handler(msg_name: str, v: dict) -> Callable[[bytes], Tuple[str, dict]]:
            """
            Generate a message handler function (taking bytes)
       -    for message type `k` with specification `v`
       +    for message type `msg_name` with specification `v`
        
       -    Check lib/lightning.json, `k` could be 'init',
       +    Check lib/lightning.json, `msg_name` could be 'init',
            and `v` could be
        
              { type: 16, payload: { 'gflen': ..., ... }, ... }
       t@@ -57,8 +57,8 @@ def _make_handler(k: str, v: dict) -> Callable[[bytes], Tuple[str, dict]]:
            Returns function taking bytes
            """
            def handler(data: bytes) -> Tuple[str, dict]:
       -        nonlocal k, v
       -        ma = {}
       +        nonlocal msg_name, v
       +        ma = {}  # map of field name -> field data; after parsing msg
                pos = 0
                for fieldname in v["payload"]:
                    poslenMap = v["payload"][fieldname]
       t@@ -69,8 +69,9 @@ def _make_handler(k: str, v: dict) -> Callable[[bytes], Tuple[str, dict]]:
                    length = _eval_exp_with_ctx(length, ma)
                    ma[fieldname] = data[pos:pos+length]
                    pos += length
       -        assert pos == len(data), (k, pos, len(data))
       -        return k, ma
       +        # BOLT-01: "MUST ignore any additional data within a message beyond the length that it expects for that type."
       +        assert pos <= len(data), (msg_name, pos, len(data))
       +        return msg_name, ma
            return handler
        
        class LNSerializer:
       t@@ -80,12 +81,12 @@ class LNSerializer:
                with open(path) as f:
                    structured = json.loads(f.read(), object_pairs_hook=OrderedDict)
        
       -        for k in structured:
       -            v = structured[k]
       +        for msg_name in structured:
       +            v = structured[msg_name]
                    # these message types are skipped since their types collide
                    # (for example with pong, which also uses type=19)
                    # we don't need them yet
       -            if k in ["final_incorrect_cltv_expiry", "final_incorrect_htlc_amount"]:
       +            if msg_name in ["final_incorrect_cltv_expiry", "final_incorrect_htlc_amount"]:
                        continue
                    if len(v["payload"]) == 0:
                        continue
       t@@ -95,11 +96,11 @@ class LNSerializer:
                        #print("skipping", k)
                        continue
                    byts = num.to_bytes(2, 'big')
       -            assert byts not in message_types, (byts, message_types[byts].__name__, k)
       +            assert byts not in message_types, (byts, message_types[byts].__name__, msg_name)
                    names = [x.__name__ for x in message_types.values()]
       -            assert k + "_handler" not in names, (k, names)
       -            message_types[byts] = _make_handler(k, v)
       -            message_types[byts].__name__ = k + "_handler"
       +            assert msg_name + "_handler" not in names, (msg_name, names)
       +            message_types[byts] = _make_handler(msg_name, v)
       +            message_types[byts].__name__ = msg_name + "_handler"
        
                assert message_types[b"\x00\x10"].__name__ == "init_handler"
                self.structured = structured