Skip to content

Commit 94be50d

Browse files
committed
renepay: fix error handling
Fix error handling since we moved from sendpay to sendonion rpc. With sendonion once a route fails we don't get the scid and node_id that failed along the route, so we have to deduce those from our own internal data. Changelog-None Signed-off-by: Lagrang3 <[email protected]>
1 parent 6685f51 commit 94be50d

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

plugins/renepay/routefail.c

+53
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct routefail {
2121

2222
static struct command_result *update_gossip(struct routefail *r);
2323
static struct command_result *handle_failure(struct routefail *r);
24+
static void find_erring_node(struct route *route);
2425

2526
struct command_result *routefail_start(const tal_t *ctx, struct route *route,
2627
struct command *cmd)
@@ -40,9 +41,60 @@ struct command_result *routefail_start(const tal_t *ctx, struct route *route,
4041
r->route = route;
4142
r->cmd = cmd;
4243
assert(route->result);
44+
find_erring_node(route);
4345
return update_gossip(r);
4446
}
4547

48+
/* The erring_node and erring_channel are necessary fields to handle the error.
49+
* We might not know those values from listsendpays because the payment could
50+
* have been paid with sendonion or similar RPCs, but if we know the route then
51+
* we can deduce them just like lightningd's wallet would with a sendpay
52+
* command. */
53+
static void find_erring_node(struct route *route)
54+
{
55+
struct payment_result *result = route->result;
56+
if (result->erring_node && result->erring_channel &&
57+
result->erring_direction)
58+
return;
59+
60+
/* we need the hops, othewise our assumptions are wrong */
61+
assert(route->hops);
62+
assert(result->erring_index);
63+
unsigned int index = *result->erring_index;
64+
unsigned int path_len = tal_count(route->hops);
65+
66+
/* self-pay failure? */
67+
assert(path_len > 0);
68+
assert(index >= 0);
69+
assert(path_len >= index);
70+
71+
if (index == path_len - 1) {
72+
result->erring_channel = tal_dup(
73+
result, struct short_channel_id, &route->hops[index].scid);
74+
result->erring_direction =
75+
tal_dup(result, int, &route->hops[index].direction);
76+
result->erring_node = tal_dup(result, struct node_id,
77+
&route->hops[index].node_id);
78+
} else {
79+
result->erring_channel =
80+
tal_dup(result, struct short_channel_id,
81+
&route->hops[index + 1].scid);
82+
result->erring_direction =
83+
tal_dup(result, int, &route->hops[index + 1].direction);
84+
85+
/* If the error is a BADONION, then it's on behalf of the
86+
* following node. */
87+
if (result->failcode & BADONION)
88+
result->erring_node =
89+
tal_dup(result, struct node_id,
90+
&route->hops[index + 1].node_id);
91+
else
92+
result->erring_node =
93+
tal_dup(result, struct node_id,
94+
&route->hops[index].node_id);
95+
}
96+
}
97+
4698
static struct command_result *routefail_end(struct routefail *r TAKES)
4799
{
48100
/* Notify the tracker that route has failed and routefail have completed
@@ -188,6 +240,7 @@ static void route_final_error(struct route *route, enum jsonrpc_errcode error,
188240
route->final_msg = tal_strdup(route, what);
189241
}
190242

243+
/* FIXME: do proper error handling for BOLT12 */
191244
static struct command_result *handle_failure(struct routefail *r)
192245
{
193246
/* BOLT #4:

0 commit comments

Comments
 (0)