Check that a payment initiated with sendpay can be completed by sendonion.
(node_factory, bitcoind)
| 7017 | |
| 7018 | |
| 7019 | def test_sendonion_sendpay(node_factory, bitcoind): |
| 7020 | """ |
| 7021 | Check that a payment initiated with sendpay can be completed by sendonion. |
| 7022 | """ |
| 7023 | opts = [ |
| 7024 | {"disable-mpp": None, "fee-base": 1000, "fee-per-satoshi": 1000}, |
| 7025 | ] |
| 7026 | l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True, opts=opts * 3) |
| 7027 | |
| 7028 | total_amount = "10000sat" |
| 7029 | # First case, do not overpay a pending MPP payment |
| 7030 | invstr = l3.rpc.invoice("10000sat", "inv", "description")["bolt11"] |
| 7031 | inv = l1.rpc.decode(invstr) |
| 7032 | route2 = l1.single_route(inv["payee"], "2000sat") |
| 7033 | route8 = l1.single_route(inv["payee"], "8000sat") |
| 7034 | |
| 7035 | def pay_with_sendpay(invoice, route, groupid, partid): |
| 7036 | l1.rpc.sendpay( |
| 7037 | route=route, |
| 7038 | payment_hash=invoice["payment_hash"], |
| 7039 | payment_secret=invoice["payment_secret"], |
| 7040 | amount_msat=invoice["amount_msat"], |
| 7041 | groupid=groupid, |
| 7042 | partid=partid, |
| 7043 | ) |
| 7044 | |
| 7045 | def pay_with_sendonion(invoice, route, groupid, partid): |
| 7046 | blockheight = l1.rpc.getinfo()["blockheight"] |
| 7047 | # Need to shift the parameters by one hop |
| 7048 | hops = [] |
| 7049 | for h, n in zip(route[:-1], route[1:]): |
| 7050 | # We tell the node h about the parameters to use for n (a.k.a. h + 1) |
| 7051 | hops.append( |
| 7052 | { |
| 7053 | "pubkey": h["node_id_out"], |
| 7054 | "payload": serialize_payload_tlv( |
| 7055 | n["amount_out_msat"], n["cltv_out"], n["short_channel_id_dir"].rsplit("/", 1)[0], blockheight |
| 7056 | ).hex(), |
| 7057 | } |
| 7058 | ) |
| 7059 | # The last hop has a special payload: |
| 7060 | hops.append( |
| 7061 | { |
| 7062 | "pubkey": route[-1]["node_id_out"], |
| 7063 | "payload": serialize_payload_final_tlv( |
| 7064 | route[-1]["amount_out_msat"], |
| 7065 | route[-1]["cltv_out"], |
| 7066 | invoice["amount_msat"], |
| 7067 | blockheight, |
| 7068 | invoice["payment_secret"], |
| 7069 | ).hex(), |
| 7070 | } |
| 7071 | ) |
| 7072 | onion = l1.rpc.createonion(hops=hops, assocdata=invoice["payment_hash"]) |
| 7073 | l1.rpc.call( |
| 7074 | "sendonion", |
| 7075 | { |
| 7076 | "onion": onion["onion"], |
nothing calls this directly
no test coverage detected