Deprecate pay, keysend, renepay and getroute#9110
Conversation
rustyrussell
commented
May 5, 2026
- Complete the xpay feature set:
- Add xkeysend variant for "keysend using xpay",
- Add label and localinvreqid parameter support,
- Implement CLTV shadow routing in xpay.
- Handle channel_updates in errors in xpay.
- Improve compat handling for xpay-handle-pay: "succeed" like pay did if we're already paid.
- Enhance getroutes and sendpay: getroutes gets clearer and more complete fields, and sendpay understands them so the two easily work together
- Deprecate pay, paystatus, keysend, getroute, and renepay/renepaystatus (all with removal window v26.06–v27.03), and make xpay-handle-pay the default.
Lagrang3
left a comment
There was a problem hiding this comment.
This has been a lot of effort.
Nice work on building xkeysend and making getroutes compatible with sendpay.
|
@rustyrussell, I think we could keep the old json rpc names I know there is a little bit of work to be done to digest the parameters in |
Instead of removing pay, we can just make it an alias for xpay when pay is fully deprecated? We could allow "invstring" as a parameter to pay: that covers 99% of the transition already (amount_msat and label are already the same). Similarly, keysend just becomes an alias for xkeysend. |
5a447d1 to
c2ca227
Compare
I've add this change: pay now accepts invstring so people can use it today. |
58e1b79 to
26827eb
Compare
c56d5fd to
119d29b
Compare
update-mocks searches for prototypes, looking first in the local directory, then in */*.h, and takes the first. In the case of plugins/bkpr/test/run-currencyrate_str.c referring to jsonrpc_request_start_, this means it could get either the one in libplugin (correct) or the one in lightningd (wrong!), depending on directory order randomness. Hack it a bit harder, to look one up from the local dir before */*.h. This is redundant in most cases, but not for three-deep-nested dirs like this. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
These are useful for the common pattern of "append these bytes to this tal array". As a bonus, we do memcheck() on all these callers, for extra checking under valgrind. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Use standard names, and don't wait for each channel: wait for the final result. In particular, make sure l1 sees *all* the gossip! Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We were doing it for "auto.no_mpp_support", but not maxparts=1. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
In particular, we can return PAY_ROUTE_TOO_EXPENSIVE. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
If all channels are disabled, say so clearly. Also reword: it's not the source or destination which have disabled the channels. While we're here, remove the double space, lest people think I'm Satoshi. Before: Failed after 1 attempts. Unexpected error (invalid_onion_payload) from final node: disabling 103x1x0/1 for this payment. Then routing failed: We could not find a usable set of paths. The source has disabled 1 of 1 channels, leaving capacity only 0msat of 1000000000msat. After: Failed after 1 attempts. Unexpected error (invalid_onion_payload) from final node: disabling 103x1x0/1 for this payment. Then routing failed: We could not find a usable set of paths. All 1 channels to the source are disabled. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
…port" layer. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
In implementing shadow, I added a call to payment_log in xpay_core, which caused a valgrind error because we set unique_id later. This was a premature optimization, so we didn't assign unique_id for payments which didn't even start, but it's a footgun, and there are other (less common) calls to payment_log too early which make the same mistake. Simplify: unique_id is assigned at creation. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Much of this is redundant, but now it's better labeleled and stands alone. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This reflects a long-standing complaint from @Lagrang3 when the API was first implemented, and I should have listened. In particular, the impedance mismatch with the sendpay API is annoying. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Added: JSON-RPC: `getroutes` `route` explicit fields `node_id_in`, `node_id_out`, `amount_in_msat`, `amount_out_msat`, `cltv_in`, `cltv_out`.
Changelog-Deprecated: JSON-RPC: `getroutes` `route` fields `next_node_id`, `amount_msat` and `delay` (use `node_id_out`, `amount_in_msat` and `cltv_in`). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
119d29b to
fce4055
Compare
…e ones. Changelog-Added: JSON-RPC: `sendpay` now accepts one of the `paths` returned from `getroutes` as its `route` parameter. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
…o pyln-testing. And remove the two getroute() calls inside pyln-testing. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
We add a nice getroutes wrapper and use it to replace the simple getroute() calls which simply hand the result to sendpay(). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Excluding explicit getroute tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This uses askrene, so it benefits from previous payment experience. Changelog-Added: JSON-RPC: `xkeysend` command for keysend with modern routing support. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Starting up two nodes for each variant is slow, so do this internally. Also check that the descriptions are correct, not just that there is some invoice! Before: ================================ 7 passed in 75.63s (0:01:15) ================================ After: ===================================== 1 passed in 12.62s ===================================== Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: offers: we now use `xpay` not `pay` for paying invoices made with invoicerequest(). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1. Don't assume they send group 0 (thus waitsendpay works). waitsendpay should be unnecessary after pay anyway. 2. Don't use pay for test_multichan_stress, since it relies on pay not learning that the channel is unreliable. 3. Use xpay for test_listhtlcs_wait, since we want no shadow. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Good for conditional mocks, like in next patch. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This usually means changing the error strings, where we test them, and avoiding `paystatus`. Other changes: 1. Completely get rid of `test_custom_notification_topics`: xpay tests do this already. 2. Add xpay wrapper to pyln-client so we can mix named and unnamed args. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
The main change here is the error messages got better. Where that was the case, and the test was not completely redundant with existing xpay tests, I explicitly converted to calls to xpay (meaning the tests will be kept when `pay` is finally removed). Test changes: 1. deschash checking is old-pay only, keep that there. 2. Add debug logs for checks for using forwarding via scid in injectpaymentonion. 3. Don't assert that not all sendpays should have the invoice string: xpay does not try to be clever there. 4. We no longer check if invoices are already paid before routing, since injectpaymentonion will catch that for us. 5. Removed `test_pay_get_error_with_update` which has xpay equiv. Changelog-Changed: JSON-RPC: `xpay` now handles `pay` command by default (use `xpay-handle-pay=false` to prevent this) Changelog-Removed: JSON-RPC: `exclude` parameter to `pay` (when `xpay-handle-pay` is True): craft a layer with desired modifications and pass it to `xpay` `layers`. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
If you don't use complex pay options, you can use `invstring` now and when xpay becomes pay, there's no transition. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Changed: JSON-RPC: `pay` now accepts `invstring` as a parameter name for `bolt11`, to ease transition when xpay takes over in v27.03.
Use xpay and listpays. Some tests which are pay/paystatus specific simply enabled deprecations. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-Deprecated: JSON-RPC: `pay` and `paystatus`: use `xpay`, `listpays` (or `xpay`'s notifications for details of attempts). `pay` will be replaced by `xpay` in v27.03.
Changelog-Deprecated: JSON-RPC: `getroute` (use `getroutes` with layers `["auto.localchans","auto.sourcefree"]` and `maxparts=1`) (since v25.09). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Deprecated: JSON-RPC: `keysend` (use `xkeysend`). `xkeysend` will take over `keysend` in v27.03. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This will help when we implement listpays (next) to be xpay-aware. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This will make life easier when we remove the pay plugin, but also fixes an issue where `listpays` can indicate ongoing payments are failed, even though xpay is still working on it. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
I think Eduardo and I stole all the best bits to make xpay and askrene. I simply enabled deprecations on all the renepay tests. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
fce4055 to
a9241d8
Compare