electrum

Electrum Bitcoin wallet
git clone https://git.parazyd.org/electrum
Log | Files | Refs | Submodules

commit edc00b448f95fca71284ba65320164ea5aa67fc8
parent a6e3a244e80023ac3c42f691699b759908b22d51
Author: SomberNight <somber.night@protonmail.com>
Date:   Sat, 15 Feb 2020 15:25:41 +0100

fix lightning "init" msg assertion error

closes #5962

Diffstat:
Melectrum/lnmsg.py | 29+++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)

diff --git a/electrum/lnmsg.py b/electrum/lnmsg.py @@ -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': ..., ... }, ... } @@ -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] @@ -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: @@ -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 @@ -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