electrum

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

commit c69f812f13aafaf3f11b0d021660194d622c4fd8
parent cbf8d4c78141df88e08e088646d949112248838c
Author: Janus <ysangkok@gmail.com>
Date:   Tue, 10 Apr 2018 19:36:49 +0200

lightning: do not list python files as resources, use lightning spec generated serialization

Diffstat:
Mlib/lnbase.py | 97++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 96 insertions(+), 1 deletion(-)

diff --git a/lib/lnbase.py b/lib/lnbase.py @@ -4,6 +4,8 @@ Derived from https://gist.github.com/AdamISZ/046d05c156aaeb56cc897f85eecb3eb8 """ +import json +from collections import OrderedDict import asyncio import sys import binascii @@ -17,6 +19,99 @@ from electrum.bitcoin import int_to_hex, bfh, rev_hex tcp_socket_timeout = 10 server_response_timeout = 60 +############################### + +message_types = {} + +def handlesingle(x, ma): + try: + x = int(x) + except ValueError: + x = ma[x] + try: + x = int(x) + except ValueError: + x = int.from_bytes(x, byteorder="big") + return x + +def calcexp(exp, ma): + exp = str(exp) + assert "*" not in exp + return sum(handlesingle(x, ma) for x in exp.split("+")) + +def make_handler(k, v): + def handler(data): + nonlocal k, v + print("msg type", k) + ma = {} + pos = 0 + for fieldname in v["payload"]: + poslenMap = v["payload"][fieldname] + #print(poslenMap["position"], ma) + assert pos == calcexp(poslenMap["position"], ma) + length = poslenMap["length"] + length = calcexp(length, ma) + ma[fieldname] = data[pos:pos+length] + pos += length + assert pos == len(data), (k, pos, len(data)) + return ma + return handler + +with open("lightning.json") as f: + structured = json.loads(f.read(), object_pairs_hook=OrderedDict) + +for k in structured: + v = structured[k] + if k in ["open_channel","final_incorrect_cltv_expiry", "final_incorrect_htlc_amount"]: + continue + if len(v["payload"]) == 0: + continue + try: + num = int(v["type"]) + except ValueError: + #print("skipping", k) + continue + byts = num.to_bytes(byteorder="big",length=2) + assert byts not in message_types, (byts, message_types[byts].__name__, k) + 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 message_types[b"\x00\x10"].__name__ == "init_handler" + +def decode_msg(data): + typ = data[:2] + parsed = message_types[typ](data[2:]) + return parsed + + +def gen_msg(msg_type, **kwargs): + typ = structured[msg_type] + data = int(typ["type"]).to_bytes(byteorder="big", length=2) + lengths = {} + for k in typ["payload"]: + poslenMap = typ["payload"][k] + leng = calcexp(poslenMap["length"], lengths) + try: + leng = kwargs[poslenMap["length"]] + except: + pass + try: + param = kwargs[k] + except KeyError: + param = 0 + try: + param = param.to_bytes(length=leng, byteorder="big") + except: + raise Exception("{} does not fit in {} bytes".format(k, leng)) + lengths[k] = len(param) + data += param + return data + +############################### + + def decode(string): """Return the integer value of the bytestring b @@ -198,7 +293,7 @@ async def main_loop(my_privkey, host, port, pubkey, loop): rn += 2 # send init - init_msg = encode(16, 2) + encode(0, 2) +encode(0,2) + init_msg = gen_msg("init", gflen=0, lflen=0) send_message(writer, init_msg, sk, sn) sn += 2