Skip to content

Commit b2fcf5f

Browse files
committed
renepay: use askrene API to for payment failures
The execution of the failure notification makes calls to askrene to disable or bias channels that have returned weird errors. Changelog-None. Signed-off-by: Lagrang3 <[email protected]>
1 parent dbccb8d commit b2fcf5f

File tree

1 file changed

+90
-69
lines changed

1 file changed

+90
-69
lines changed

plugins/renepay/routefail.c

Lines changed: 90 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,39 @@ enum node_type {
1414
};
1515

1616
struct routefail {
17-
struct command *cmd;
1817
struct payment *payment;
1918
struct route *route;
2019
};
2120

22-
static struct command_result *update_gossip(struct routefail *r);
23-
static struct command_result *handle_failure(struct routefail *r);
21+
static void update_gossip(struct command *cmd,
22+
struct request_batch *batch,
23+
struct routefail *r);
24+
25+
static void handle_failure(struct command *cmd,
26+
struct request_batch *batch,
27+
struct routefail *r);
28+
29+
static struct command_result *routefail_end(struct command *cmd,
30+
struct routefail *r)
31+
{
32+
/* Notify the tracker that route has failed and routefail have completed
33+
* handling all possible errors cases. */
34+
route_failure_register(r->payment->routetracker, r->route);
35+
r = tal_free(r);
36+
return notification_handled(cmd);
37+
}
38+
39+
static struct command_result *log_routefail_err(struct command *cmd,
40+
const char *method,
41+
const char *buf,
42+
const jsmntok_t *tok,
43+
struct routefail *r)
44+
{
45+
plugin_log(cmd->plugin, LOG_UNUSUAL,
46+
"routefail batch failed: %s failed: '%.*s'", method,
47+
json_tok_full_len(tok), json_tok_full(buf, tok));
48+
return command_still_pending(cmd);
49+
}
2450

2551
struct command_result *routefail_start(const tal_t *ctx, struct route *route,
2652
struct command *cmd)
@@ -38,20 +64,12 @@ struct command_result *routefail_start(const tal_t *ctx, struct route *route,
3864

3965
r->payment = payment;
4066
r->route = route;
41-
r->cmd = cmd;
42-
assert(route->result);
43-
return update_gossip(r);
44-
}
4567

46-
static struct command_result *routefail_end(struct routefail *r TAKES)
47-
{
48-
/* Notify the tracker that route has failed and routefail have completed
49-
* handling all possible errors cases. */
50-
struct command *cmd = r->cmd;
51-
route_failure_register(r->payment->routetracker, r->route);
52-
if (taken(r))
53-
r = tal_steal(tmpctx, r);
54-
return notification_handled(cmd);
68+
struct request_batch *batch =
69+
request_batch_new(cmd, NULL, log_routefail_err, routefail_end, r);
70+
update_gossip(cmd, batch, r);
71+
handle_failure(cmd, batch, r);
72+
return batch_done(cmd, batch);
5573
}
5674

5775
/*****************************************************************************
@@ -109,49 +127,9 @@ static u8 *channel_update_from_onion_error(const tal_t *ctx,
109127
return patch_channel_update(ctx, take(channel_update));
110128
}
111129

112-
static struct command_result *update_gossip_done(struct command *cmd UNUSED,
113-
const char *method UNUSED,
114-
const char *buf UNUSED,
115-
const jsmntok_t *result UNUSED,
116-
struct routefail *r)
117-
{
118-
return handle_failure(r);
119-
}
120-
121-
static struct command_result *update_gossip_failure(struct command *cmd UNUSED,
122-
const char *method UNUSED,
123-
const char *buf,
124-
const jsmntok_t *result,
125-
struct routefail *r)
126-
{
127-
assert(r);
128-
assert(r->payment);
129-
assert(r->route->result->erring_index);
130-
131-
const int index = *r->route->result->erring_index;
132-
struct short_channel_id_dir scidd;
133-
134-
if (r->route->result->erring_channel) {
135-
scidd.scid = *r->route->result->erring_channel;
136-
scidd.dir = *r->route->result->erring_direction;
137-
} else if (r->route->hops) {
138-
assert(index < tal_count(r->route->hops));
139-
const struct route_hop *hop = &r->route->hops[index];
140-
scidd.scid = hop->scid;
141-
scidd.dir = hop->direction;
142-
143-
} else /* don't have information to disable the erring channel */
144-
goto finish;
145-
146-
payment_disable_chan(
147-
r->payment, scidd, LOG_INFORM, "addgossip failed (%.*s)",
148-
json_tok_full_len(result), json_tok_full(buf, result));
149-
150-
finish:
151-
return update_gossip_done(cmd, method, buf, result, r);
152-
}
153-
154-
static struct command_result *update_gossip(struct routefail *r)
130+
static void update_gossip(struct command *cmd,
131+
struct request_batch *batch,
132+
struct routefail *r)
155133
{
156134
/* if there is no raw_message we continue */
157135
if (!r->route->result->raw_message)
@@ -163,14 +141,12 @@ static struct command_result *update_gossip(struct routefail *r)
163141
if (!update)
164142
goto skip_update_gossip;
165143

166-
struct out_req *req =
167-
jsonrpc_request_start(r->cmd, "addgossip",
168-
update_gossip_done, update_gossip_failure, r);
144+
struct out_req *req = add_to_batch(cmd, batch, "addgossip");
169145
json_add_hex_talarr(req->js, "message", update);
170-
return send_outreq(req);
146+
send_outreq(req);
171147

172148
skip_update_gossip:
173-
return handle_failure(r);
149+
return;
174150
}
175151

176152
/*****************************************************************************
@@ -198,8 +174,42 @@ static void route_final_error(struct route *route, enum jsonrpc_errcode error,
198174
route->final_msg = tal_strdup(route, what);
199175
}
200176

177+
static void disable_node(struct command *cmd, struct request_batch *batch,
178+
struct routefail *r, struct node_id *node)
179+
{
180+
struct out_req *req = add_to_batch(cmd, batch, "askrene-disable-node");
181+
json_add_string(req->js, "layer", r->payment->payment_layer);
182+
json_add_node_id(req->js, "node", node);
183+
send_outreq(req);
184+
}
185+
186+
static void disable_channel(struct command *cmd, struct request_batch *batch,
187+
struct routefail *r, struct short_channel_id_dir scidd)
188+
{
189+
struct out_req *req =
190+
add_to_batch(cmd, batch, "askrene-udpate-channel");
191+
json_add_string(req->js, "layer", r->payment->payment_layer);
192+
json_add_short_channel_id_dir(req->js, "short_channel_id_dir", scidd);
193+
json_add_bool(req->js, "enabled", false);
194+
send_outreq(req);
195+
}
196+
197+
static void bias_channel(struct command *cmd, struct request_batch *batch,
198+
struct routefail *r, struct short_channel_id_dir scidd,
199+
int bias)
200+
{
201+
// FIXME: we want to increment the bias, not set it
202+
struct out_req *req = add_to_batch(cmd, batch, "askrene-bias-channel");
203+
json_add_string(req->js, "layer", r->payment->payment_layer);
204+
json_add_short_channel_id_dir(req->js, "short_channel_id_dir", scidd);
205+
json_add_num(req->js, "bias", bias);
206+
send_outreq(req);
207+
}
208+
201209
/* FIXME: do proper error handling for BOLT12 */
202-
static struct command_result *handle_failure(struct routefail *r)
210+
static void handle_failure(struct command *cmd,
211+
struct request_batch *batch,
212+
struct routefail *r)
203213
{
204214
/* BOLT #4:
205215
*
@@ -322,6 +332,9 @@ static struct command_result *handle_failure(struct routefail *r)
322332
payment, route->hops[*result->erring_index].node_id,
323333
LOG_DBG, "received %s from previous hop",
324334
onion_wire_name(failcode));
335+
disable_node(
336+
cmd, batch, r,
337+
&route->hops[*result->erring_index].node_id);
325338
break;
326339
case UNKNOWN_NODE:
327340
break;
@@ -351,6 +364,9 @@ static struct command_result *handle_failure(struct routefail *r)
351364
route->hops[*result->erring_index - 1].node_id,
352365
LOG_INFORM, "received error %s",
353366
onion_wire_name(failcode));
367+
disable_node(
368+
cmd, batch, r,
369+
&route->hops[*result->erring_index - 1].node_id);
354370
break;
355371
case UNKNOWN_NODE:
356372
break;
@@ -399,6 +415,9 @@ static struct command_result *handle_failure(struct routefail *r)
399415
route->hops[*result->erring_index - 1].node_id,
400416
LOG_INFORM, "received error %s",
401417
onion_wire_name(failcode));
418+
disable_node(
419+
cmd, batch, r,
420+
&route->hops[*result->erring_index - 1].node_id);
402421
break;
403422
case UNKNOWN_NODE:
404423
break;
@@ -442,7 +461,7 @@ static struct command_result *handle_failure(struct routefail *r)
442461
.dir = route->hops[*result->erring_index].direction};
443462
payment_disable_chan(payment, scidd, LOG_INFORM, "%s",
444463
onion_wire_name(failcode));
445-
464+
disable_channel(cmd, batch, r, scidd);
446465
break;
447466
case UNKNOWN_NODE:
448467
break;
@@ -469,7 +488,9 @@ static struct command_result *handle_failure(struct routefail *r)
469488
route->hops[*result->erring_index - 1].node_id,
470489
LOG_INFORM, "received error %s",
471490
onion_wire_name(failcode));
472-
491+
disable_node(
492+
cmd, batch, r,
493+
&route->hops[*result->erring_index - 1].node_id);
473494
break;
474495
case ORIGIN_NODE:
475496
case FINAL_NODE:
@@ -518,7 +539,7 @@ static struct command_result *handle_failure(struct routefail *r)
518539
payment_warn_chan(payment, scidd, LOG_INFORM,
519540
"received error %s",
520541
onion_wire_name(failcode));
521-
542+
bias_channel(cmd, batch, r, scidd, -1);
522543
break;
523544
case UNKNOWN_NODE:
524545
break;
@@ -554,5 +575,5 @@ static struct command_result *handle_failure(struct routefail *r)
554575
}
555576

556577
finish:
557-
return routefail_end(take(r));
578+
return;
558579
}

0 commit comments

Comments
 (0)