|
1 | 1 | from fixtures import * # noqa: F401,F403 |
2 | 2 | from fixtures import TEST_NETWORK |
3 | 3 | from pathlib import Path |
4 | | -from io import BytesIO |
5 | 4 | from pyln.client import RpcError, Millisatoshi |
6 | 5 | from pyln.proto.onion import TlvPayload |
7 | 6 | from pyln.testing.utils import EXPERIMENTAL_DUAL_FUND, FUNDAMOUNT, scid_to_int |
8 | 7 | from utils import ( |
9 | 8 | wait_for, only_one, sync_blockheight, TIMEOUT, |
10 | | - mine_funding_to_announce, first_scid |
| 9 | + mine_funding_to_announce, first_scid, serialize_payload_tlv, serialize_payload_final_tlv |
11 | 10 | ) |
12 | 11 | import copy |
13 | 12 | import os |
14 | 13 | import pytest |
15 | 14 | import random |
16 | 15 | import re |
17 | 16 | import string |
18 | | -import struct |
19 | 17 | import subprocess |
20 | 18 | import time |
21 | 19 | import unittest |
@@ -2980,80 +2978,19 @@ def test_sendonion_rpc(node_factory): |
2980 | 2978 | first_hop = route[0] |
2981 | 2979 | blockheight = l1.rpc.getinfo()['blockheight'] |
2982 | 2980 |
|
2983 | | - def truncate_encode(i: int): |
2984 | | - """Encode a tu64 (or tu32 etc) value""" |
2985 | | - ret = struct.pack("!Q", i) |
2986 | | - while ret.startswith(b'\0'): |
2987 | | - ret = ret[1:] |
2988 | | - return ret |
2989 | | - |
2990 | | - def serialize_payload_tlv(n): |
2991 | | - block, tx, out = n['channel'].split('x') |
2992 | | - |
2993 | | - payload = TlvPayload() |
2994 | | - # BOLT #4: |
2995 | | - # 1. type: 2 (`amt_to_forward`) |
2996 | | - # 2. data: |
2997 | | - # * [`tu64`:`amt_to_forward`] |
2998 | | - b = BytesIO() |
2999 | | - b.write(truncate_encode(int(n['amount_msat']))) |
3000 | | - payload.add_field(2, b.getvalue()) |
3001 | | - # BOLT #4: |
3002 | | - # 1. type: 4 (`outgoing_cltv_value`) |
3003 | | - # 2. data: |
3004 | | - # * [`tu32`:`outgoing_cltv_value`] |
3005 | | - b = BytesIO() |
3006 | | - b.write(truncate_encode(blockheight + n['delay'])) |
3007 | | - payload.add_field(4, b.getvalue()) |
3008 | | - # BOLT #4: |
3009 | | - # 1. type: 6 (`short_channel_id`) |
3010 | | - # 2. data: |
3011 | | - # * [`short_channel_id`:`short_channel_id`] |
3012 | | - b = BytesIO() |
3013 | | - b.write(struct.pack("!Q", int(block) << 40 | int(tx) << 16 | int(out))) |
3014 | | - payload.add_field(6, b.getvalue()) |
3015 | | - return payload.to_bytes().hex() |
3016 | | - |
3017 | | - def serialize_payload_final_tlv(n, payment_secret: str): |
3018 | | - payload = TlvPayload() |
3019 | | - # BOLT #4: |
3020 | | - # 1. type: 2 (`amt_to_forward`) |
3021 | | - # 2. data: |
3022 | | - # * [`tu64`:`amt_to_forward`] |
3023 | | - b = BytesIO() |
3024 | | - b.write(truncate_encode(int(n['amount_msat']))) |
3025 | | - payload.add_field(2, b.getvalue()) |
3026 | | - # BOLT #4: |
3027 | | - # 1. type: 4 (`outgoing_cltv_value`) |
3028 | | - # 2. data: |
3029 | | - # * [`tu32`:`outgoing_cltv_value`] |
3030 | | - b = BytesIO() |
3031 | | - b.write(truncate_encode(blockheight + n['delay'])) |
3032 | | - payload.add_field(4, b.getvalue()) |
3033 | | - # BOLT #4: |
3034 | | - # 1. type: 8 (`payment_data`) |
3035 | | - # 2. data: |
3036 | | - # * [`32*byte`:`payment_secret`] |
3037 | | - # * [`tu64`:`total_msat`] |
3038 | | - b = BytesIO() |
3039 | | - b.write(bytes.fromhex(payment_secret)) |
3040 | | - b.write(truncate_encode(int(n['amount_msat']))) |
3041 | | - payload.add_field(8, b.getvalue()) |
3042 | | - return payload.to_bytes().hex() |
3043 | | - |
3044 | 2981 | # Need to shift the parameters by one hop |
3045 | 2982 | hops = [] |
3046 | 2983 | for h, n in zip(route[:-1], route[1:]): |
3047 | 2984 | # We tell the node h about the parameters to use for n (a.k.a. h + 1) |
3048 | 2985 | hops.append({ |
3049 | 2986 | "pubkey": h['id'], |
3050 | | - "payload": serialize_payload_tlv(n) |
| 2987 | + "payload": serialize_payload_tlv(n['amount_msat'], n['delay'], n['channel'], blockheight).hex() |
3051 | 2988 | }) |
3052 | 2989 |
|
3053 | 2990 | # The last hop has a special payload: |
3054 | 2991 | hops.append({ |
3055 | 2992 | "pubkey": route[-1]['id'], |
3056 | | - "payload": serialize_payload_final_tlv(route[-1], inv['payment_secret']) |
| 2993 | + "payload": serialize_payload_final_tlv(route[-1]['amount_msat'], route[-1]['delay'], route[-1]['amount_msat'], blockheight, inv['payment_secret']).hex() |
3057 | 2994 | }) |
3058 | 2995 |
|
3059 | 2996 | onion = l1.rpc.createonion(hops=hops, assocdata=inv['payment_hash']) |
|
0 commit comments