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:
M | lib/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