From 96c2f520f265060948bca208e46f9f14195058c7 Mon Sep 17 00:00:00 2001 From: Lagrang3 Date: Mon, 15 Jun 2026 13:43:01 +0100 Subject: [PATCH 1/2] askrene-getroutes: add test for source==destination Changelog-None Signed-off-by: Lagrang3 --- tests/test_askrene.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/test_askrene.py b/tests/test_askrene.py index 9fbc9e708672..6d05583f600f 100644 --- a/tests/test_askrene.py +++ b/tests/test_askrene.py @@ -2667,3 +2667,45 @@ def test_impossible_payment(node_factory): final_cltv=5, maxparts=1, ) + + +@pytest.mark.xfail(strict=True) +def test_bad_user_entries(node_factory): + """Test bad user entries that should result in an RPC error and not crash + lightningd.""" + l1 = node_factory.get_node() + node1 = "020000000000000000000000000000000000000000000000000000000000000001" + node2 = "020000000000000000000000000000000000000000000000000000000000000002" + million_sats = 1000000000 + l1.rpc.askrene_create_layer("mylayer") + l1.rpc.askrene_create_channel( + layer="mylayer", + source=node1, + destination=node2, + short_channel_id="0x0x1", + capacity_msat=million_sats, + ) + l1.rpc.askrene_update_channel( + layer="mylayer", + short_channel_id_dir="0x0x1/0", + enabled=True, + htlc_minimum_msat=0, + htlc_maximum_msat=million_sats, + fee_base_msat=0, + fee_proportional_millionths=0, + cltv_expiry_delta=18, + ) + + # Try querying getroutes with source==destination + with pytest.raises( + RpcError, + match=r"source and destination must be different", + ): + l1.rpc.getroutes( + source=node1, + destination=node1, + amount_msat=1000, + layers=["mylayer"], + maxfee_msat=2000, + final_cltv=5, + ) From 66722a27d6a6bee348f531327e36b132c4a871d9 Mon Sep 17 00:00:00 2001 From: Lagrang3 Date: Mon, 15 Jun 2026 13:43:55 +0100 Subject: [PATCH 2/2] getroutes: don't crash on source==destination ``` cln-askrene: plugins/askrene/child/child.c:40: final_hop: Assertion `tal_count(hops) > 0' failed. cln-askrene: FATAL SIGNAL 6 (version v26.06-19-g46b039d) lightningd-1 2026-06-15T12:34:26.296Z DEBUG plugin-cln-askrene: notify msg debug: Final answer has 1 flows 0x55ab65429902 send_backtrace common/daemon.c:38 0x55ab6542998c crashdump common/daemon.c:83 0x7fbc84a8bdef ??? ./signal/../sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0 0x7fbc84ae095c __pthread_kill_implementation ./nptl/pthread_kill.c:44 0x7fbc84a8bcc1 __GI_raise ../sysdeps/posix/raise.c:26 0x7fbc84a744ab __GI_abort ./stdlib/abort.c:77 0x7fbc84a7441f __assert_fail_base ./assert/assert.c:118 0x55ab6541b60c final_hop plugins/askrene/child/child.c:40 0x55ab6541b70d fmt_route plugins/askrene/child/child.c:48 0x55ab6541ba5b convert_flows_to_routes plugins/askrene/child/child.c:135 0x55ab6541c037 run_child plugins/askrene/child/child.c:265 0x55ab65416caa do_getroutes plugins/askrene/askrene.c:711 0x55ab65416d28 begin_request plugins/askrene/askrene.c:887 0x55ab654170a2 json_getroutes plugins/askrene/askrene.c:968 0x55ab654285ec ld_command_handle plugins/libplugin.c:2206 0x55ab654287f6 ld_read_json plugins/libplugin.c:2282 0x55ab65439261 next_plan ccan/ccan/io/io.c:60 0x55ab65439580 do_plan ccan/ccan/io/io.c:422 0x55ab65439639 io_ready ccan/ccan/io/io.c:439 0x55ab6543a5fc io_loop ccan/ccan/io/poll.c:470 0x55ab65428bc4 plugin_main plugins/libplugin.c:2481 0x55ab65417491 main plugins/askrene/askrene.c:1551 0x7fbc84a75ca7 __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 0x7fbc84a75d64 __libc_start_main_impl ../csu/libc-start.c:360 0x55ab65413920 ??? _start+0x20:0 0xffffffffffffffff ??? ???:0 ``` Changelog-Fixed: askrene-getroutes: don't crash on invalid user input, source==destination Signed-off-by: Lagrang3 --- plugins/askrene/askrene.c | 5 +++++ tests/test_askrene.py | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/askrene/askrene.c b/plugins/askrene/askrene.c index 736054ebab7b..70247c1ea189 100644 --- a/plugins/askrene/askrene.c +++ b/plugins/askrene/askrene.c @@ -943,6 +943,11 @@ static struct command_result *json_getroutes(struct command *cmd, maxdelay_allowed); } + if (node_id_eq(source, dest)) { + return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + "source and destination must be different"); + } + if (command_check_only(cmd)) return command_check_done(cmd); diff --git a/tests/test_askrene.py b/tests/test_askrene.py index 6d05583f600f..4474ec321dfe 100644 --- a/tests/test_askrene.py +++ b/tests/test_askrene.py @@ -2669,7 +2669,6 @@ def test_impossible_payment(node_factory): ) -@pytest.mark.xfail(strict=True) def test_bad_user_entries(node_factory): """Test bad user entries that should result in an RPC error and not crash lightningd."""