Skip to content

Commit 0ee92bd

Browse files
committed
askrene: move fork() entry point into its own file.
Now there's only one file clearly shared by both parent and child. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent 8eb900f commit 0ee92bd

File tree

5 files changed

+265
-226
lines changed

5 files changed

+265
-226
lines changed

plugins/askrene/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ PLUGIN_ASKRENE_PARENT_SRC := \
55
plugins/askrene/reserve.c \
66

77
PLUGIN_ASKRENE_CHILD_SRC := \
8+
plugins/askrene/child/entry.c \
89
plugins/askrene/child/mcf.c \
910
plugins/askrene/child/dijkstra.c \
1011
plugins/askrene/child/flow.c \

plugins/askrene/askrene.c

Lines changed: 2 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@
88
*/
99
#include "config.h"
1010
#include <ccan/array_size/array_size.h>
11-
#include <ccan/json_out/json_out.h>
12-
#include <ccan/noerr/noerr.h>
13-
#include <ccan/read_write_all/read_write_all.h>
1411
#include <ccan/tal/grab_file/grab_file.h>
1512
#include <ccan/tal/str/str.h>
1613
#include <common/clock_time.h>
@@ -26,17 +23,12 @@
2623
#include <math.h>
2724
#include <plugins/askrene/askrene.h>
2825
#include <plugins/askrene/child/child_log.h>
29-
#include <plugins/askrene/child/flow.h>
30-
#include <plugins/askrene/child/mcf.h>
26+
#include <plugins/askrene/child/entry.h>
3127
#include <plugins/askrene/layer.h>
3228
#include <plugins/askrene/reserve.h>
3329
#include <sys/wait.h>
34-
#include <unistd.h>
3530
#include <wire/wire_sync.h>
3631

37-
/* Temporary hack */
38-
static bool am_child = false;
39-
4032
/* "spendable" for a channel assumes a single HTLC: for additional HTLCs,
4133
* the need to pay for fees (if we're the owner) reduces it */
4234
struct per_htlc_cost {
@@ -339,27 +331,6 @@ const char *rq_log(const tal_t *ctx,
339331
return msg;
340332
}
341333

342-
static const char *fmt_route(const tal_t *ctx,
343-
const struct route *route,
344-
struct amount_msat delivers,
345-
u32 final_cltv)
346-
{
347-
char *str = tal_strdup(ctx, "");
348-
349-
for (size_t i = 0; i < tal_count(route->hops); i++) {
350-
struct short_channel_id_dir scidd;
351-
scidd.scid = route->hops[i].scid;
352-
scidd.dir = route->hops[i].direction;
353-
tal_append_fmt(&str, "%s/%u %s -> ",
354-
fmt_amount_msat(tmpctx, route->hops[i].amount),
355-
route->hops[i].delay,
356-
fmt_short_channel_id_dir(tmpctx, &scidd));
357-
}
358-
tal_append_fmt(&str, "%s/%u",
359-
fmt_amount_msat(tmpctx, delivers), final_cltv);
360-
return str;
361-
}
362-
363334
enum algorithm {
364335
/* Min. Cost Flow by successive shortests paths. */
365336
ALGO_DEFAULT,
@@ -432,89 +403,6 @@ static void apply_layers(struct askrene *askrene, struct route_query *rq,
432403
}
433404
}
434405

435-
/* Convert back into routes, with delay and other information fixed */
436-
static struct route **convert_flows_to_routes(const tal_t *ctx,
437-
struct route_query *rq,
438-
u32 finalcltv,
439-
struct flow **flows,
440-
struct amount_msat **amounts)
441-
{
442-
struct route **routes;
443-
routes = tal_arr(ctx, struct route *, tal_count(flows));
444-
*amounts = tal_arr(ctx, struct amount_msat, tal_count(flows));
445-
446-
for (size_t i = 0; i < tal_count(flows); i++) {
447-
struct route *r;
448-
struct amount_msat msat;
449-
u32 delay;
450-
451-
routes[i] = r = tal(routes, struct route);
452-
r->success_prob = flow_probability(flows[i], rq);
453-
r->hops = tal_arr(r, struct route_hop, tal_count(flows[i]->path));
454-
455-
/* Fill in backwards to calc amount and delay */
456-
msat = flows[i]->delivers;
457-
delay = finalcltv;
458-
459-
for (int j = tal_count(flows[i]->path) - 1; j >= 0; j--) {
460-
struct route_hop *rh = &r->hops[j];
461-
struct gossmap_node *far_end;
462-
const struct half_chan *h = flow_edge(flows[i], j);
463-
464-
if (!amount_msat_add_fee(&msat, h->base_fee, h->proportional_fee))
465-
plugin_err(rq->plugin, "Adding fee to amount");
466-
delay += h->delay;
467-
468-
rh->scid = gossmap_chan_scid(rq->gossmap, flows[i]->path[j]);
469-
rh->direction = flows[i]->dirs[j];
470-
far_end = gossmap_nth_node(rq->gossmap, flows[i]->path[j], !flows[i]->dirs[j]);
471-
gossmap_node_get_id(rq->gossmap, far_end, &rh->node_id);
472-
rh->amount = msat;
473-
rh->delay = delay;
474-
}
475-
(*amounts)[i] = flows[i]->delivers;
476-
rq_log(tmpctx, rq, LOG_INFORM, "Flow %zu/%zu: %s",
477-
i, tal_count(flows),
478-
fmt_route(tmpctx, r, (*amounts)[i], finalcltv));
479-
}
480-
481-
return routes;
482-
}
483-
484-
static void json_add_getroutes(struct json_stream *js,
485-
struct route **routes,
486-
const struct amount_msat *amounts,
487-
double probability,
488-
u32 final_cltv)
489-
{
490-
json_add_u64(js, "probability_ppm", (u64)(probability * 1000000));
491-
json_array_start(js, "routes");
492-
for (size_t i = 0; i < tal_count(routes); i++) {
493-
json_object_start(js, NULL);
494-
json_add_u64(js, "probability_ppm",
495-
(u64)(routes[i]->success_prob * 1000000));
496-
json_add_amount_msat(js, "amount_msat", amounts[i]);
497-
json_add_u32(js, "final_cltv", final_cltv);
498-
json_array_start(js, "path");
499-
for (size_t j = 0; j < tal_count(routes[i]->hops); j++) {
500-
struct short_channel_id_dir scidd;
501-
const struct route_hop *r = &routes[i]->hops[j];
502-
json_object_start(js, NULL);
503-
scidd.scid = r->scid;
504-
scidd.dir = r->direction;
505-
json_add_short_channel_id_dir(
506-
js, "short_channel_id_dir", scidd);
507-
json_add_node_id(js, "next_node_id", &r->node_id);
508-
json_add_amount_msat(js, "amount_msat", r->amount);
509-
json_add_u32(js, "delay", r->delay);
510-
json_object_end(js);
511-
}
512-
json_array_end(js);
513-
json_object_end(js);
514-
}
515-
json_array_end(js);
516-
}
517-
518406
void get_constraints(const struct route_query *rq,
519407
const struct gossmap_chan *chan,
520408
int dir,
@@ -551,110 +439,6 @@ void get_constraints(const struct route_query *rq,
551439
reserve_sub(rq->reserved, &scidd, rq->layers, max);
552440
}
553441

554-
/* Returns fd to child */
555-
static int fork_router_child(struct route_query *rq,
556-
enum algorithm algo,
557-
struct timemono deadline,
558-
const struct gossmap_node *srcnode,
559-
const struct gossmap_node *dstnode,
560-
struct amount_msat amount,
561-
struct amount_msat maxfee,
562-
u32 finalcltv, u32 maxdelay,
563-
const char *cmd_id,
564-
struct json_filter *cmd_filter,
565-
int *log_fd,
566-
int *child_pid)
567-
{
568-
int replyfds[2], logfds[2];
569-
double probability;
570-
struct flow **flows;
571-
struct route **routes;
572-
struct amount_msat *amounts;
573-
const char *err, *p;
574-
size_t len;
575-
576-
if (pipe(replyfds) != 0)
577-
return -1;
578-
if (pipe(logfds) != 0) {
579-
close_noerr(replyfds[0]);
580-
close_noerr(replyfds[1]);
581-
return -1;
582-
}
583-
*child_pid = fork();
584-
if (*child_pid < 0) {
585-
close_noerr(replyfds[0]);
586-
close_noerr(replyfds[1]);
587-
close_noerr(logfds[0]);
588-
close_noerr(logfds[1]);
589-
return -1;
590-
}
591-
if (*child_pid != 0) {
592-
close(logfds[1]);
593-
close(replyfds[1]);
594-
*log_fd = logfds[0];
595-
return replyfds[0];
596-
}
597-
598-
/* We are the child. Run the algo */
599-
close(logfds[0]);
600-
close(replyfds[0]);
601-
set_child_log_fd(logfds[1]);
602-
am_child = true;
603-
if (algo == ALGO_SINGLE_PATH) {
604-
err = single_path_routes(rq, rq, deadline, srcnode, dstnode,
605-
amount, maxfee, finalcltv,
606-
maxdelay, &flows, &probability);
607-
} else {
608-
assert(algo == ALGO_DEFAULT);
609-
err = default_routes(rq, rq, deadline, srcnode, dstnode,
610-
amount, maxfee, finalcltv, maxdelay,
611-
&flows, &probability);
612-
}
613-
if (err) {
614-
write_all(replyfds[1], err, strlen(err));
615-
/* Non-zero exit tells parent this is an error string. */
616-
exit(1);
617-
}
618-
619-
/* otherwise we continue */
620-
assert(tal_count(flows) > 0);
621-
rq_log(tmpctx, rq, LOG_DBG, "Final answer has %zu flows",
622-
tal_count(flows));
623-
624-
/* convert flows to routes */
625-
routes = convert_flows_to_routes(rq, rq, finalcltv, flows,
626-
&amounts);
627-
assert(tal_count(routes) == tal_count(flows));
628-
assert(tal_count(amounts) == tal_count(flows));
629-
630-
/* output the results */
631-
struct json_stream *js = new_json_stream(tmpctx, NULL, NULL);
632-
json_object_start(js, NULL);
633-
json_add_string(js, "jsonrpc", "2.0");
634-
json_add_id(js, cmd_id);
635-
json_object_start(js, "result");
636-
if (cmd_filter)
637-
json_stream_attach_filter(js, cmd_filter);
638-
json_add_getroutes(js, routes, amounts, probability, finalcltv);
639-
640-
/* Detach filter before it complains about closing object it never saw */
641-
if (cmd_filter) {
642-
err = json_stream_detach_filter(tmpctx, js);
643-
if (err)
644-
json_add_string(js, "warning_parameter_filter", err);
645-
}
646-
/* "result" object */
647-
json_object_end(js);
648-
/* Global object */
649-
json_object_end(js);
650-
json_stream_close(js, NULL);
651-
652-
p = json_out_contents(js->jout, &len);
653-
if (!write_all(replyfds[1], p, len))
654-
abort();
655-
exit(0);
656-
}
657-
658442
static void process_child_logs(struct route_query *rq, int log_fd)
659443
{
660444
u8 *msg;
@@ -761,7 +545,7 @@ static struct command_result *do_getroutes(struct command *cmd,
761545
time_start = time_mono();
762546
deadline = timemono_add(time_start,
763547
time_from_sec(askrene->route_seconds));
764-
child_fd = fork_router_child(rq, info->dev_algo,
548+
child_fd = fork_router_child(rq, info->dev_algo == ALGO_SINGLE_PATH,
765549
deadline, srcnode, dstnode, info->amount,
766550
info->maxfee, info->finalcltv, info->maxdelay,
767551
cmd->id, cmd->filter, &log_fd, &child_pid);

plugins/askrene/askrene.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,6 @@
1212

1313
struct gossmap_chan;
1414

15-
/* A single route. */
16-
struct route {
17-
/* Actual path to take */
18-
struct route_hop *hops;
19-
/* Probability estimate (0-1) */
20-
double success_prob;
21-
};
22-
2315
/* Grab-bag of "globals" for this plugin */
2416
struct askrene {
2517
struct plugin *plugin;

0 commit comments

Comments
 (0)