Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions contrib/msggen/msggen/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -18584,10 +18584,12 @@
"A routing failure object has the fields below:",
"",
"*erring_index*: The index of the node along the route that reported the error. 0 for the local node, 1 for the first hop, and so on.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error.",
"*erring_channel*: The short channel ID of the channel that has the error, or *0:0:0* if the destination node raised the error.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error. This is inferred from the route, so it may be absent in rare cases.",
"*erring_channel*: The short channel ID of the channel that has the error. Only present if the channel is known.",
"*erring_direction*: The direction of traversing the *erring_channel*. Only present with *erring_channel*.",
"*failcode*: The failure code, as per BOLT #4.",
"*channel_update*: The hex string of the *channel_update* message received from the remote node. Only present if error is from the remote node and the *failcode* has the `UPDATE` bit set, as per BOLT #4."
"*failcodename*: The human-readable name corresponding to *failcode*, if known.",
"*raw_message*: The hex string of the raw failure message from the node that reported the error. Not present for failures that did not come from a node, such as a local routing failure."
],
"author": [
"Christian Decker [decker@blockstream.com](mailto:decker@blockstream.com) is mainly responsible."
Expand Down Expand Up @@ -32846,10 +32848,12 @@
"A routing failure object has the fields below:",
"",
"*erring_index*: The index of the node along the route that reported the error. 0 for the local node, 1 for the first hop, and so on.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error.",
"*erring_channel*: The short channel ID of the channel that has the error, or *0:0:0* if the destination node raised the error.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error. This is inferred from the route, so it may be absent in rare cases.",
"*erring_channel*: The short channel ID of the channel that has the error. Only present if the channel is known.",
"*erring_direction*: The direction of traversing the *erring_channel*. Only present with *erring_channel*.",
"*failcode*: The failure code, as per BOLT #4.",
"*channel_update*: The hex string of the *channel_update* message received from the remote node. Only present if error is from the remote node and the *failcode* has the UPDATE bit set, as per BOLT #4.",
"*failcodename*: The human-readable name corresponding to *failcode*, if known.",
"*raw_message*: The hex string of the raw failure message from the node that reported the error. Not present for failures that did not come from a node, such as a local routing failure.",
"",
"The *data* field of errors will include statistics *getroute_tries* and *sendpay_tries*. It will also contain a *failures* field with detailed data about routing errors."
],
Expand Down Expand Up @@ -35794,9 +35798,11 @@
"",
"*erring_index*: The index of the node along the route that reported the error. 0 for the local node, 1 for the first hop, and so on.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error.",
"*erring_channel*: The short channel ID of the channel that has the error, or *0:0:0* if the destination node raised the error. In addition *erring_direction* will indicate which direction of the channel caused the failure.",
"*erring_channel*: The short channel ID of the channel that has the error. Only present if the channel is known.",
"*erring_direction*: The direction of traversing the *erring_channel*. Only present with *erring_channel*.",
"*failcode*: The failure code, as per BOLT #4.",
"*channel_update*: The hex string of the *channel_update* message received from the remote node. Only present if error is from the remote node and the *failcode* has the UPDATE bit set, as per BOLT #4."
"*failcodename*: The human-readable name corresponding to *failcode*, if known.",
"*raw_message*: The hex string of the raw failure message from the node that reported the error. Not present for failures that did not come from a node, such as a local routing failure."
],
"author": [
"Rusty Russell [rusty@rustcorp.com.au](mailto:rusty@rustcorp.com.au) is mainly responsible."
Expand Down Expand Up @@ -40975,11 +40981,12 @@
"A routing failure object has the fields below:",
"",
"*erring_index*: The index of the node along the route that reported the error. 0 for the local node, 1 for the first hop, and so on.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error.",
"*erring_channel*: The short channel ID of the channel that has the error (or the final channel if the destination raised the error).",
"*erring_direction*: The direction of traversing the *erring_channel*:",
"*erring_node*: The hex string of the pubkey id of the node that reported the error. Only present if the node is known: a payment sent with **sendonion** does not record it.",
"*erring_channel*: The short channel ID of the channel that has the error. Only present if the channel is known.",
"*erring_direction*: The direction of traversing the *erring_channel*. Only present with *erring_channel*.",
"*failcode*: The failure code, as per BOLT #4.",
"*failcodename*: The human-readable name corresponding to *failcode*, if known."
"*failcodename*: The human-readable name corresponding to *failcode*, if known.",
"*raw_message*: The hex string of the raw failure message from the node that reported the error. Not present for failures that did not come from a node, such as a local routing failure."
],
"author": [
"ZmnSCPxj [ZmnSCPxj@protonmail.com](mailto:ZmnSCPxj@protonmail.com) is mainly responsible."
Expand Down Expand Up @@ -42905,7 +42912,7 @@
"erring_direction": {
"type": "u32",
"description": [
"The direction within the erring channel."
"The direction within the erring channel. Only present with *erring_channel*."
]
},
"raw_message": {
Expand Down
8 changes: 5 additions & 3 deletions doc/schemas/keysend.json
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,12 @@
"A routing failure object has the fields below:",
"",
"*erring_index*: The index of the node along the route that reported the error. 0 for the local node, 1 for the first hop, and so on.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error.",
"*erring_channel*: The short channel ID of the channel that has the error, or *0:0:0* if the destination node raised the error.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error. This is inferred from the route, so it may be absent in rare cases.",
"*erring_channel*: The short channel ID of the channel that has the error. Only present if the channel is known.",
"*erring_direction*: The direction of traversing the *erring_channel*. Only present with *erring_channel*.",
"*failcode*: The failure code, as per BOLT #4.",
"*channel_update*: The hex string of the *channel_update* message received from the remote node. Only present if error is from the remote node and the *failcode* has the `UPDATE` bit set, as per BOLT #4."
"*failcodename*: The human-readable name corresponding to *failcode*, if known.",
"*raw_message*: The hex string of the raw failure message from the node that reported the error. Not present for failures that did not come from a node, such as a local routing failure."
],
"author": [
"Christian Decker [decker@blockstream.com](mailto:decker@blockstream.com) is mainly responsible."
Expand Down
2 changes: 1 addition & 1 deletion doc/schemas/notification/sendpay_failure.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@
"erring_direction": {
"type": "u32",
"description": [
"The direction within the erring channel."
"The direction within the erring channel. Only present with *erring_channel*."
]
},
"raw_message": {
Expand Down
8 changes: 5 additions & 3 deletions doc/schemas/pay.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,12 @@
"A routing failure object has the fields below:",
"",
"*erring_index*: The index of the node along the route that reported the error. 0 for the local node, 1 for the first hop, and so on.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error.",
"*erring_channel*: The short channel ID of the channel that has the error, or *0:0:0* if the destination node raised the error.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error. This is inferred from the route, so it may be absent in rare cases.",
"*erring_channel*: The short channel ID of the channel that has the error. Only present if the channel is known.",
"*erring_direction*: The direction of traversing the *erring_channel*. Only present with *erring_channel*.",
"*failcode*: The failure code, as per BOLT #4.",
"*channel_update*: The hex string of the *channel_update* message received from the remote node. Only present if error is from the remote node and the *failcode* has the UPDATE bit set, as per BOLT #4.",
"*failcodename*: The human-readable name corresponding to *failcode*, if known.",
"*raw_message*: The hex string of the raw failure message from the node that reported the error. Not present for failures that did not come from a node, such as a local routing failure.",
"",
"The *data* field of errors will include statistics *getroute_tries* and *sendpay_tries*. It will also contain a *failures* field with detailed data about routing errors."
],
Expand Down
6 changes: 4 additions & 2 deletions doc/schemas/sendpay.json
Original file line number Diff line number Diff line change
Expand Up @@ -364,9 +364,11 @@
"",
"*erring_index*: The index of the node along the route that reported the error. 0 for the local node, 1 for the first hop, and so on.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error.",
"*erring_channel*: The short channel ID of the channel that has the error, or *0:0:0* if the destination node raised the error. In addition *erring_direction* will indicate which direction of the channel caused the failure.",
"*erring_channel*: The short channel ID of the channel that has the error. Only present if the channel is known.",
"*erring_direction*: The direction of traversing the *erring_channel*. Only present with *erring_channel*.",
"*failcode*: The failure code, as per BOLT #4.",
"*channel_update*: The hex string of the *channel_update* message received from the remote node. Only present if error is from the remote node and the *failcode* has the UPDATE bit set, as per BOLT #4."
"*failcodename*: The human-readable name corresponding to *failcode*, if known.",
"*raw_message*: The hex string of the raw failure message from the node that reported the error. Not present for failures that did not come from a node, such as a local routing failure."
],
"author": [
"Rusty Russell [rusty@rustcorp.com.au](mailto:rusty@rustcorp.com.au) is mainly responsible."
Expand Down
9 changes: 5 additions & 4 deletions doc/schemas/waitsendpay.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,12 @@
"A routing failure object has the fields below:",
"",
"*erring_index*: The index of the node along the route that reported the error. 0 for the local node, 1 for the first hop, and so on.",
"*erring_node*: The hex string of the pubkey id of the node that reported the error.",
"*erring_channel*: The short channel ID of the channel that has the error (or the final channel if the destination raised the error).",
"*erring_direction*: The direction of traversing the *erring_channel*:",
"*erring_node*: The hex string of the pubkey id of the node that reported the error. Only present if the node is known: a payment sent with **sendonion** does not record it.",
"*erring_channel*: The short channel ID of the channel that has the error. Only present if the channel is known.",
"*erring_direction*: The direction of traversing the *erring_channel*. Only present with *erring_channel*.",
"*failcode*: The failure code, as per BOLT #4.",
"*failcodename*: The human-readable name corresponding to *failcode*, if known."
"*failcodename*: The human-readable name corresponding to *failcode*, if known.",
"*raw_message*: The hex string of the raw failure message from the node that reported the error. Not present for failures that did not come from a node, such as a local routing failure."
],
"author": [
"ZmnSCPxj [ZmnSCPxj@protonmail.com](mailto:ZmnSCPxj@protonmail.com) is mainly responsible."
Expand Down
9 changes: 5 additions & 4 deletions lightningd/pay.c
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,7 @@ static struct command_result *wait_payment(struct lightningd *ld,
&faildirection,
&failmsg);
/* Old DB might not save failure information */
if (!failonionreply && !failnode) {
if (!failonionreply && !failnode && !failmsg) {
return command_fail(cmd, PAY_UNSPECIFIED_ERROR,
"Payment failure reason unknown");
} else if (failonionreply) {
Expand All @@ -732,13 +732,14 @@ static struct command_result *wait_payment(struct lightningd *ld,
NULL, faildetail),
NULL);
} else {
/* Parsed onion error, get its details */
assert(failnode);
/* Parsed onion error, get its details. A sendonion
* failure has no erring node, only the failmsg. */
assert(failnode || failmsg);
fail = tal(tmpctx, struct routing_failure);
fail->erring_index = failindex;
fail->failcode = failcode;
fail->erring_node =
tal_dup(fail, struct node_id, failnode);
tal_dup_or_null(fail, struct node_id, failnode);

if (failchannel) {
fail->erring_channel = tal_dup(
Expand Down
1 change: 1 addition & 0 deletions plugins/keysend.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ static struct command_result *keysend_cb(struct keysend_data *d, struct payment
featurebit method.*/

if (p->result != NULL &&
p->result->erring_node != NULL &&
node_id_eq(p->route_destination, p->result->erring_node) &&
p->result->failcode == WIRE_INVALID_ONION_PAYLOAD) {
return payment_abort(
Expand Down
15 changes: 14 additions & 1 deletion tests/test_pay.py
Original file line number Diff line number Diff line change
Expand Up @@ -3467,12 +3467,23 @@ def test_sendpay_msatoshi_arg(node_factory):
assert inv['amount_received_msat'] == Millisatoshi(1001)


def test_reject_invalid_payload(node_factory):
@pytest.mark.parametrize(
"wait_for_failure",
[
False,
True,
],
)
def test_reject_invalid_payload(node_factory, wait_for_failure):
"""Send an onion payload with an unknown even type.

Recipient l2 should reject it the incoming HTLC with an invalid onion
payload error.

With wait_for_failure, waitsendpay runs only after the sender has recorded
the failure, so it reads the failure from the database rather than from a
live waiter. That path used to report "Payment failure reason unknown".

"""

l1, l2 = node_factory.line_graph(2)
Expand All @@ -3491,6 +3502,8 @@ def test_reject_invalid_payload(node_factory):
first_hop=first_hop,
payment_hash=inv['payment_hash'],
shared_secrets=onion['shared_secrets'])
if wait_for_failure:
l1.daemon.wait_for_log(r'htlc failed from 0th node')
with pytest.raises(RpcError, match=r'WIRE_INVALID_ONION_PAYLOAD'):
l1.rpc.waitsendpay(inv['payment_hash'])

Expand Down
Loading