askrene: make "child.c" to be the explicit child entry point.
What changed, and why it matters
This commit is a straightforward internal code reorganization in Core Lightning's routing plugin (askrene). It moves the fork() logic from a dedicated child entry file into the main askrene.c file and renames the child entry point. There is no change to security-sensitive behavior, no bug fix, and no disclosed vulnerability.
No security action needed. Treat as normal refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors askrene’s parent/child process split. Previously, fork_router_child() in child/entry.c created pipes, forked, and ran the routing algorithm in the child. Now, askrene.c performs the fork() and pipe setup directly, then calls run_child() in the new child/child.c. The child algorithm code is otherwise unchanged. The Makefile is updated to compile child.c instead of entry.c, and entry.h is replaced with child.h. This is a structural cleanup, not a functional or security patch.
Changed components
plugins/askrene/askrene.cplugins/askrene/child/child.cplugins/askrene/child/child.hplugins/askrene/MakefileInspect captured patch +365 / −377
diff --git a/plugins/askrene/Makefile b/plugins/askrene/Makefile
index d676624e..29205911 100644
--- a/plugins/askrene/Makefile
+++ b/plugins/askrene/Makefile
@@ -2,10 +2,10 @@ PLUGIN_ASKRENE_PARENT_SRC := \
plugins/askrene/askrene.c \
plugins/askrene/datastore_wire.c \
plugins/askrene/layer.c \
- plugins/askrene/reserve.c \
+ plugins/askrene/reserve.c
PLUGIN_ASKRENE_CHILD_SRC := \
- plugins/askrene/child/entry.c \
+ plugins/askrene/child/child.c \
plugins/askrene/child/mcf.c \
plugins/askrene/child/dijkstra.c \
plugins/askrene/child/flow.c \
diff --git a/plugins/askrene/askrene.c b/plugins/askrene/askrene.c
index 4910b858..a5709c12 100644
--- a/plugins/askrene/askrene.c
+++ b/plugins/askrene/askrene.c
@@ -8,6 +8,7 @@
*/
#include "config.h"
#include <ccan/array_size/array_size.h>
+#include <ccan/noerr/noerr.h>
#include <ccan/tal/grab_file/grab_file.h>
#include <ccan/tal/str/str.h>
#include <common/clock_time.h>
@@ -24,7 +25,8 @@
#include <math.h>
#include <plugins/askrene/askrene.h>
#include <plugins/askrene/child/additional_costs.h>
-#include <plugins/askrene/child/entry.h>
+#include <plugins/askrene/child/child.h>
+#include <plugins/askrene/child/child_log.h>
#include <plugins/askrene/layer.h>
#include <plugins/askrene/reserve.h>
#include <sys/wait.h>
@@ -522,12 +524,11 @@ static struct command_result *do_getroutes(struct command *cmd,
bool include_fees;
const char *err;
struct timemono deadline;
- int child_fd, log_fd;
+ int replyfds[2], logfds[2];
struct router_child *child;
const struct layer **layers;
s8 *biases;
fp16_t *capacities;
- int ecode;
/* update the gossmap */
if (gossmap_refresh(askrene->gossmap)) {
@@ -625,31 +626,56 @@ static struct command_result *do_getroutes(struct command *cmd,
child->start = time_mono();
deadline = timemono_add(child->start,
time_from_sec(askrene->route_seconds));
- child_fd = fork_router_child(askrene->gossmap,
- layers,
- biases,
- info->additional_costs,
- askrene->reserved,
- take(capacities),
- info->dev_algo == ALGO_SINGLE_PATH,
- deadline, srcnode, dstnode, info->amount,
- info->maxfee, info->finalcltv, info->maxdelay, info->maxparts,
- include_fees,
- cmd->id, cmd->filter, &log_fd, &child->pid);
- /* Save this, as remove_localmods won't preserve it. */
- ecode = errno;
- /* We don't need this any more. */
- gossmap_remove_localmods(askrene->gossmap, localmods);
- if (child_fd == -1) {
- err = tal_fmt(tmpctx, "failed to fork: %s", strerror(ecode));
- gossmap_remove_localmods(askrene->gossmap, localmods);
+ if (pipe(replyfds) != 0) {
+ err = tal_fmt(tmpctx, "failed to create pipes: %s", strerror(errno));
+ goto fail_broken;
+ }
+ if (pipe(logfds) != 0) {
+ err = tal_fmt(tmpctx, "failed to create pipes: %s", strerror(errno));
+ close_noerr(replyfds[0]);
+ close_noerr(replyfds[1]);
+ goto fail_broken;
+ }
+ child->pid = fork();
+ if (child->pid < 0) {
+ err = tal_fmt(tmpctx, "failed to fork: %s", strerror(errno));
+ close_noerr(replyfds[0]);
+ close_noerr(replyfds[1]);
+ close_noerr(logfds[0]);
+ close_noerr(logfds[1]);
goto fail_broken;
}
- child->reply_conn = io_new_conn(child, child_fd,
+ if (child->pid == 0) {
+ /* We are the child. Run the algo */
+ close(logfds[0]);
+ close(replyfds[0]);
+ set_child_log_fd(logfds[1]);
+
+ /* Does not return! */
+ run_child(askrene->gossmap,
+ layers,
+ biases,
+ info->additional_costs,
+ askrene->reserved,
+ take(capacities),
+ info->dev_algo == ALGO_SINGLE_PATH,
+ deadline, srcnode, dstnode, info->amount,
+ info->maxfee, info->finalcltv, info->maxdelay, info->maxparts,
+ include_fees,
+ cmd->id, cmd->filter, replyfds[1]);
+ abort();
+ }
+
+ close(logfds[1]);
+ close(replyfds[1]);
+
+ /* We don't need this any more. */
+ gossmap_remove_localmods(askrene->gossmap, localmods);
+ child->reply_conn = io_new_conn(child, replyfds[0],
child_reply_init, child);
- child->log_conn = io_new_conn(child, log_fd, child_log_init, child);
+ child->log_conn = io_new_conn(child, logfds[0], child_log_init, child);
child->cmd = cmd;
list_add_tail(&askrene->children, &child->list);
diff --git a/plugins/askrene/child/child.c b/plugins/askrene/child/child.c
new file mode 100644
index 00000000..8a4363d5
--- /dev/null
+++ b/plugins/askrene/child/child.c
@@ -0,0 +1,278 @@
+#include "config.h"
+#include <assert.h>
+#include <ccan/json_out/json_out.h>
+#include <ccan/read_write_all/read_write_all.h>
+#include <ccan/tal/str/str.h>
+#include <common/json_stream.h>
+#include <common/route.h>
+#include <common/utils.h>
+#include <plugins/askrene/child/child.h>
+#include <plugins/askrene/child/child_log.h>
+#include <plugins/askrene/child/flow.h>
+#include <plugins/askrene/child/mcf.h>
+#include <plugins/askrene/child/route_query.h>
+
+/* A single route. */
+struct route {
+ /* Actual path to take */
+ struct route_hop *hops;
+ /* Probability estimate (0-1) */
+ double success_prob;
+};
+
+static const char *fmt_route(const tal_t *ctx,
+ const struct route *route,
+ struct amount_msat delivers,
+ u32 final_cltv)
+{
+ char *str = tal_strdup(ctx, "");
+
+ for (size_t i = 0; i < tal_count(route->hops); i++) {
+ struct short_channel_id_dir scidd;
+ scidd.scid = route->hops[i].scid;
+ scidd.dir = route->hops[i].direction;
+ tal_append_fmt(&str, "%s/%u %s -> ",
+ fmt_amount_msat(tmpctx, route->hops[i].amount),
+ route->hops[i].delay,
+ fmt_short_channel_id_dir(tmpctx, &scidd));
+ }
+ tal_append_fmt(&str, "%s/%u",
+ fmt_amount_msat(tmpctx, delivers), final_cltv);
+ return str;
+}
+
+/* Convert back into routes, with delay and other information fixed */
+static struct route **convert_flows_to_routes(const tal_t *ctx,
+ struct route_query *rq,
+ u32 finalcltv,
+ struct flow **flows,
+ struct amount_msat **amounts,
+ bool include_fees)
+{
+ struct route **routes;
+ routes = tal_arr(ctx, struct route *, tal_count(flows));
+ *amounts = tal_arr(ctx, struct amount_msat, tal_count(flows));
+
+ for (size_t i = 0; i < tal_count(flows); i++) {
+ struct route *r;
+ struct amount_msat msat;
+ u32 delay;
+
+ routes[i] = r = tal(routes, struct route);
+ r->success_prob = flow_probability(flows[i], rq);
+ r->hops = tal_arr(r, struct route_hop, tal_count(flows[i]->path));
+
+ msat = flows[i]->delivers;
+ delay = finalcltv;
+
+ if (!include_fees) {
+ /* Fill in backwards to calc amount and delay */
+ for (int j = tal_count(flows[i]->path) - 1; j >= 0;
+ j--) {
+ struct route_hop *rh = &r->hops[j];
+ struct gossmap_node *far_end;
+ const struct half_chan *h =
+ flow_edge(flows[i], j);
+
+ if (!amount_msat_add_fee(&msat, h->base_fee,
+ h->proportional_fee))
+ abort();
+ delay += h->delay;
+
+ rh->scid = gossmap_chan_scid(rq->gossmap,
+ flows[i]->path[j]);
+ rh->direction = flows[i]->dirs[j];
+ far_end = gossmap_nth_node(rq->gossmap,
+ flows[i]->path[j],
+ !flows[i]->dirs[j]);
+ gossmap_node_get_id(rq->gossmap, far_end,
+ &rh->node_id);
+ rh->amount = msat;
+ rh->delay = delay;
+ }
+ (*amounts)[i] = flows[i]->delivers;
+ } else {
+ /* Fill in backwards to calc delay */
+ for (int j = tal_count(flows[i]->path) - 1; j >= 0;
+ j--) {
+ struct route_hop *rh = &r->hops[j];
+ struct gossmap_node *far_end;
+ const struct half_chan *h =
+ flow_edge(flows[i], j);
+
+ delay += h->delay;
+
+ rh->scid = gossmap_chan_scid(rq->gossmap,
+ flows[i]->path[j]);
+ rh->direction = flows[i]->dirs[j];
+ far_end = gossmap_nth_node(rq->gossmap,
+ flows[i]->path[j],
+ !flows[i]->dirs[j]);
+ gossmap_node_get_id(rq->gossmap, far_end,
+ &rh->node_id);
+ rh->delay = delay;
+ }
+ /* Compute fees forward */
+ for (int j = 0; j < tal_count(flows[i]->path); j++) {
+ struct route_hop *rh = &r->hops[j];
+ const struct half_chan *h =
+ flow_edge(flows[i], j);
+
+ rh->amount = msat;
+ msat = amount_msat_sub_fee(msat, h->base_fee,
+ h->proportional_fee);
+ }
+ (*amounts)[i] = msat;
+ }
+
+ child_log(tmpctx, LOG_INFORM, "Flow %zu/%zu: %s",
+ i, tal_count(flows),
+ fmt_route(tmpctx, r, (*amounts)[i], finalcltv));
+ }
+
+ return routes;
+}
+
+static void json_add_getroutes(struct json_stream *js,
+ struct route **routes,
+ const struct amount_msat *amounts,
+ double probability,
+ u32 final_cltv)
+{
+ json_add_u64(js, "probability_ppm", (u64)(probability * 1000000));
+ json_array_start(js, "routes");
+ for (size_t i = 0; i < tal_count(routes); i++) {
+ json_object_start(js, NULL);
+ json_add_u64(js, "probability_ppm",
+ (u64)(routes[i]->success_prob * 1000000));
+ json_add_amount_msat(js, "amount_msat", amounts[i]);
+ json_add_u32(js, "final_cltv", final_cltv);
+ json_array_start(js, "path");
+ for (size_t j = 0; j < tal_count(routes[i]->hops); j++) {
+ struct short_channel_id_dir scidd;
+ const struct route_hop *r = &routes[i]->hops[j];
+ json_object_start(js, NULL);
+ scidd.scid = r->scid;
+ scidd.dir = r->direction;
+ json_add_short_channel_id_dir(
+ js, "short_channel_id_dir", scidd);
+ json_add_node_id(js, "next_node_id", &r->node_id);
+ json_add_amount_msat(js, "amount_msat", r->amount);
+ json_add_u32(js, "delay", r->delay);
+ json_object_end(js);
+ }
+ json_array_end(js);
+ json_object_end(js);
+ }
+ json_array_end(js);
+}
+
+
+static struct route_query *new_route_query(const tal_t *ctx,
+ const struct gossmap *gossmap,
+ const char *cmd_id,
+ const struct layer **layers,
+ const s8 *biases,
+ const struct additional_cost_htable *additional_costs,
+ struct reserve_htable *reserved,
+ fp16_t *capacities TAKES)
+{
+ struct route_query *rq = tal(ctx, struct route_query);
+
+ rq->gossmap = gossmap;
+ rq->cmd_id = tal_strdup(rq, cmd_id);
+ rq->layers = layers;
+ rq->biases = biases;
+ rq->additional_costs = additional_costs;
+ rq->reserved = reserved;
+ rq->capacities = tal_dup_talarr(rq, fp16_t, capacities);
+ rq->disabled_chans =
+ tal_arrz(rq, bitmap,
+ 2 * BITMAP_NWORDS(gossmap_max_chan_idx(gossmap)));
+
+ return rq;
+}
+
+void run_child(const struct gossmap *gossmap,
+ const struct layer **layers,
+ const s8 *biases,
+ const struct additional_cost_htable *additional_costs,
+ struct reserve_htable *reserved,
+ fp16_t *capacities TAKES,
+ bool single_path,
+ struct timemono deadline,
+ const struct gossmap_node *srcnode,
+ const struct gossmap_node *dstnode,
+ struct amount_msat amount, struct amount_msat maxfee,
+ u32 finalcltv, u32 maxdelay, size_t maxparts,
+ bool include_fees,
+ const char *cmd_id,
+ struct json_filter *cmd_filter,
+ int replyfd)
+{
+ double probability;
+ struct flow **flows;
+ struct route **routes;
+ struct amount_msat *amounts;
+ const char *err, *p;
+ size_t len;
+ struct route_query *rq;
+
+ /* We exit below, so we don't bother freeing this */
+ rq = new_route_query(NULL, gossmap, cmd_id, layers,
+ biases, additional_costs,
+ reserved, capacities);
+ if (single_path) {
+ err = single_path_routes(rq, rq, deadline, srcnode, dstnode,
+ amount, maxfee, finalcltv,
+ maxdelay, &flows, &probability);
+ } else {
+ err = default_routes(rq, rq, deadline, srcnode, dstnode,
+ amount, maxfee, finalcltv, maxdelay,
+ maxparts, &flows, &probability);
+ }
+ if (err) {
+ write_all(replyfd, err, strlen(err));
+ /* Non-zero exit tells parent this is an error string. */
+ exit(1);
+ }
+
+ /* otherwise we continue */
+ assert(tal_count(flows) > 0);
+ child_log(tmpctx, LOG_DBG, "Final answer has %zu flows",
+ tal_count(flows));
+
+ /* convert flows to routes */
+ routes = convert_flows_to_routes(rq, rq, finalcltv, flows,
+ &amounts, include_fees);
+ assert(tal_count(routes) == tal_count(flows));
+ assert(tal_count(amounts) == tal_count(flows));
+
+ /* output the results */
+ struct json_stream *js = new_json_stream(tmpctx, NULL, NULL);
+ json_object_start(js, NULL);
+ json_add_string(js, "jsonrpc", "2.0");
+ json_add_id(js, cmd_id);
+ json_object_start(js, "result");
+ if (cmd_filter)
+ json_stream_attach_filter(js, cmd_filter);
+ json_add_getroutes(js, routes, amounts, probability, finalcltv);
+
+ /* Detach filter before it complains about closing object it never saw */
+ if (cmd_filter) {
+ err = json_stream_detach_filter(tmpctx, js);
+ if (err)
+ json_add_string(js, "warning_parameter_filter", err);
+ }
+ /* "result" object */
+ json_object_end(js);
+ /* Global object */
+ json_object_end(js);
+ json_stream_close(js, NULL);
+
+ p = json_out_contents(js->jout, &len);
+ if (!write_all(replyfd, p, len))
+ abort();
+ exit(0);
+}
+
diff --git a/plugins/askrene/child/child.h b/plugins/askrene/child/child.h
new file mode 100644
index 00000000..847bda99
--- /dev/null
+++ b/plugins/askrene/child/child.h
@@ -0,0 +1,36 @@
+#ifndef LIGHTNING_PLUGINS_ASKRENE_CHILD_CHILD_H
+#define LIGHTNING_PLUGINS_ASKRENE_CHILD_CHILD_H
+#include "config.h"
+#include <ccan/compiler/compiler.h>
+#include <ccan/short_types/short_types.h>
+#include <ccan/time/time.h>
+#include <common/amount.h>
+#include <common/fp16.h>
+#include <stdbool.h>
+
+struct additional_cost_htable;
+struct gossmap;
+struct json_filter;
+struct layer;
+struct reserve_htable;
+
+/* This is the child. Do the thing. */
+void run_child(const struct gossmap *gossmap,
+ const struct layer **layers,
+ const s8 *biases,
+ const struct additional_cost_htable *additional_costs,
+ struct reserve_htable *reserved,
+ fp16_t *capacities TAKES,
+ bool single_path,
+ struct timemono deadline,
+ const struct gossmap_node *srcnode,
+ const struct gossmap_node *dstnode,
+ struct amount_msat amount, struct amount_msat maxfee,
+ u32 finalcltv, u32 maxdelay, size_t maxparts,
+ bool include_fees,
+ const char *cmd_id,
+ struct json_filter *cmd_filter,
+ int reply_fd) NORETURN;
+
+#endif /* LIGHTNING_PLUGINS_ASKRENE_CHILD_CHILD_H */
+
diff --git a/plugins/askrene/child/entry.c b/plugins/askrene/child/entry.c
deleted file mode 100644
index 92dddd1a..00000000
--- a/plugins/askrene/child/entry.c
+++ /dev/null
@@ -1,317 +0,0 @@
-#include "config.h"
-#include <assert.h>
-#include <ccan/json_out/json_out.h>
-#include <ccan/noerr/noerr.h>
-#include <ccan/read_write_all/read_write_all.h>
-#include <ccan/tal/str/str.h>
-#include <common/json_stream.h>
-#include <common/route.h>
-#include <common/utils.h>
-#include <plugins/askrene/child/child_log.h>
-#include <plugins/askrene/child/entry.h>
-#include <plugins/askrene/child/flow.h>
-#include <plugins/askrene/child/mcf.h>
-#include <plugins/askrene/child/route_query.h>
-#include <unistd.h>
-
-/* A single route. */
-struct route {
- /* Actual path to take */
- struct route_hop *hops;
- /* Probability estimate (0-1) */
- double success_prob;
-};
-
-static const char *fmt_route(const tal_t *ctx,
- const struct route *route,
- struct amount_msat delivers,
- u32 final_cltv)
-{
- char *str = tal_strdup(ctx, "");
-
- for (size_t i = 0; i < tal_count(route->hops); i++) {
- struct short_channel_id_dir scidd;
- scidd.scid = route->hops[i].scid;
- scidd.dir = route->hops[i].direction;
- tal_append_fmt(&str, "%s/%u %s -> ",
- fmt_amount_msat(tmpctx, route->hops[i].amount),
- route->hops[i].delay,
- fmt_short_channel_id_dir(tmpctx, &scidd));
- }
- tal_append_fmt(&str, "%s/%u",
- fmt_amount_msat(tmpctx, delivers), final_cltv);
- return str;
-}
-
-/* Convert back into routes, with delay and other information fixed */
-static struct route **convert_flows_to_routes(const tal_t *ctx,
- struct route_query *rq,
- u32 finalcltv,
- struct flow **flows,
- struct amount_msat **amounts,
- bool include_fees)
-{
- struct route **routes;
- routes = tal_arr(ctx, struct route *, tal_count(flows));
- *amounts = tal_arr(ctx, struct amount_msat, tal_count(flows));
-
- for (size_t i = 0; i < tal_count(flows); i++) {
- struct route *r;
- struct amount_msat msat;
- u32 delay;
-
- routes[i] = r = tal(routes, struct route);
- r->success_prob = flow_probability(flows[i], rq);
- r->hops = tal_arr(r, struct route_hop, tal_count(flows[i]->path));
-
- msat = flows[i]->delivers;
- delay = finalcltv;
-
- if (!include_fees) {
- /* Fill in backwards to calc amount and delay */
- for (int j = tal_count(flows[i]->path) - 1; j >= 0;
- j--) {
- struct route_hop *rh = &r->hops[j];
- struct gossmap_node *far_end;
- const struct half_chan *h =
- flow_edge(flows[i], j);
-
- if (!amount_msat_add_fee(&msat, h->base_fee,
- h->proportional_fee))
- abort();
- delay += h->delay;
-
- rh->scid = gossmap_chan_scid(rq->gossmap,
- flows[i]->path[j]);
- rh->direction = flows[i]->dirs[j];
- far_end = gossmap_nth_node(rq->gossmap,
- flows[i]->path[j],
- !flows[i]->dirs[j]);
- gossmap_node_get_id(rq->gossmap, far_end,
- &rh->node_id);
- rh->amount = msat;
- rh->delay = delay;
- }
- (*amounts)[i] = flows[i]->delivers;
- } else {
- /* Fill in backwards to calc delay */
- for (int j = tal_count(flows[i]->path) - 1; j >= 0;
- j--) {
- struct route_hop *rh = &r->hops[j];
- struct gossmap_node *far_end;
- const struct half_chan *h =
- flow_edge(flows[i], j);
-
- delay += h->delay;
-
- rh->scid = gossmap_chan_scid(rq->gossmap,
- flows[i]->path[j]);
- rh->direction = flows[i]->dirs[j];
- far_end = gossmap_nth_node(rq->gossmap,
- flows[i]->path[j],
- !flows[i]->dirs[j]);
- gossmap_node_get_id(rq->gossmap, far_end,
- &rh->node_id);
- rh->delay = delay;
- }
- /* Compute fees forward */
- for (int j = 0; j < tal_count(flows[i]->path); j++) {
- struct route_hop *rh = &r->hops[j];
- const struct half_chan *h =
- flow_edge(flows[i], j);
-
- rh->amount = msat;
- msat = amount_msat_sub_fee(msat, h->base_fee,
- h->proportional_fee);
- }
- (*amounts)[i] = msat;
- }
-
- child_log(tmpctx, LOG_INFORM, "Flow %zu/%zu: %s",
- i, tal_count(flows),
- fmt_route(tmpctx, r, (*amounts)[i], finalcltv));
- }
-
- return routes;
-}
-
-static void json_add_getroutes(struct json_stream *js,
- struct route **routes,
- const struct amount_msat *amounts,
- double probability,
- u32 final_cltv)
-{
- json_add_u64(js, "probability_ppm", (u64)(probability * 1000000));
- json_array_start(js, "routes");
- for (size_t i = 0; i < tal_count(routes); i++) {
- json_object_start(js, NULL);
- json_add_u64(js, "probability_ppm",
- (u64)(routes[i]->success_prob * 1000000));
- json_add_amount_msat(js, "amount_msat", amounts[i]);
- json_add_u32(js, "final_cltv", final_cltv);
- json_array_start(js, "path");
- for (size_t j = 0; j < tal_count(routes[i]->hops); j++) {
- struct short_channel_id_dir scidd;
- const struct route_hop *r = &routes[i]->hops[j];
- json_object_start(js, NULL);
- scidd.scid = r->scid;
- scidd.dir = r->direction;
- json_add_short_channel_id_dir(
- js, "short_channel_id_dir", scidd);
- json_add_node_id(js, "next_node_id", &r->node_id);
- json_add_amount_msat(js, "amount_msat", r->amount);
- json_add_u32(js, "delay", r->delay);
- json_object_end(js);
- }
- json_array_end(js);
- json_object_end(js);
- }
- json_array_end(js);
-}
-
-
-static struct route_query *new_route_query(const tal_t *ctx,
- const struct gossmap *gossmap,
- const char *cmd_id,
- const struct layer **layers,
- const s8 *biases,
- const struct additional_cost_htable *additional_costs,
- struct reserve_htable *reserved,
- fp16_t *capacities TAKES)
-{
- struct route_query *rq = tal(ctx, struct route_query);
-
- rq->gossmap = gossmap;
- rq->cmd_id = tal_strdup(rq, cmd_id);
- rq->layers = layers;
- rq->biases = biases;
- rq->additional_costs = additional_costs;
- rq->reserved = reserved;
- rq->capacities = tal_dup_talarr(rq, fp16_t, capacities);
- rq->disabled_chans =
- tal_arrz(rq, bitmap,
- 2 * BITMAP_NWORDS(gossmap_max_chan_idx(gossmap)));
-
- return rq;
-}
-
-/* Returns fd to child */
-int fork_router_child(const struct gossmap *gossmap,
- const struct layer **layers,
- const s8 *biases,
- const struct additional_cost_htable *additional_costs,
- struct reserve_htable *reserved,
- fp16_t *capacities TAKES,
- bool single_path,
- struct timemono deadline,
- const struct gossmap_node *srcnode,
- const struct gossmap_node *dstnode,
- struct amount_msat amount, struct amount_msat maxfee,
- u32 finalcltv, u32 maxdelay, size_t maxparts,
- bool include_fees,
- const char *cmd_id,
- struct json_filter *cmd_filter,
- int *log_fd,
- int *child_pid)
-{
- int replyfds[2], logfds[2];
- double probability;
- struct flow **flows;
- struct route **routes;
- struct amount_msat *amounts;
- const char *err, *p;
- size_t len;
- struct route_query *rq;
-
- if (pipe(replyfds) != 0)
- goto parent_fail;
- if (pipe(logfds) != 0) {
- close_noerr(replyfds[0]);
- close_noerr(replyfds[1]);
- goto parent_fail;
- }
- *child_pid = fork();
- if (*child_pid < 0) {
- close_noerr(replyfds[0]);
- close_noerr(replyfds[1]);
- close_noerr(logfds[0]);
- close_noerr(logfds[1]);
- goto parent_fail;
- }
- if (*child_pid != 0) {
- close(logfds[1]);
- close(replyfds[1]);
- *log_fd = logfds[0];
- if (taken(capacities))
- tal_free(capacities);
- return replyfds[0];
- }
-
- /* We are the child. Run the algo */
- close(logfds[0]);
- close(replyfds[0]);
- set_child_log_fd(logfds[1]);
-
- /* We exit below, so we don't bother freeing this */
- rq = new_route_query(NULL, gossmap, cmd_id, layers,
- biases, additional_costs,
- reserved, capacities);
- if (single_path) {
- err = single_path_routes(rq, rq, deadline, srcnode, dstnode,
- amount, maxfee, finalcltv,
- maxdelay, &flows, &probability);
- } else {
- err = default_routes(rq, rq, deadline, srcnode, dstnode,
- amount, maxfee, finalcltv, maxdelay,
- maxparts, &flows, &probability);
- }
- if (err) {
- write_all(replyfds[1], err, strlen(err));
- /* Non-zero exit tells parent this is an error string. */
- exit(1);
- }
-
- /* otherwise we continue */
- assert(tal_count(flows) > 0);
- child_log(tmpctx, LOG_DBG, "Final answer has %zu flows",
- tal_count(flows));
-
- /* convert flows to routes */
- routes = convert_flows_to_routes(rq, rq, finalcltv, flows,
- &amounts, include_fees);
- assert(tal_count(routes) == tal_count(flows));
- assert(tal_count(amounts) == tal_count(flows));
-
- /* output the results */
- struct json_stream *js = new_json_stream(tmpctx, NULL, NULL);
- json_object_start(js, NULL);
- json_add_string(js, "jsonrpc", "2.0");
- json_add_id(js, cmd_id);
- json_object_start(js, "result");
- if (cmd_filter)
- json_stream_attach_filter(js, cmd_filter);
- json_add_getroutes(js, routes, amounts, probability, finalcltv);
-
- /* Detach filter before it complains about closing object it never saw */
- if (cmd_filter) {
- err = json_stream_detach_filter(tmpctx, js);
- if (err)
- json_add_string(js, "warning_parameter_filter", err);
- }
- /* "result" object */
- json_object_end(js);
- /* Global object */
- json_object_end(js);
- json_stream_close(js, NULL);
-
- p = json_out_contents(js->jout, &len);
- if (!write_all(replyfds[1], p, len))
- abort();
- exit(0);
-
-parent_fail:
- if (taken(capacities))
- tal_free(capacities);
- return -1;
-}
-
diff --git a/plugins/askrene/child/entry.h b/plugins/askrene/child/entry.h
deleted file mode 100644
index 7484b609..00000000
--- a/plugins/askrene/child/entry.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef LIGHTNING_PLUGINS_ASKRENE_CHILD_ENTRY_H
-#define LIGHTNING_PLUGINS_ASKRENE_CHILD_ENTRY_H
-#include "config.h"
-#include <ccan/short_types/short_types.h>
-#include <ccan/time/time.h>
-#include <common/amount.h>
-#include <common/fp16.h>
-#include <stdbool.h>
-
-struct route_query;
-struct gossmap_node;
-struct json_filter;
-struct layer;
-struct reserve_htable;
-struct additional_cost_htable;
-
-/* Entry point to the child process. */
-int fork_router_child(const struct gossmap *gossmap,
- const struct layer **layers,
- const s8 *biases,
- const struct additional_cost_htable *additional_costs,
- struct reserve_htable *reserved,
- fp16_t *capacities TAKES,
- bool single_path,
- struct timemono deadline,
- const struct gossmap_node *srcnode,
- const struct gossmap_node *dstnode,
- struct amount_msat amount, struct amount_msat maxfee,
- u32 finalcltv, u32 maxdelay, size_t maxparts,
- bool include_fees,
- const char *cmd_id,
- struct json_filter *cmd_filter,
- int *log_fd,
- int *child_pid);
-#endif /* LIGHTNING_PLUGINS_ASKRENE_CHILD_ENTRY_H */
Why this scored 11/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.