CLN is too permissive for serde_json when validating json:
`lightning-cli -k myplugin-cmd channels='[123456x1x0]'`
is valid for lightning-cli but is actually invalid json (bare token in array).
The cln-plugin decoder would error and end the FramedRead stream, causing the
PluginDriver loop to exit, and therefore exiting the plugin itself.
We need to recover the id from the invalid json with a separate parser to return a
json rpc error to CLN with the correct id so the rpc command does not hang.
Changelog-None
This is an undocumented interface, so we can just change it.
Rename "recurrence_label" to the more general "label", now we don't
require it to find previous payments.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We don't actually need to enforce this check here: we can make that
the users' responsibility. This simplifies our work quite a lot,
since createinvoicerequest won't have to do a lookup any more.
This can be done by the repeatpay plugin itself.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This mirrors the previous commit, where we did it for recurring offers.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: Offers: we set a 10 minute expiry when we create invoices for offers in other currencies.
Consider the case in which payment fails due to not enough "known enabled"
liquidity. Notice that we cover the "known" and "enabled" cases already.
But:
known_enabled <= enabled
and
known_enabled <= known
Changelog-None
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
Add PAY_INSUFFICIENT_FUNDS and PAY_ROUTE_NOT_FOUND, and give nice
detailed errors for those.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: JSON-RPC: `getroutes` can now return PAY_INSUFFICIENT_FUNDS (215) and PAY_DESTINATION_INSUFFICIENT_CAPACITY (220) error codes.
on trim_constraints:
to be sure we don't miss elements we add to the hash table after the
loop and not during iteration.
Changelog-None
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
On deletion of individual channel intel entries we need to free the
pointer inside the structure.
Changelog-None
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
Pure "constraints" don't care about order (they simply clamp max and
min), but "impressions" are relative, so they do. Change the
hashtable to keep them timestamp sorted.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Normal constraints are clamps on min/max caused by failed payments:
min for the channels that succeeded, max for the channel which failed.
Impressions are the results of successful payments, which alter both
min and max (negatively in the forward direction, positively in the
reverse).
impression: n
1. An effect, feeling, or image retained as a consequence of experience.
2. A vague notion, remembrance, or belief.
3. A mark produced on a surface by pressure.
Unlike constraints, this is the result of our own effect on the network: they're related
but different enough to get their own API and terminology.
The name conveys both we made an impression on the channel, and that
the results are a bit vague (due to other changes since then, which we
won't know about).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: JSON-RPC: `askrene` layers now contain "impressions" representing the effects of successful payments we made through channels.
Following the recent enforcement of ids being printable strings
we put guards on "method" and "prefix" as well.
Changelog-None
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
We used to handle it being a literal, but this was removed in
73fc9b0c2a (v25.05) so we don't need to handle that at all.
Not using the raw JSON means we handle weird methodnames by replacement: otherwise we would
not match the responses. Only an issue for commando, where the command would time out
rather than report "Unknown method".
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Shades of `efacada7dd` which did the same thing in multifundchannel:
(ab)used the id, which being a string, gave and id of 34 (").
Also clean up the leftover assert in multifundchannel.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Produce traces (see common/trace.h) for every payment in order to gather
statistics about the duration of a full payment execution.
Changelog-None
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
Changelog-Fixed: renepay: fix the computation of the CLTV for the first hop, it was double counting the current blockheight leading to too 900k blocks into the future.
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
A payment attempt in listpays is defined as pair (payment hash, group id).
If we query xpay for ongoing payments we must discriminate
using both values.
Fixes flaky test tests/test_pay.py:test_sendpay_grouping
```
FAILED tests/test_pay.py::test_sendpay_grouping - AssertionError: assert ['pending', 'pending', 'complete'] == ['failed', 'failed', 'complete']
```
Changelog-None
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
minimal setups without `ca-certificates` would cause cln-currencyrate to immediately exit with
`builder error`
We vendor the root certificates and improve the error message.
reported by @nepet
Changelog-Fixed: cln-currencyrate: include root certificates to fix the `builder error` on OS's without root certificates
We use to call askrene-age on xpay layer every 60 seconds to remove old
entries. But for payments to discard old entries it is enough to call
askrene-age before getroutes. True as long as:
age(t1) * age(t2) * ... * age(tN) = age(tN)
Reduces flakyness caused by xpay failing to call askrene-age during lightningd shutdown.
Changelog-None
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
preapproveinvoice_succeed and preapprovekeysend_succeed
do the same thing: acknowledge that preapproval rpc call have succeeded
and continue the payment execution via populate_private_layers.
Therefore we use a unique function for both cases: preapprove_succeed.
Changelog-None.
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>
specifically coindesk was constantly hitting API rate limits causing our tests to fail
so lets unit tests all endpoints with a snapshot of real responses and only allow for http
error 401/429 in integration tests
Also fix a flake in test_bkpr_currencyrate_persisted that would pick up a cached rate from CLN's own caching
Changelog-None
The bwatch plugin lived in plugins/bwatch/ and output its binary as
plugins/bwatch/bwatch. This caused make install to install it flat as
<plugindir>/bwatch, while lightningd expected it at <plugindir>/bwatch/bwatch, so plugin registration failed at startup with "failed to register plugin".
Fix by renaming the output to plugins/cln-bwatch, following the same
convention as cln-renepay, cln-xpay and cln-askrene.
Changelog-Fixed: bwatch plugin failed to register on startup after make install
channel_is_available() checked whether a channel_update existed
(gossmap_chan_set) and whether renepay's own disabledmap had flagged
it, but never checked gossmap's half_chan.enabled flag. This meant
renepay would route through channels marked disabled in the
gossip_store, wasting HTLC round-trips to re-discover the failure.
Changelog-Fixed: renepay now skips channels disabled in the gossip map.
Changelog-Added: sendamount command, to make a payment specifying the desired amount to send instead of the amount to be received.
Signed-off-by: Lagrang3 <lagrang3@protonmail.com>