|
8 | 8 | */ |
9 | 9 | #include "config.h" |
10 | 10 | #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> |
14 | 11 | #include <ccan/tal/grab_file/grab_file.h> |
15 | 12 | #include <ccan/tal/str/str.h> |
16 | 13 | #include <common/clock_time.h> |
|
26 | 23 | #include <math.h> |
27 | 24 | #include <plugins/askrene/askrene.h> |
28 | 25 | #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> |
31 | 27 | #include <plugins/askrene/layer.h> |
32 | 28 | #include <plugins/askrene/reserve.h> |
33 | 29 | #include <sys/wait.h> |
34 | | -#include <unistd.h> |
35 | 30 | #include <wire/wire_sync.h> |
36 | 31 |
|
37 | | -/* Temporary hack */ |
38 | | -static bool am_child = false; |
39 | | - |
40 | 32 | /* "spendable" for a channel assumes a single HTLC: for additional HTLCs, |
41 | 33 | * the need to pay for fees (if we're the owner) reduces it */ |
42 | 34 | struct per_htlc_cost { |
@@ -339,27 +331,6 @@ const char *rq_log(const tal_t *ctx, |
339 | 331 | return msg; |
340 | 332 | } |
341 | 333 |
|
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 | | - |
363 | 334 | enum algorithm { |
364 | 335 | /* Min. Cost Flow by successive shortests paths. */ |
365 | 336 | ALGO_DEFAULT, |
@@ -432,89 +403,6 @@ static void apply_layers(struct askrene *askrene, struct route_query *rq, |
432 | 403 | } |
433 | 404 | } |
434 | 405 |
|
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 | | - |
518 | 406 | void get_constraints(const struct route_query *rq, |
519 | 407 | const struct gossmap_chan *chan, |
520 | 408 | int dir, |
@@ -551,110 +439,6 @@ void get_constraints(const struct route_query *rq, |
551 | 439 | reserve_sub(rq->reserved, &scidd, rq->layers, max); |
552 | 440 | } |
553 | 441 |
|
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 | | - |
658 | 442 | static void process_child_logs(struct route_query *rq, int log_fd) |
659 | 443 | { |
660 | 444 | u8 *msg; |
@@ -761,7 +545,7 @@ static struct command_result *do_getroutes(struct command *cmd, |
761 | 545 | time_start = time_mono(); |
762 | 546 | deadline = timemono_add(time_start, |
763 | 547 | 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, |
765 | 549 | deadline, srcnode, dstnode, info->amount, |
766 | 550 | info->maxfee, info->finalcltv, info->maxdelay, |
767 | 551 | cmd->id, cmd->filter, &log_fd, &child_pid); |
|
0 commit comments