Commit Graph

290 Commits

Author SHA1 Message Date
Rusty Russell
9c6430c076 plugins/pay: don't crash if erring index is past route array end.
I assume this happens with multi-hop routehints?

```
1768169599027	2026-01-11T22:13:19.027Z	pay: plugins/libplugin-pay.c:1199: payment_result_infer: Assertion `i <= len' failed.
1768169599027	2026-01-11T22:13:19.027Z	pay: FATAL SIGNAL 6 (version 25.12)
1768169599036	2026-01-11T22:13:19.036Z	0x5562816bcaa4 send_backtrace
1768169599036	2026-01-11T22:13:19.036Z		common/daemon.c:38
1768169599036	2026-01-11T22:13:19.036Z	0x5562816bcb40 crashdump
1768169599036	2026-01-11T22:13:19.036Z		common/daemon.c:83
1768169599036	2026-01-11T22:13:19.036Z	0x7f5fca29d32f ???
1768169599036	2026-01-11T22:13:19.036Z		???:0
1768169599036	2026-01-11T22:13:19.036Z	0x7f5fca2f6b2c ???
1768169599036	2026-01-11T22:13:19.036Z		pthread_kill+0x11c:0
1768169599036	2026-01-11T22:13:19.036Z	0x7f5fca29d27d ???
1768169599036	2026-01-11T22:13:19.036Z		gsignal+0x1d:0
1768169599036	2026-01-11T22:13:19.036Z	0x7f5fca2808fe ???
1768169599036	2026-01-11T22:13:19.036Z		abort+0xde:0
1768169599036	2026-01-11T22:13:19.036Z	0x7f5fca28081a ???
1768169599036	2026-01-11T22:13:19.036Z		???:0
1768169599036	2026-01-11T22:13:19.036Z	0x7f5fca293516 ???
1768169599036	2026-01-11T22:13:19.036Z		__assert_fail+0x46:0
1768169599037	2026-01-11T22:13:19.037Z	0x5562816ae9f6 payment_result_infer
1768169599037	2026-01-11T22:13:19.037Z		plugins/libplugin-pay.c:1199
1768169599037	2026-01-11T22:13:19.037Z	0x5562816b4acd payment_waitsendpay_finished
1768169599037	2026-01-11T22:13:19.037Z		plugins/libplugin-pay.c:1653
1768169599037	2026-01-11T22:13:19.037Z	0x5562816aca60 handle_rpc_reply
1768169599037	2026-01-11T22:13:19.037Z		plugins/libplugin.c:1062
1768169599037	2026-01-11T22:13:19.037Z	0x5562816acc86 rpc_conn_read_response
1768169599037	2026-01-11T22:13:19.037Z		plugins/libplugin.c:1377
1768169599037	2026-01-11T22:13:19.037Z	0x5562816f0e87 next_plan
1768169599037	2026-01-11T22:13:19.037Z		ccan/ccan/io/io.c:60
1768169599037	2026-01-11T22:13:19.037Z	0x5562816f1358 do_plan
1768169599037	2026-01-11T22:13:19.037Z		ccan/ccan/io/io.c:422
1768169599037	2026-01-11T22:13:19.037Z	0x5562816f1415 io_ready
1768169599037	2026-01-11T22:13:19.037Z		ccan/ccan/io/io.c:439
1768169599037	2026-01-11T22:13:19.037Z	0x5562816f2e23 io_loop
1768169599037	2026-01-11T22:13:19.037Z		ccan/ccan/io/poll.c:470
1768169599037	2026-01-11T22:13:19.037Z	0x5562816ae114 plugin_main
1768169599037	2026-01-11T22:13:19.037Z		plugins/libplugin.c:2429
1768169599037	2026-01-11T22:13:19.037Z	0x5562816a894c main
1768169599037	2026-01-11T22:13:19.037Z		plugins/pay.c:1581
1768169599037	2026-01-11T22:13:19.037Z	0x7f5fca2821c9 ???
1768169599037	2026-01-11T22:13:19.037Z		???:0
1768169599037	2026-01-11T22:13:19.037Z	0x7f5fca28228a ???
1768169599037	2026-01-11T22:13:19.037Z		__libc_start_main+0x8a:0
1768169599037	2026-01-11T22:13:19.037Z	0x5562816a4eb4 ???
1768169599037	2026-01-11T22:13:19.037Z		_start+0x24:0
1768169599037	2026-01-11T22:13:19.037Z	0xffffffffffffffff ???
1768169599037	2026-01-11T22:13:19.037Z		???:0
1768169599136	2026-01-11T22:13:19.136Z	2026-01-11T22:13:19.136Z INFO    plugin-pay: Killing plugin: exited during normal operation
69599136	2026-01-11T22:13:19.136Z	2026-01-11T22:13:19.136Z **BROKEN** plugin-pay: Plugin marked as important, shutting down lightningd!
```

Reported-by: michael1011
Fixes: https://github.com/ElementsProject/lightning/issues/8828
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: plugins: `pay` can crash on errors returned from deep inside routehints.
2026-01-14 17:06:02 +10:30
wqxoxo
bc3b9b4f11 pay: Enforce maxdelay for direct channel payments
When paying through a direct channel, direct_pay_override() creates a
route bypassing the normal routing path, which skips the CLTV budget
check in payment_getroute(). This allows payments to succeed even when
maxdelay is set below the required min_final_cltv_expiry.

Add a check in direct_pay_override() to verify the required CLTV
doesn't exceed cltv_budget before using the direct channel shortcut.
If it exceeds, skip the direct channel and let normal routing handle
the failure with a proper error message.

Fixes: #8609

Changelog-Fixed: pay: `maxdelay` parameter now enforced for direct channel payments
2025-12-19 12:41:17 +01:00
wqxoxo
b906507968 Fix BOLT11 annotation loss after sendonion failure
Fixes #6978 where bolt11 annotations were lost when sendonion failed early and payment was retried.

When sendonion RPC fails before saving payment to database, invstring_used flag would remain true, causing retry attempts to omit bolt11 parameter. Successful retries would then save to DB without bolt11 annotation.

Move invstring_used flag setting from payment_createonion_success to payment_sendonion_success. This ensures the flag is only set after sendonion actually succeeds. The bolt11 will be sent with every sendonion attempt until the first successful one, accepting the minor redundancy for cleaner state management.
Changelog-Fixed: Plugins: `listpays` can be missing the bolt11 information in some cases where `pay` is used.
2025-11-24 14:32:24 +10:30
Rusty Russell
35f65c5d91 common: add amount_msat_deduct / amount_msat_deduct_sub.
I added amount_msat_accumulate for the "a+=b" case, but I was struggling
with a name for the subtractive equivalent.  After some prompting, ChatGPT
suggested deduct.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-17 10:56:18 +10:30
Rusty Russell
8b9020d7b9 global: use clock_time in place of time_now().
Except for tracing, that sticks with time_now().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-13 21:21:29 +10:30
Rusty Russell
522457a12b connectd, gossipd, pay, bcli: use timemono when solely measuring duration for timeouts.
This is immune to things like clock changes, and has the convenient side-effect that
it will *not* be overridden when we override time for developer purposes.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-11-13 21:21:29 +10:30
Rusty Russell
6e5cb299dd global: remove unnecessary includes from C files.
Basically, `devtools/reduce-includes.sh */*.c`.

Build time from make clean (RUST=0) (includes building external libs):

Before:
	real    0m38.944000-40.416000(40.1131+/-0.4)s
	user    3m6.790000-17.159000(15.0571+/-2.8)s
	sys     0m35.304000-37.336000(36.8942+/-0.57)s
After:
	real    0m37.872000-39.974000(39.5466+/-0.59)s
	user    3m1.211000-14.968000(12.4556+/-3.9)s
	sys     0m35.008000-36.830000(36.4143+/-0.5)s

Build time after touch config.vars (RUST=0):

Before:
	real    0m19.831000-21.862000(21.5528+/-0.58)s
	user    2m15.361000-30.731000(28.4798+/-4.4)s
	sys     0m21.056000-22.339000(22.0346+/-0.35)s

After:
	real    0m18.384000-21.307000(20.8605+/-0.92)s
	user    2m5.585000-26.843000(23.6017+/-6.7)s
	sys     0m19.650000-22.003000(21.4943+/-0.69)s

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30
Rusty Russell
f6a4e79420 global: remove unnecessary includes from headers.
Each header should only include the other headers it needs to compile;
`devtools/reduce-includes.sh */*.h` does this.  The C files then need
additional includes if they don't compile.

And remove the entirely useless wire/onion_wire.h, which only serves to include wire/onion_wiregen.h.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-10-23 06:44:04 +10:30
Chandra Pratap
a77aa50ae1 plugins/libplugin-pay: Add a check for NaN values
Changelog-Fixed: Due to the imprecision of `htlc_max`'s type (`fp16_t`),
`capacity_bias()` can return `NaN` in some cases. This leads to a
runtime error when compiled with UBSan. Add a check against it.
2025-09-22 10:52:59 +09:30
Rusty Russell
1c537c258e pay: fix uninitialized var in debug output.
@nepet noted that Valgrind complained.  Nobody really cares though?
TL;DR: if channel isn't enabled, estimate isn't set.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-None: CI only
2025-08-27 12:53:38 +09:30
Rusty Russell
5d5741e681 libplugin: correctly wrap notifications we send in the notification name.
All the core notifications changed over to wrapping the notification
fields in an object with the name of the notification, but notifications
from plugins were missed.

Changelog-Added: Plugins: `channel_hint_update`, `pay_failure` and `pay_success` notifications now have objects of the same name containing the expected fields.
Changelog-Deprecated: Plugins: `channel_hint_update`, `pay_failure` and `pay_success` notification fields outside the same-named object.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-08-18 10:01:07 +09:30
Rusty Russell
fdfc7ce62f gossmap: add (and use) logging hook.
Default goes to stderr for LOG_UNUSUAL and higher.

We have to whitelist more cases in map_catchup so we don't spam the logs
with perfectly-expected (but ignored) messages though.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2025-02-11 15:11:47 -06:00
Christian Decker
94e70b8124 pay: Print the HTLC result as soon as it's known
We used to not print what happened with an HTLC in the `pay`
plugin. This meant that to follow the HTLCs we'd have to map the `pay`
HTLCs to the `lightningd` HTLCs, and then trace that. BY having `pay`
print the outcome as it sees it, we can make that tracking much
simpler, even allowing for tooling to do it for us.

Changelog-None This is a log-only change
2025-01-30 09:35:50 +10:30
Jesse de Wit
087a29b0b3 libplugin-pay: trace payment_continue
Changelog-Added: Plugins: `pay` now has tracing support for various payment steps.
2024-11-13 13:15:52 +01:00
Rusty Russell
c797b6fb20 libplugin: add method string to jsonrpc callbacks, implement generic helpers.
Without knowing what method was called, we can't have useful general logging
methods, so go through the pain of adding "const char *method" everywhere,
and add:

1. ignore_and_complete - we're done when jsonrpc returned
2. log_broken_and_complete - we're done, but emit BROKEN log.
3. plugin_broken_cb - if this happens, fail the plugin.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-07 17:04:35 +10:30
Rusty Russell
c5099b1647 libplugin: clean up API.
When we used to allow cmd to be NULL, we had to hand the plugin
everywhere.  We no longer do.

1. Various jsonrpc_ functions no longer need the plugin arg.
2. send_outreq no longer needs a plugin arg.
3. The init function takes a command, not a plugin.
4. Remove command_deprecated_in_nocmd_ok.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-07 17:04:35 +10:30
Rusty Russell
bc22a8db4f libplugin-pay: fix command logging
We were dereferencing the first character of the id, (always '"') which meant
everything was id 34.

Before:
	plugin-pay: cmd 34 partid 5

After:
	cmd pytest:pay#62/cln:pay#105 partid 0

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: `pay`: debug logging now uses correct JSON ids.
2024-11-07 17:04:35 +10:30
Rusty Russell
ec8293d215 libplugin-pay: always use a non-NULL struct command.
This means we replace p->cmd with an auxillary command after we've
finished, so we have a valid command to use.

It also means we weave `struct command_result` returns back through
all the callers.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-07 17:04:35 +10:30
Rusty Russell
0a909bdea5 libplugin: reindent.
This does not code changes, but makes the next changes easier.

We short-cut the "we are a child" case and de-indent the main
cases.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-11-07 17:04:35 +10:30
Rusty Russell
f944e03fca BOLT update: remove INVALID_REALM error.
This is obsolete (since modern onions) and so removed from spec.
We should not set it, and don't need to handle it specially.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-10-16 07:14:32 +10:30
Jesse de Wit
8330e3a0df pay-plugin: set gossmods directly
Multiple places in the pay lifecycle depend on mods to be set. By
setting the mods directly after the first listpeerchannels call,
subsequent calls to listpeerchannels are avoided.

Changelog-Fixed: pay-plugin: only call listpeerchannels once during a
payment lifecycle.
2024-10-08 19:26:14 +02:00
Jesse de Wit
281c639b57 pay-plugin: direct_pay only destination channels
The direct_pay payment modifier would query all peer channels, while
only the channels of the given peer suffices.

Changelog-None
2024-10-08 19:26:14 +02:00
Jesse de Wit
cc1362ead3 libplugin-pay: use map for channel hints
For nodes with many channels this is a tremendous improvement in pay
performance. PR #7611 improves payment performance from 15 seconds to
13.5 seconds on one of our nodes. This commit improves payment
performance from 13.5 seconds to 5.7 seconds.

Changelog-Fixed: Improved pathfinding speed for large nodes.
2024-10-07 15:16:46 +02:00
Christian Decker
a6a7dd8f71 pay: Switch to msat for total_capacity
This minimizes the need to convert back and forth from and to sat
values, and it also removes a new instance of sats in the public
interface (`channel_hints`).

Suggested-By: Rusty Russell <@rustyrussell>
2024-10-07 14:05:47 +02:00
Christian Decker
f6d410d924 pay: Remove use of temporary local channel_hint
We were using `channel_hint` to temporarily tweak the graph inside of
a payment. However, these ad-hoc `channel_hints` are stickier than
their predecessors, in that they outlive the payment attempt itself,
and interfere with later ones.

Changelog-Changed: pay: Discarding an overly long or expensive route does not blocklist channels anymore.
2024-10-07 14:05:47 +02:00
Christian Decker
30d2a57f50 pay: Log when and why we exclude a channel from the route 2024-10-07 14:05:47 +02:00
Christian Decker
91ffa8e424 pay: Add channel_hint_set_count primitive 2024-10-07 14:05:47 +02:00
Christian Decker
50a0321759 pay: Use the global channel_hint_set and remember across payments 2024-10-07 14:05:47 +02:00
Christian Decker
3ad0085478 route: Change the type of the funding capacity to amount_sat
Keeping it in `amount_msat` made the comparisons easier, but it was
the wrong type for this.
2024-10-07 14:05:47 +02:00
Christian Decker
cf09314b3b pay: Rename overall_capacity to just capacity
Suggested-by: Rusty Russell <@rustyrussell>
2024-10-07 14:05:47 +02:00
Christian Decker
37a204df41 plugin: Split out the struct channel_hint handling
We're getting serious about how we manage the channel_hints, so let's
give them a proper home.
2024-10-07 14:05:47 +02:00
Christian Decker
b897b4365d pay: Make the channel_hints global
We attach the hints to the plugin, so they get shared across multiple
payments.
2024-10-07 14:05:47 +02:00
Christian Decker
5225218094 pay: Use the total_mast amount as the upper limit for channel_hints 2024-10-07 14:05:47 +02:00
Christian Decker
1eb878be82 route: Add the total capacity to route_hops
We need to know the overall channel capacity, i.e., the amount_msat
that the channel was funded with, in order to relax the channel_hint
to refill over time.
2024-10-07 14:05:47 +02:00
Christian Decker
d60db28c41 pay: Add a function to update channel_hints based on their age
We relax constraints from the `channel_hint` through a linear refill.
2024-10-07 14:05:47 +02:00
Rusty Russell
5052f0763f gossmap: keep capacity for locally-generated channels as well.
It was weird not to have a capacity associated with localmods channels, and
fixing it has some very nice side effects.

Now the gossmap_chan_get_capacity() call never fails (we prevented reading
of channels from gossmap in the partially-written case already), so we
make it return the capacity.  We do this in msat, because that's what
all the callers want.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-10-04 11:27:53 +09:30
Rusty Russell
f05f871c92 common/amount: add amount_msat_accumulate()
Saves some typing, and is clearer than checking if both args really
are the same!

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-09-19 12:16:53 +09:30
Rusty Russell
a243f3c79c plugin/pay: fix crash if failcodename isn't set.
Fixes: https://github.com/ElementsProject/lightning/issues/7200
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-08-12 18:36:11 +09:30
Christian Decker
aa45e737dc libplugin: Add parser for channel_hint from JSON 2024-08-09 13:59:07 +09:30
Christian Decker
6a53cf288b libplugin: Add primitive to serialize channel_hint to JSON 2024-08-09 13:59:07 +09:30
Christian Decker
8e9f71ff85 libplugin: pay now emits channel_hint as we learn about the net
The `pay` plugin, as well as other plugins making use of the tree-pay
executor, will now emit their observations as they see them. The
notifications are sent on the `channel_hint_updated` topic, and any
subscriber will get them.

We also added a `timestamp` to the `struct channel_hint`, as these
observations now outlive the `pay` call, and have to be attenuated /
relaxed as they age, until we can eliminate them completely (when the
restriction is equal to the structural information gathered from the
gossip).

Changelog-Added: pay: Payments now emit `channel_hint_updated` notification to share inferred balances and observations across multiple payments.
2024-08-09 13:59:07 +09:30
Christian Decker
89f01f13fc pay: Use paymod_log when filtering routehints for changes
Changelog-Changed: pay: Improved logging should facilitate debugging considerably.
2024-08-08 12:20:44 -07:00
Christian Decker
44e5bbc8e5 pay: Log the invoice we are about to pay
Should make debugging based on logs a bit simpler.
2024-08-08 12:20:44 -07:00
Christian Decker
82afa8d38c pay: Add a pre-flight check for the spendable balance
Changelog-Added: pay: The pay plugin now checks whether we have enough spendable capacity before computing a route, returning a clear error message if we don't
2024-08-08 12:20:44 -07:00
Christian Decker
c2a698069e pay: Add an error code to the payments
This allows us to directly returnan error code based on where we
decided to abort, rather than attemtping to infer it from the parts.

Changelog-Added: pay: The pay plugin now returns better error codes
2024-08-08 12:20:44 -07:00
Rusty Russell
f00f832b96 plugins/pay: pay to invoices where first hop is a short_channel_id_dir.
Changelog-Added: Protocol: pay can now pay to bolt12 invoices if entry to blinded hop is specified as a short_channel_id (rather than node id).
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-18 10:53:55 +09:30
Rusty Russell
47c1ca8d85 plugins/pay: separate route destination and pay destination.
For bolt12, we have blinded paths so we route to the head of the blinded
path, which may not be the same as the final payment destination.

This matters mainly for detecting self-pay.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-18 10:53:55 +09:30
Rusty Russell
ec2b626630 plugins/pay: don't crash if getroute is empty.
This can't happen because we go the self-pay path in this case, but
once we fix that for bolt12, this can be reached.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-07-09 15:09:29 +02:00
Rusty Russell
3c48438821 pay: fix bolt12 blinded path cltv logic.
The spec has moved a bit here: the `outgoing_cltv_value` in the final onion
is basically the blockheight now (plus the 1 block delta we give ourselves).

Also, we were doubling ours, since p->min_final_cltv_expiry was already set
to p->blindedpay->cltv_expiry_delta above.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-05-15 10:55:16 -05:00
Rusty Russell
cb2c4963f2 bolt12: allow first_node_id in blinded path to be a scid.
We don't actually support it yet, but this threads through the type change,
puts it in "decode" etc.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2024-05-12 19:11:43 -05:00