Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 0 additions & 167 deletions libs/gl-testing/tests/test_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,173 +221,6 @@ def test_node_listpays_preimage(clients, node_factory, bitcoind):
assert pay.pays[0].preimage.hex() == preimage


def test_lsp_jit_fee(clients, node_factory, bitcoind):
"""Test that the LSP (our peer) is allowed to alter the amount to
deduct its fee.

The scenario is simple: l1 -> gl1, with l1 being the LSP,
forwarding less than it is supposed to according to the onion
packet. We explicitly opt-in to this deduction by having a
matching invoice stashed with the node. Upon receiving the
incoming HTLC the plugin fetches the invoice, checks that indeed
the expected `total_msat` is lower than the sender thought, and
then we modify the onion payload in order to get `lightningd` to
accept it and settle the invoice with it.

We test multiple parts and overpay slightly to verify that even
that works out ok.

We also check that we can handle unorthodox onion payloads that
don't carry fields that we expect.

"""
c = clients.new()
c.register(configure=True)
s = c.signer().run_in_thread()
gl1 = c.node()
l1 = node_factory.get_node()
gl1.connect_peer(l1.info["id"], f"127.0.0.1:{l1.daemon.port}")
l1.fundwallet(10**6)
wait_for(lambda: len(l1.rpc.listfunds()["outputs"]) > 0)
l1.rpc.fundchannel(c.node_id.hex(), "all")
bitcoind.generate_block(6, wait_for_mempool=1)
wait_for(
lambda: l1.rpc.listpeerchannels()["channels"][0]["state"] == "CHANNELD_NORMAL"
)

# Create an invoice for 10k
preimage = "00" * 32
payment_hash = "66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925"
parts = 2
p1, p2 = 300000, 700000 # The two parts we're going to use
fee = 100000 # Fee leverage on each part
inv = gl1.invoice(
label="lbl",
amount_msat=clnpb.AmountOrAny(amount=clnpb.Amount(msat=p1 + p2 - parts * fee)),
description="desc",
preimage=bytes.fromhex(preimage),
).bolt11

decoded = l1.rpc.decodepay(inv)

# So we have an invoice for 100k, now send it in two parts:
o1 = l1.rpc.createonion(
hops=[
{
"pubkey": c.node_id.hex(),
"payload": (
"30"
+ "0203"
+ "0493e0" # amt_to_forward: 30k
+ "04016e" # 110 blocks CLTV
+ "0823"
+ decoded["payment_secret"]
+ "0f4240" # Payment_secret + total_msat
+ "FB0142" # Typ 251 payload 0x42 (testing we don't lose TLVs)
),
}
],
assocdata=payment_hash,
)

o2 = l1.rpc.createonion(
hops=[
{
"pubkey": c.node_id.hex(),
"payload": (
"30"
+ "0203"
+ "0aae60" # amt_to_forward: 70k
+ "04016e" # 110 blocks CLTV
+ "0823"
+ decoded["payment_secret"]
+ "0f4240" # Payment_secret + total_msat
+ "FB0142" # Typ 251 payload 0x42 (testing we don't lose TLVs)
),
}
],
assocdata=payment_hash,
)

l1.rpc.call(
"sendonion",
{
"onion": o1["onion"],
"first_hop": {
"id": c.node_id.hex(),
"amount_msat": f"{p1 - fee}msat",
"delay": 21,
},
"payment_hash": payment_hash,
"partid": 1,
"groupid": 1,
"shared_secrets": o1["shared_secrets"],
},
)
l1.rpc.call(
"sendonion",
{
"onion": o2["onion"],
"first_hop": {
"id": c.node_id.hex(),
"amount_msat": f"{p2 - fee}msat",
"delay": 21,
},
"payment_hash": payment_hash,
"partid": 2,
"groupid": 1,
"shared_secrets": o1["shared_secrets"],
},
)

# Check that custom payloads are preserved. See the type=251 field
# at the end of the onion-construction above.
c.find_node().process.wait_for_log(r"Serialized payload: .*fb0142")

l1.rpc.waitsendpay(payment_hash=payment_hash, partid=1, timeout=10)
l1.rpc.waitsendpay(payment_hash=payment_hash, partid=2, timeout=10)

# Check that custom payloads that we do not understand are skipped. The
# following onion payload does not contain `amt_to_forward`, see Bolt4.
o3 = l1.rpc.createonion(
hops=[
{
"pubkey": c.node_id.hex(),
"payload": (
"26"
+ "04016e" # 110 blocks CLTV
+ "0821"
+ "0000000000000000000000000000000000000000000000000000000000000000"
+ "00" # payment_data with dummy values
),
}
],
assocdata="0000000000000000000000000000000000000000000000000000000000000000",
)

l1.rpc.call(
"sendonion",
{
"onion": o3["onion"],
"first_hop": {
"id": c.node_id.hex(),
"amount_msat": "1msat",
"delay": 21,
},
"payment_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"partid": 0,
"groupid": 1,
"shared_secrets": o3["shared_secrets"],
},
)

# The htlc should be passed on to the next consumer.
c.find_node().process.wait_for_log(
r"Lsp-plugin continue, reason: payload=.* is missing forward_msat",
timeout=10,
)


@pytest.mark.skip(reason="Log-line can't be found anymore")
def test_custommsg(clients, node_factory, bitcoind, executor):
"""Connect a GL node and a CLN node and have them talk."""
Expand Down
Loading