Skip to content

Commit 797c3b1

Browse files
committed
renepay: use getroutes
Changelog-Added: renepay: use external call to [askrene-]getroutes instead of computing routes internally. Signed-off-by: Lagrang3 <[email protected]>
1 parent 6d142df commit 797c3b1

File tree

3 files changed

+160
-56
lines changed

3 files changed

+160
-56
lines changed

plugins/renepay/json.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,3 +393,58 @@ void json_myadd_blinded_path(struct json_stream *s,
393393
json_array_end(s);
394394
json_object_end(s);
395395
}
396+
397+
bool json_to_myroute(const char *buf,
398+
const jsmntok_t *tok,
399+
struct route *route)
400+
{
401+
u64 probability_ppm;
402+
u32 final_delay;
403+
const char *err = json_scan(
404+
tmpctx, buf, tok, "{probability_ppm:%,amount_msat:%,final_cltv:%}",
405+
JSON_SCAN(json_to_u64, &probability_ppm),
406+
JSON_SCAN(json_to_msat, &route->amount_deliver),
407+
JSON_SCAN(json_to_u32, &final_delay));
408+
409+
if (err)
410+
return false;
411+
route->success_prob = probability_ppm * 1e-6;
412+
const jsmntok_t *pathtok = json_get_member(buf, tok, "path");
413+
if (!pathtok || pathtok->type != JSMN_ARRAY)
414+
return false;
415+
416+
assert(route->hops == NULL);
417+
route->hops = tal_arr(route, struct route_hop, pathtok->size);
418+
size_t i;
419+
const jsmntok_t *hoptok;
420+
json_for_each_arr(i, hoptok, pathtok)
421+
{
422+
struct route_hop *hop = &route->hops[i];
423+
struct short_channel_id_dir scidd;
424+
struct amount_msat amount;
425+
u32 delay;
426+
err = json_scan(tmpctx, buf, hoptok,
427+
"{short_channel_id_dir:%,next_node_id:%,amount_msat:%,delay:%}",
428+
JSON_SCAN(json_to_short_channel_id_dir, &scidd),
429+
JSON_SCAN(json_to_node_id, &hop->node_id),
430+
JSON_SCAN(json_to_msat, &amount),
431+
JSON_SCAN(json_to_u32, &delay));
432+
if (err) {
433+
route->hops = tal_free(route->hops);
434+
return false;
435+
}
436+
hop->scid = scidd.scid;
437+
hop->direction = scidd.dir;
438+
439+
/* FIXME: this convention is so weird. If we ever get to merge
440+
* PR 7639, remember to remove this index adjustment. */
441+
if (i > 0) {
442+
route->hops[i - 1].amount = amount;
443+
route->hops[i - 1].delay = delay;
444+
}
445+
}
446+
route->hops[i - 1].amount = route->amount_deliver;
447+
route->hops[i - 1].delay = final_delay;
448+
route->amount_sent = route->hops[0].amount;
449+
return true;
450+
}

plugins/renepay/json.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,8 @@ void json_myadd_blinded_path(struct json_stream *s,
2525
const char *fieldname,
2626
const struct blinded_path *blinded_path);
2727

28+
bool json_to_myroute(const char *buf,
29+
const jsmntok_t *tok,
30+
struct route *route);
31+
2832
#endif /* LIGHTNING_PLUGINS_RENEPAY_JSON_H */

plugins/renepay/mods.c

Lines changed: 101 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -644,23 +644,79 @@ REGISTER_PAYMENT_MODIFIER(blindedhints, blindedhints_cb);
644644

645645

646646
/*****************************************************************************
647-
* compute_routes
647+
* getroutes
648648
*
649-
* Compute the payment routes.
649+
* Call askrene-getroutes
650650
*/
651651

652-
static struct command_result *compute_routes_cb(struct payment *payment)
652+
653+
static struct command_result *getroutes_done(struct command *cmd,
654+
const char *method,
655+
const char *buf,
656+
const jsmntok_t *tok,
657+
struct payment *payment)
653658
{
654-
assert(payment->status == PAYMENT_PENDING);
655659
struct routetracker *routetracker = payment->routetracker;
656660
assert(routetracker);
657661

658-
if (routetracker->computed_routes &&
659-
tal_count(routetracker->computed_routes))
662+
if (tal_count(routetracker->computed_routes) > 0)
660663
plugin_err(pay_plugin->plugin,
661664
"%s: no previously computed routes expected.",
662665
__func__);
663666

667+
routetracker->computed_routes = tal_free(routetracker->computed_routes);
668+
const jsmntok_t *routestok = json_get_member(buf, tok, "routes");
669+
assert(routestok && routestok->type == JSMN_ARRAY);
670+
routetracker->computed_routes =
671+
tal_arr(routetracker, struct route *, 0);
672+
673+
size_t i;
674+
const jsmntok_t *r;
675+
json_for_each_arr(i, r, routestok)
676+
{
677+
struct route *route = new_route(
678+
routetracker->computed_routes, payment->groupid,
679+
payment->next_partid++, payment->payment_info.payment_hash,
680+
AMOUNT_MSAT(0), AMOUNT_MSAT(0));
681+
tal_arr_expand(&routetracker->computed_routes, route);
682+
bool success = json_to_myroute(buf, r, route);
683+
if (!success) {
684+
plugin_err(
685+
pay_plugin->plugin,
686+
"%s: failed to parse route from getroutes, %.*s",
687+
__func__, json_tok_full_len(r),
688+
json_tok_full(buf, r));
689+
}
690+
assert(success);
691+
}
692+
return payment_continue(payment);
693+
}
694+
695+
static struct command_result *getroutes_fail(struct command *cmd,
696+
const char *method,
697+
const char *buf,
698+
const jsmntok_t *tok,
699+
struct payment *payment)
700+
{
701+
// FIXME: read the response
702+
// if can we do something about his failure:
703+
// disable channels or add biases
704+
// return payment_continue(payment);
705+
// else:
706+
// return payment_fail(payment, PAY_STOPPED_RETRYING, "getroutes
707+
// failed to find a feasible solution %s", explain_error(buf,
708+
// tok));
709+
const jsmntok_t *messtok = json_get_member(buf, tok, "message");
710+
assert(messtok);
711+
return payment_fail(
712+
payment, PAYMENT_PENDING,
713+
"getroutes failed to find a feasible solution: %.*s",
714+
json_tok_full_len(messtok), json_tok_full(buf, messtok));
715+
}
716+
717+
static struct command_result *getroutes_cb(struct payment *payment)
718+
{
719+
assert(payment->status == PAYMENT_PENDING);
664720
struct amount_msat feebudget, fees_spent, remaining;
665721

666722
/* Total feebudget */
@@ -691,57 +747,46 @@ static struct command_result *compute_routes_cb(struct payment *payment)
691747
return payment_continue(payment);
692748
}
693749

694-
enum jsonrpc_errcode errcode;
695-
const char *err_msg = NULL;
696-
697-
gossmap_apply_localmods(pay_plugin->gossmap, payment->local_gossmods);
698-
699-
/* get_routes returns the answer, we assign it to the computed_routes,
700-
* that's why we need to tal_free the older array. Maybe it would be
701-
* better to pass computed_routes as a reference? */
702-
routetracker->computed_routes = tal_free(routetracker->computed_routes);
703-
704-
/* Send get_routes a note that it should discard the last hop because we
705-
* are actually solving a multiple destinations problem. */
706-
bool blinded_destination = true;
707-
708-
// TODO: add an algorithm selector here
709-
/* We let this return an unlikely path, as it's better to try once than
710-
* simply refuse. Plus, models are not truth! */
711-
routetracker->computed_routes = get_routes(
712-
routetracker,
713-
&payment->payment_info,
714-
&pay_plugin->my_id,
715-
payment->routing_destination,
716-
pay_plugin->gossmap,
717-
pay_plugin->uncertainty,
718-
payment->disabledmap,
719-
remaining,
720-
feebudget,
721-
&payment->next_partid,
722-
payment->groupid,
723-
blinded_destination,
724-
&errcode,
725-
&err_msg);
726-
727-
/* Otherwise the error message remains a child of the routetracker. */
728-
err_msg = tal_steal(tmpctx, err_msg);
729-
730-
gossmap_remove_localmods(pay_plugin->gossmap, payment->local_gossmods);
731-
732-
/* Couldn't feasible route, we stop. */
733-
if (!routetracker->computed_routes ||
734-
tal_count(routetracker->computed_routes) == 0) {
735-
if (err_msg == NULL)
736-
err_msg = tal_fmt(
737-
tmpctx, "get_routes returned NULL error message");
738-
return payment_fail(payment, errcode, "%s", err_msg);
739-
}
740-
741-
return payment_continue(payment);
750+
/* FIXME:
751+
* call getroutes:
752+
* input: source, destination, amount, maxfee, final_cltv,
753+
* maxdelay, layers: [auto.localchans, auto.sourcefree,
754+
* thispaymenthints, thispaymentexclude, renepayknowledge]
755+
*
756+
* possible outcomes:
757+
* success: then continue
758+
* fail with hint: try to fix and retry or fail payment
759+
* */
760+
struct command *cmd = payment_command(payment);
761+
struct out_req *req = jsonrpc_request_start(
762+
cmd, "getroutes", getroutes_done, getroutes_fail, payment);
763+
764+
// FIXME: add an algorithm selection in askrene such that we could
765+
// retrieve a single path route if necessary, see issue 8042
766+
// FIXME: register layers before using then:
767+
// -> register RENEPAY_LAYER on plugin startup
768+
// -> register payment->payment_layer when payment is created
769+
// -> payment_layer should auto clean
770+
// -> register payment->command_layer when the payment execution
771+
// starts
772+
// -> command_layer should auto clean
773+
774+
json_add_node_id(req->js, "source", &pay_plugin->my_id);
775+
json_add_node_id(req->js, "destination", payment->routing_destination);
776+
json_add_amount_msat(req->js, "amount_msat", remaining);
777+
json_add_amount_msat(req->js, "maxfee_msat", feebudget);
778+
json_add_u32(req->js, "final_cltv", payment->payment_info.final_cltv);
779+
json_array_start(req->js, "layers");
780+
json_add_string(req->js, NULL, "auto.localchans");
781+
json_add_string(req->js, NULL, "auto.sourcefree");
782+
json_array_end(req->js);
783+
// FIXME: add further constraints here if necessary when they become
784+
// available in getroutes
785+
// eg. json_add_u32(req->js, "maxdelay", payment->payment_info.maxdelay);
786+
return send_outreq(req);
742787
}
743788

744-
REGISTER_PAYMENT_MODIFIER(compute_routes, compute_routes_cb);
789+
REGISTER_PAYMENT_MODIFIER(getroutes, getroutes_cb);
745790

746791
/*****************************************************************************
747792
* send_routes
@@ -1270,7 +1315,7 @@ void *payment_virtual_program[] = {
12701315
/*16*/ OP_CALL, &pendingsendpays_pay_mod,
12711316
/*18*/ OP_CALL, &checktimeout_pay_mod,
12721317
/*20*/ OP_CALL, &refreshgossmap_pay_mod,
1273-
/*22*/ OP_CALL, &compute_routes_pay_mod,
1318+
/*22*/ OP_CALL, &getroutes_pay_mod,
12741319
/*24*/ OP_CALL, &send_routes_pay_mod,
12751320
/*do*/
12761321
/*26*/ OP_CALL, &sleep_pay_mod,

0 commit comments

Comments
 (0)