Given a flow in the residual network, build a set of payment flows in the * gossmap that corresponds to this flow. */
| 815 | /* Given a flow in the residual network, build a set of payment flows in the |
| 816 | * gossmap that corresponds to this flow. */ |
| 817 | static struct flow ** |
| 818 | get_flow_paths(const tal_t *ctx, |
| 819 | const tal_t *working_ctx, |
| 820 | const struct pay_parameters *params, |
| 821 | const struct graph *graph, |
| 822 | const s64 *arc_residual_capacity) |
| 823 | { |
| 824 | struct flow **flows = tal_arr(ctx,struct flow*,0); |
| 825 | |
| 826 | const size_t max_num_chans = gossmap_max_chan_idx(params->rq->gossmap); |
| 827 | struct chan_flow *chan_flow = tal_arrz(working_ctx,struct chan_flow,max_num_chans); |
| 828 | |
| 829 | const size_t max_num_nodes = gossmap_max_node_idx(params->rq->gossmap); |
| 830 | s64 *balance = tal_arrz(working_ctx,s64,max_num_nodes); |
| 831 | |
| 832 | const struct gossmap_chan **prev_chan |
| 833 | = tal_arr(working_ctx,const struct gossmap_chan *,max_num_nodes); |
| 834 | |
| 835 | |
| 836 | int *prev_dir = tal_arr(working_ctx,int,max_num_nodes); |
| 837 | u32 *prev_idx = tal_arr(working_ctx, u32, max_num_nodes); |
| 838 | |
| 839 | for (u32 node_idx = 0; node_idx < max_num_nodes; node_idx++) |
| 840 | prev_idx[node_idx] = INVALID_INDEX; |
| 841 | |
| 842 | // Convert the arc based residual network flow into a flow in the |
| 843 | // directed channel network. |
| 844 | // Compute balance on the nodes. |
| 845 | for (struct node n = {.idx = 0}; n.idx < max_num_nodes; n.idx++) { |
| 846 | for(struct arc arc = node_adjacency_begin(graph,n); |
| 847 | !node_adjacency_end(arc); |
| 848 | arc = node_adjacency_next(graph,arc)) |
| 849 | { |
| 850 | if(arc_is_dual(graph, arc)) |
| 851 | continue; |
| 852 | struct node m = arc_head(graph,arc); |
| 853 | s64 flow = get_arc_flow(arc_residual_capacity, |
| 854 | graph, arc); |
| 855 | u32 chanidx; |
| 856 | int chandir; |
| 857 | |
| 858 | balance[n.idx] -= flow; |
| 859 | balance[m.idx] += flow; |
| 860 | |
| 861 | arc_to_parts(arc, &chanidx, &chandir, NULL, NULL); |
| 862 | chan_flow[chanidx].half[chandir] +=flow; |
| 863 | } |
| 864 | } |
| 865 | |
| 866 | // Select all nodes with negative balance and find a flow that reaches a |
| 867 | // positive balance node. |
| 868 | for (struct node source = {.idx = 0}; source.idx < max_num_nodes; |
| 869 | source.idx++) { |
| 870 | // this node has negative balance, flows leaves from here |
| 871 | while (balance[source.idx] < 0) { |
| 872 | prev_chan[source.idx] = NULL; |
| 873 | struct node sink = find_path_or_cycle( |
| 874 | working_ctx, params->rq, chan_flow, source, |
no test coverage detected