Skip to content

Commit 4066423

Browse files
committed
renepay: now calls getroutes
Changelog-EXPERIMENTAL: Renepay uses getroutes rpc to obtain payment routes. Signed-off-by: Lagrang3 <[email protected]>
1 parent 5ec5580 commit 4066423

File tree

1 file changed

+86
-44
lines changed

1 file changed

+86
-44
lines changed

plugins/renepay/mods.c

Lines changed: 86 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -632,9 +632,32 @@ REGISTER_PAYMENT_MODIFIER(routehints, routehints_cb);
632632
* Compute the payment routes.
633633
*/
634634

635-
static struct command_result *compute_routes_cb(struct payment *payment)
635+
static bool json_to_myroute(const char *buf, const jsmntok_t *tok,
636+
struct route *route)
637+
{
638+
u64 probability_ppm;
639+
const char *err =
640+
json_scan(tmpctx, buf, tok, "{probability_ppm:%,amount_msat:%}",
641+
JSON_SCAN(json_to_u64, &probability_ppm),
642+
JSON_SCAN(json_to_msat, &route->amount));
643+
if (err)
644+
return false;
645+
route->success_prob = probability_ppm * 1e-6;
646+
const jsmntok_t *path_tok = json_get_member(buf, tok, "path");
647+
if (!path_tok || path_tok->type != JSMN_ARRAY)
648+
return false;
649+
route->hops = json_to_route(route, buf, path_tok);
650+
if (!route->hops)
651+
return false;
652+
route->amount_sent = route->hops[0].amount;
653+
return true;
654+
}
655+
656+
static struct command_result *getroutes_done(struct command *cmd UNUSED,
657+
const char *buf,
658+
const jsmntok_t *result,
659+
struct payment *payment)
636660
{
637-
assert(payment->status == PAYMENT_PENDING);
638661
struct routetracker *routetracker = payment->routetracker;
639662
assert(routetracker);
640663

@@ -643,7 +666,49 @@ static struct command_result *compute_routes_cb(struct payment *payment)
643666
plugin_err(pay_plugin->plugin,
644667
"%s: no previously computed routes expected.",
645668
__func__);
669+
routetracker->computed_routes = tal_free(routetracker->computed_routes);
670+
671+
const jsmntok_t *routes_tok = json_get_member(buf, result, "routes");
672+
assert(routes_tok && routes_tok->type == JSMN_ARRAY);
646673

674+
routetracker->computed_routes =
675+
tal_arr(routetracker, struct route *, 0);
676+
677+
size_t i;
678+
const jsmntok_t *r;
679+
json_for_each_arr(i, r, routes_tok)
680+
{
681+
struct route *route = new_route(
682+
routetracker->computed_routes, payment->groupid,
683+
payment->next_partid++, payment->payment_info.payment_hash,
684+
AMOUNT_MSAT(0), AMOUNT_MSAT(0));
685+
assert(route);
686+
tal_arr_expand(&routetracker->computed_routes, route);
687+
bool success = json_to_myroute(buf, r, route);
688+
if (!success)
689+
plugin_err(pay_plugin->plugin,
690+
"%s: failed to parse route from json: %.*s",
691+
__func__, json_tok_full_len(r),
692+
json_tok_full(buf, r));
693+
const size_t pathlen = tal_count(route->hops);
694+
if (!amount_msat_eq(route->amount,
695+
route->hops[pathlen - 1].amount))
696+
plugin_log(pay_plugin->plugin, LOG_UNUSUAL,
697+
"%s: route partid=%" PRIu64
698+
" delivers %s which is different from what "
699+
"it claims to "
700+
"deliver %s",
701+
__func__, route->key.partid,
702+
fmt_amount_msat(
703+
tmpctx, route->hops[pathlen - 1].amount),
704+
fmt_amount_msat(tmpctx, route->amount));
705+
}
706+
return payment_continue(payment);
707+
}
708+
709+
static struct command_result *compute_routes_cb(struct payment *payment)
710+
{
711+
assert(payment->status == PAYMENT_PENDING);
647712
struct amount_msat feebudget, fees_spent, remaining;
648713

649714
/* Total feebudget */
@@ -674,48 +739,25 @@ static struct command_result *compute_routes_cb(struct payment *payment)
674739
return payment_continue(payment);
675740
}
676741

677-
enum jsonrpc_errcode errcode;
678-
const char *err_msg = NULL;
679-
680-
gossmap_apply_localmods(pay_plugin->gossmap, payment->local_gossmods);
681-
682-
/* get_routes returns the answer, we assign it to the computed_routes,
683-
* that's why we need to tal_free the older array. Maybe it would be
684-
* better to pass computed_routes as a reference? */
685-
routetracker->computed_routes = tal_free(routetracker->computed_routes);
686-
687-
// TODO: add an algorithm selector here
688-
/* We let this return an unlikely path, as it's better to try once than
689-
* simply refuse. Plus, models are not truth! */
690-
routetracker->computed_routes = get_routes(
691-
routetracker,
692-
&payment->payment_info,
693-
&pay_plugin->my_id,
694-
&payment->payment_info.destination,
695-
pay_plugin->gossmap,
696-
pay_plugin->uncertainty,
697-
payment->disabledmap,
698-
remaining,
699-
feebudget,
700-
&payment->next_partid,
701-
payment->groupid,
702-
&errcode,
703-
&err_msg);
704-
/* Otherwise the error message remains a child of the routetracker. */
705-
err_msg = tal_steal(tmpctx, err_msg);
706-
707-
gossmap_remove_localmods(pay_plugin->gossmap, payment->local_gossmods);
708-
709-
/* Couldn't feasible route, we stop. */
710-
if (!routetracker->computed_routes ||
711-
tal_count(routetracker->computed_routes) == 0) {
712-
if (err_msg == NULL)
713-
err_msg = tal_fmt(
714-
tmpctx, "get_routes returned NULL error message");
715-
return payment_fail(payment, errcode, "%s", err_msg);
716-
}
717-
718-
return payment_continue(payment);
742+
struct command *cmd = payment_command(payment);
743+
assert(cmd);
744+
struct out_req *req =
745+
jsonrpc_request_start(cmd->plugin, cmd, "getroutes", getroutes_done,
746+
payment_rpc_failure, payment);
747+
// FIXME: when multi-destination is needed to fully support blinded path
748+
// FIXME: we could have more than one algorithm to compute routes:
749+
// Minimum Cost Flows or the Max-Expected-Value (recently discussed with
750+
// Rene) or Dijkstra
751+
json_add_node_id(req->js, "source", &pay_plugin->my_id);
752+
json_add_node_id(req->js, "destination",
753+
&payment->payment_info.destination);
754+
json_add_amount_msat(req->js, "amount_msat", remaining);
755+
json_array_start(req->js, "layers");
756+
// FIXME: put here the layers that we use
757+
json_array_end(req->js);
758+
json_add_amount_msat(req->js, "maxfee_msat", feebudget);
759+
json_add_u32(req->js, "final_cltv", payment->payment_info.final_cltv);
760+
return send_outreq(cmd->plugin, req);
719761
}
720762

721763
REGISTER_PAYMENT_MODIFIER(compute_routes, compute_routes_cb);

0 commit comments

Comments
 (0)