Commit graph

13 commits

Author SHA1 Message Date
Rusty Russell
113156858b xpay: don't excees maxfee *overall*.
We were handing "maxfee" to every getroutes call, even if we had already
used some of the fees.

Reported-by: @daywalker90
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-None: xpay is new this release.
2024-12-02 14:31:11 +10:30
Rusty Russell
b8e5b122d2 decode: don't fail to decode just because a bolt12 invoice has expired.
In fact, there are several places where we try to decode old invoices,
and they should all work.  The only place we should enforce expiration is
when we're going to pay.

This also revealed that xpay wasn't checking bolt11 expiries!

Reported-by: hMsats
Fixes: https://github.com/ElementsProject/lightning/issues/7869
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: JSON-RPC: `decode` refused to decode expired bolt12 invoices.
2024-11-30 13:17:55 +01:00
Rusty Russell
90ab9325a1 xpay: give an additional block "slack" for CLTV values.
pay does this, xpay does not.  Which means if a block comes in (or you're behind),
you get gratuitous failures:

```
    def test_xpay_simple(node_factory):
        l1, l2, l3, l4 = node_factory.get_nodes(4, opts={'may_reconnect': True})
        node_factory.join_nodes([l1, l2, l3], wait_for_announce=True)
        node_factory.join_nodes([l3, l4], announce_channels=False)

        # BOLT 11, direct peer
        b11 = l2.rpc.invoice('10000msat', 'test_xpay_simple', 'test_xpay_simple bolt11')['bolt11']
>       ret = l1.rpc.xpay(b11)

tests/test_xpay.py:148:
...
        if not isinstance(resp, dict):
            raise TypeError("Malformed response, response is not a dictionary %s." % resp)
        elif "error" in resp:
>           raise RpcError(method, payload, resp['error'])
E           pyln.client.lightning.RpcError: RPC call failed: method: xpay, payload: ('lnbcrt100n1pn5qu7csp53rp0mfwtfsyyy8gzsggepnxgslyalwvz3jkg9ptmqq452ln2nmgqpp58ak9nmfz9l93r0fpm266ewyjrhurhatrs05nda0r03p82cykp0vsdp9w3jhxazl0pcxz72lwd5k6urvv5sxymmvwscnzxqyjw5qcqp99qxpqysgqa798258yppu2tlfj8herr3zuz0zgux79zvtx6z57cmfzs2wdesmr4nvnkcmyssyu6k64ud54eg0v45c3mcw342jj6uy7tu202p6klrcp6ljc9w',), error: {'code': 203, 'message': "Destination said it doesn't know invoice: incorrect_or_unknown_payment_details"}
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-None: xpay is new this release.
2024-11-23 10:20:30 +10:30
Rusty Russell
1380d36898 xpay: don't try to timeout things until after we have created xpay layer.
```
lightningd-1 2024-11-19T05:21:16.313Z DEBUG   lightningd: Looking for [askrene,layers]
lightningd-1 2024-11-19T05:21:16.314Z DEBUG   lightningd: Got [askrene,layers,xpay]
lightningd-1 2024-11-19T05:21:16.314Z DEBUG   lightningd: Printing
lightningd-1 2024-11-19T05:21:16.315Z **BROKEN** plugin-cln-xpay: askrene-age failed with {\"code\":-32602,\"message\":\"layer: Unknown layer: invalid token '\\\"xpay\\\"'\"}
lightningd-1 2024-11-19T05:21:16.318Z DEBUG   plugin-cln-askrene: datastore = {\"datastore\":[{\"key\":[\"askrene\",\"layers\",\"xpay\"],\"generation\":13,\"hex\":\"000300001000003f47af0100000000673c1fea010000000000d1b0d4000003000000000ce5066e0000000000673c1fea010000000000d1b0d400000300001000001a47050000000000673c1fea010000000000d1b0d400000300003f00005a72b40100000000673c1fea010000000000d1b0d400000300000000005a07e80100000000673c1fea010000000000d1b0d400000300001a0000e3564c0100000000673c1fea010000000000d1b0d40000030000e3000db69cf50000000000673c1fea0001000000000100637e\"}]}
lightningd-1 2024-11-19T05:21:16.318Z DEBUG   plugin-cln-askrene: Loaded level xpay (203 bytes)
lightningd-1 2024-11-19T05:21:16.391Z INFO    plugin-cln-xpay: Killing plugin: exited during normal operation
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-19 17:51:18 +10:30
Rusty Russell
05fbcb4d9b xpay: make sure to call preapproveinvoice!
This is required for VLS which wants to know (and potentially decline) invoices
we're trying to pay.

As a nice side effect, our "check" command for xpay now does much more thorough
checking of arguments.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
2c15dc0e5b xpay: make self-pay work.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
229fc3f2b4 xpay: make the xpay layer persistent.
As the first user of a persistent layer, this tripped tests which
assumed the datastore would be empty!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
41e15b1ac9 xpay: age the "xpay" layer so we forget information older than 1 hour.
1 hour is what mpay uses, so stick with that for now.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
c715253af7 xpay: option to steal easy commands from pay.
Note: won't work with grpc (or probably other tools), since the output
is different.  But good for testing.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Config: option `xpay-handle-pay` can be used to call xpay when pay is used in many cases (but output is different from pay!)
2024-11-18 11:03:26 +10:30
Rusty Russell
64c1522597 xpay: don't use rpc_scan or jsonrpc_request_sync.
These will deadlock once we hook into rpc_command, so avoid them.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
dd4d3940b1 xpay: implement partial payments.
Explicitly tell xpay to only make part of a payment.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
47318a7875 xpay: add deadline.
We promised this in the schema originally, now support it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30
Rusty Russell
7c2407ef48 xpay: new plugin which uses askrene, injectpaymentonion.
Changelog-Added: Plugins: cln-xpay, with associated `xpay` command for payments.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-18 11:03:26 +10:30