Repository navigation
lightningd: fix 209 "Payment failure reason unknown" for sendonion payments - #9623
Open
daywalker90 wants to merge 4 commits into
Open
daywalker90 wants to merge 4 commits into
daywalker90 wants to merge 4 commits into
Conversation
A sendonion payment whose remote failure is recorded before waitsendpay
is called reports "Payment failure reason unknown" (code 209) instead of
the failure. The CI ASan/UBSan shard failed test_reject_invalid_payload
this way:
RpcError: RPC call failed: method: waitsendpay, ... error: {'code': 209,
'message': 'Payment failure reason unknown'}
test_reject_invalid_payload now takes a wait_for_failure parameter. When
it is set, the test waits for the sender to log "htlc failed from 0th
node" before calling waitsendpay, so the call reads the failure from the
database rather than from a live waiter. The unset case is the original
test and passes either way. The set case is marked xfail(strict=True)
until the fix lands in the next commit.
Changelog-None
Signed-off-by: daywalker90 <daywalker990@gmx.de>
…e fact
A sendonion payment has no route nodes, so remote_routing_failure() sets
no erring node, and payment_failed() stores failonion as NULL. The
failure is still stored with its failcode and raw failmsg. wait_payment()
only looked at failonionreply and failnode, so a waitsendpay() that ran
after the failure was recorded reported:
RpcError: ... error: {'code': 209, 'message': 'Payment failure reason unknown'}
A waitsendpay() that ran before the failure got the failure from the live
waiter and was correct, so the error only showed up when the call lost the
race. wait_payment() now uses the stored failmsg as the remote failure
when there is no erring node, the same way the live path does. The
"reason unknown" error is kept for databases with no failure information.
Changelog-Fixed: waitsendpay reports the remote failure for sendonion payments that failed before the call, instead of "Payment failure reason unknown"
Signed-off-by: daywalker90 <daywalker990@gmx.de>
… waitsendpay The routing failure objects described fields the code does not send, and called other fields always present when they are not: - erring_node: waitsendpay on a payment sent with sendonion does not record the node. pay and keysend infer it from their route, so it may be absent in rare cases. - erring_channel: the daemon omits it when the channel is not known. The "or 0:0:0" text described a value that is never sent. - erring_direction: only sent together with erring_channel. Documented for all four commands and the sendpay_failure notification. - channel_update: not sent in the routing failure object. The field that carries the remote message is raw_message, which is now documented. It is not present for failures that did not come from a node, such as a local routing failure or the pay "ran out of routes" failure. - failcodename: documented for pay, keysend and sendpay, where it is omitted for unknown failcodes. sendpay always has the route it was given, so its erring_node text is unchanged. The sendpay_failure notification already marked erring_node and erring_channel as "if known". contrib/msggen/msggen/schema.json is regenerated from the schemas by make gen. Changelog-None Signed-off-by: daywalker90 <daywalker990@gmx.de>
keysend compares the failing node with the destination before it reads the failcode. The plugin only fills erring_node from the route when the daemon reports an erring_index inside the route, so the field can be NULL. Check for NULL before the comparison. This is defensive: the current code paths I checked always set erring_node for keysend, so no test covers this. It prevents a NULL dereference if that invariant changes. Changelog-None Signed-off-by: daywalker90 <daywalker990@gmx.de>
cdecker
approved these changes
Oct 14, 2026
cdecker
enabled auto-merge (rebase)
October 14, 2026 10:09
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Saw this during a CI run:
Also cleaned up related docs for routing failure object.