MCPcopy Create free account
hub / github.com/ElementsProject/lightning / find_path_or_cycle

Function find_path_or_cycle

plugins/askrene/child/mcf.c:638–701  ·  view source on GitHub ↗

Search in the network a path of positive flow until we reach a node with * positive balance (returns a node idx with positive balance) * or we discover a cycle (returns a node idx with 0 balance). * */

Source from the content-addressed store, hash-verified

636 * or we discover a cycle (returns a node idx with 0 balance).
637 * */
638static struct node find_path_or_cycle(
639 const tal_t *working_ctx,
640 const struct route_query *rq,
641 const struct chan_flow *chan_flow,
642 const struct node source,
643 const s64 *balance,
644
645 const struct gossmap_chan **prev_chan,
646 int *prev_dir,
647 u32 *prev_idx)
648{
649 const struct gossmap *gossmap = rq->gossmap;
650 const size_t max_num_nodes = gossmap_max_node_idx(gossmap);
651 bitmap *visited =
652 tal_arrz(working_ctx, bitmap, BITMAP_NWORDS(max_num_nodes));
653 u32 final_idx = source.idx;
654 bitmap_set_bit(visited, final_idx);
655
656 /* It is guaranteed to halt, because we either find a node with
657 * balance[]>0 or we hit a node twice and we stop. */
658 while (balance[final_idx] <= 0) {
659 u32 updated_idx = INVALID_INDEX;
660 struct gossmap_node *cur =
661 gossmap_node_byidx(gossmap, final_idx);
662
663 for (size_t i = 0; i < cur->num_chans; ++i) {
664 int dir;
665 const struct gossmap_chan *c =
666 gossmap_nth_chan(gossmap, cur, i, &dir);
667
668 if (!channel_is_available(rq, c, dir))
669 continue;
670
671 const u32 c_idx = gossmap_chan_idx(gossmap, c);
672
673 /* follow the flow */
674 if (chan_flow[c_idx].half[dir] > 0) {
675 const struct gossmap_node *n =
676 gossmap_nth_node(gossmap, c, !dir);
677 u32 next_idx = gossmap_node_idx(gossmap, n);
678
679 prev_dir[next_idx] = dir;
680 prev_chan[next_idx] = c;
681 prev_idx[next_idx] = final_idx;
682
683 updated_idx = next_idx;
684 break;
685 }
686 }
687
688 assert(updated_idx != INVALID_INDEX);
689 assert(updated_idx != final_idx);
690 final_idx = updated_idx;
691
692 if (bitmap_test_bit(visited, updated_idx)) {
693 /* We have seen this node before, we've found a cycle.
694 */
695 assert(balance[updated_idx] <= 0);

Callers 1

get_flow_pathsFunction · 0.85

Calls 10

gossmap_max_node_idxFunction · 0.85
bitmap_set_bitFunction · 0.85
gossmap_node_byidxFunction · 0.85
gossmap_nth_chanFunction · 0.85
gossmap_chan_idxFunction · 0.85
gossmap_nth_nodeFunction · 0.85
gossmap_node_idxFunction · 0.85
bitmap_test_bitFunction · 0.85
node_objFunction · 0.85
channel_is_availableFunction · 0.70

Tested by

no test coverage detected