def parse(byte_string): scid, remainder, err = Namespace.pop_short_channel_id(byte_string) if err: return None, err #print("scid: %s, remainder: %s\n" % (scid, remainder.hex())) amt_to_forward, remainder, err = Namespace.pop_u64(remainder) if err: return None, err #print("amt: %s, remainder: %s\n" % (amt_to_forward, remainder.hex())) outgoing_cltv_value, remainder, err = Namespace.pop_u32(remainder) if err: return None, err #print("outgoing: %s, remainder: %s\n" % (outgoing_cltv_value, # remainder.hex())) padding, remainder, err = Namespace.pop_bytes(12, remainder) if err: return None, err #print("padding %s, remainder: %s\n" % (padding, remainder.hex())) if len(remainder) != 0: return None, "unexpected remaining bytes" return { 'format': 'legacy', 'short_channel_id': scid, 'amt_to_forward': amt_to_forward, 'outgoing_cltv_value': outgoing_cltv_value, 'padding': padding }, None
def parse_fixed(byte_string): if len(byte_string) != ONION_BYTE_LENGTH: return None, "onion is the wrong length" version, remainder, err = Namespace.pop_u8(byte_string) if err: return None, "could not pop version byte" if version != 0: return None, "unsupported onion packet version" public_key, remainder, err = Namespace.pop_point(remainder) if err: return None, "could not pop public key: %s" % err hop_payloads, remainder, err = Namespace.pop_bytes(HOP_PAYLOADS_LENGTH, remainder) if err: return None, "could not pop hops_payloads: %s" % err hmac, remainder, err = Namespace.pop_bytes(HMAC_LENGTH, remainder) if err: return None, "could not pop hmac: %s" % err if len(remainder) != 0: return None, "unexpected remaining bytes" # TODO Check hmac for validity, need assocdata return {'version': version, 'public_key': public_key, 'hop_payloads': hop_payloads, 'hmac': hmac}, None
def encode(short_channel_id, amt_to_forward, outgoing_cltv_value): encoded_version = Namespace.encode_u8(0) encoded_scid = Namespace.encode_short_channel_id(short_channel_id) encoded_amt = Namespace.encode_u64(amt_to_forward) encoded_outgoing = Namespace.encode_u32(outgoing_cltv_value) padding = 12 * Namespace.encode_u8(0) return (encoded_version + encoded_scid + encoded_amt + encoded_outgoing + padding)
def parse_payment_data(tlv): payment_secret, remainder, err = Namespace.pop_bytes(32, tlv.v) if err: return None, err total_msat, remainder, err = Namespace.pop_tu64( len(remainder), remainder) if err: return None, err if len(remainder) != 0: return None, "unexpected remaining bytes" return { 'tlv_type_name': 'payment_data', 'payment_secret': payment_secret, 'total_msat': total_msat }, None
def parse_tlv2(self, tlv): cltv_expiry, remainder, err = Namespace.pop_tu32(tlv.l, tlv.v) if err: return None, err if len(remainder) != 0: return None, "unexpected remaining bytes" return {'tlv_type_name': "tlv2", 'cltv_expiry': cltv_expiry}, None
def parse_art_no(tlv): art_no, remainder, err = Namespace.pop_tu16(tlv.l, tlv.v) if err: return None, err if len(remainder) > 0: return None, "unexpected extra bytes" return {'tlv_type_name': "bannerpunk_art_no", 'art_no': art_no}, None
def parse_tlv1(self, tlv): amount_msat, remainder, err = Namespace.pop_tu64(tlv.l, tlv.v) if err: return None, err if len(remainder) != 0: return None, "unexpected remaining bytes" return {'tlv_type_name': "tlv1", 'amount_msat': amount_msat}, None
def parse(self, byte_string): tlv_parsers = { 1: self.parse_tlv1, 2: self.parse_tlv2, 3: self.parse_tlv3, 254: self.parse_tlv4 } return Namespace.parse(byte_string, tlv_parsers)
def parse_tlv4(self, tlv): print("parsing tlv4: %s" % tlv) cltv_delta, remainder, err = Namespace.pop_u16(tlv.v) if err: return None, err if len(remainder) != 0: return None, "unexpected remaining bytes" return {'tlv_type_name': "tlv4", 'cltv_delta': cltv_delta}, None
def parse_tlv3(self, tlv): print("parsing tlv3: %s" % tlv) node_id, remainder, err = Namespace.pop_point(tlv.v) if err: return None, err amount_msat_1, remainder, err = Namespace.pop_u64(remainder) if err: return None, err amount_msat_2, remainder, err = Namespace.pop_u64(remainder) if err: return None, err if len(remainder) != 0: return None, "unexpected remaining bytes" return { 'tlv_type_name': "tlv3", 'node_id': node_id, 'amount_msat_1': amount_msat_1, 'amount_msat_2': amount_msat_2 }, None
def parse_short_channel_id(tlv): scid, remainder, err = Namespace.pop_short_channel_id(tlv.v) if err: return None, err if len(remainder) != 0: return None, "unexpected remaining bytes" return { 'tlv_type_name': 'short_channel_id', 'short_channel_id': scid }, None
def parse_outgoing_cltv_value(tlv): outgoing_cltv_value, remainder, err = Namespace.pop_tu32(tlv.l, tlv.v) if err: return None, err if len(remainder) != 0: return None, "unexpected remaining bytes" return { 'tlv_type_name': 'outgoing_cltv_value', 'outgoing_cltv_value': outgoing_cltv_value }, None
def parse_amt_to_forward(tlv): amt_to_forward, remainder, err = Namespace.pop_tu64(tlv.l, tlv.v) if err: return None, err if len(remainder) != 0: return None, "unexpected remaining bytes" return { 'tlv_type_name': 'amt_to_forward', 'amt_to_forward': amt_to_forward }, None
def parse_pixels(tlv): pixels = [] if tlv.l % 5 != 0: return None, "unexpected length" remainder = tlv.v while len(remainder) > 0: pixel_hex, remainder, err = Namespace.pop_bytes(5, remainder) if err: return None, err pixels.append(Pixel.from_bin(h2b(pixel_hex))) return {'tlv_type_name': "bannerpunk_pixels", 'pixels': pixels}, None
def parse_tlv2(self, tlv): print("parsing tlv2: %s" % tlv) short_channel_id, remainder, err = Namespace.pop_short_channel_id( tlv.v) if err: return None, err if len(remainder) != 0: return None, "unexpected remaining bytes" return { 'tlv_type_name': "tlv2", 'short_channel_id': short_channel_id }, None
def parse(byte_string, extension_parsers=None): tlv_parsers = { 2: TlvHopPayload.parse_amt_to_forward, 4: TlvHopPayload.parse_outgoing_cltv_value, 6: TlvHopPayload.parse_short_channel_id, 8: TlvHopPayload.parse_payment_data } if extension_parsers: tlv_parsers.update(extension_parsers) parsed, err = Namespace.parse(byte_string, tlv_parsers) if err: print("err 123: %s" % err) return None, err return {'format': 'tlv', 'tlvs': parsed}, None
def encode_outgoing_cltv_value(outgoing_cltv_value): return Tlv(4, Namespace.encode_tu32(outgoing_cltv_value)).encode()
def parse(self, byte_string): tlv_parsers = {0: self.parse_tlv1, 11: self.parse_tlv2} return Namespace.parse(byte_string, tlv_parsers)
def encode_short_channel_id(short_channel_id): t = Tlv(6, Namespace.encode_short_channel_id(short_channel_id)) return t.encode()
def encode_payment_data(payment_secret, total_msat): body = (Namespace.encode_bytes(payment_secret) + Namespace.encode_tu64(total_msat)) return Tlv(8, body).encode()
def _encode_art_no(art_no): encoded = Namespace.encode_tu16(art_no) return Tlv(ART_TLV_TYPE, encoded).encode()
def encode_amt_to_forward(amt_to_forward): return Tlv(2, Namespace.encode_tu64(amt_to_forward)).encode()