22#include <assert.h>
33#include <ccan/asort/asort.h>
44#include <ccan/bitmap/bitmap.h>
5+ #include <ccan/err/err.h>
56#include <ccan/list/list.h>
67#include <ccan/tal/str/str.h>
78#include <ccan/tal/tal.h>
159160 *
160161 * */
161162
163+ #define PANIC (message ) \
164+ errx(1, "Panic in function %s line %d: %s", __func__, __LINE__, \
165+ message);
166+
162167#define PARTS_BITS 2
163168#define CHANNEL_PARTS (1 << PARTS_BITS)
164169
@@ -297,6 +302,10 @@ struct pay_parameters {
297302
298303 double delay_feefactor ;
299304 double base_fee_penalty ;
305+
306+ /* keep this here to have a consistent conversion factor all over.
307+ * Probability Cost (x) = prob_cost_factor * (-log Probability(x)) */
308+ double prob_cost_factor ;
300309};
301310
302311/* Helper function.
@@ -319,6 +328,46 @@ static void set_capacity(s64 *capacity, u64 value, u64 *cap_on_capacity)
319328 * cap_on_capacity -= * capacity ;
320329}
321330
331+ /* FIXME: unit test this */
332+ /* The probability of forwarding a payment amount given a high and low liquidity
333+ * bounds.
334+ * @low: the liquidity is known to be greater or equal than "low"
335+ * @high: the liquidity is known to be less than "high"
336+ * @amount: how much is required to forward */
337+ static double pickhardt_richter_probability (struct amount_msat low ,
338+ struct amount_msat high ,
339+ struct amount_msat amount )
340+ {
341+ struct amount_msat all_states , good_states ;
342+ if (amount_msat_greater_eq (amount , high ))
343+ return 0.0 ;
344+ if (!amount_msat_sub (& amount , amount , low ))
345+ return 1.0 ;
346+ if (!amount_msat_sub (& all_states , high , low ))
347+ PANIC ("we expect high > low" );
348+ if (!amount_msat_sub (& good_states , all_states , amount ))
349+ PANIC ("we expect high > amount" );
350+ return amount_msat_ratio (good_states , all_states );
351+ }
352+
353+ /* Returns the probability of success that this channel is able to forward x
354+ * considering only the bounds on the liquidity. */
355+ static double channel_probability (const struct pay_parameters * params ,
356+ const struct gossmap_chan * c , const int dir ,
357+ struct amount_msat forward )
358+ {
359+ struct amount_msat mincap , maxcap ;
360+ /* This takes into account any payments in progress. */
361+ get_constraints (params -> rq , c , dir , & mincap , & maxcap );
362+ /* Assume if min > max, min is wrong */
363+ if (amount_msat_greater (mincap , maxcap ))
364+ mincap = maxcap ;
365+ /* It is preferable to work on 1msat past the known bound. */
366+ if (!amount_msat_accumulate (& maxcap , amount_msat (1 )))
367+ PANIC ("maxcap + 1msat overflows" );
368+ return pickhardt_richter_probability (mincap , maxcap , forward );
369+ }
370+
322371// TODO(eduardo): unit test this
323372/* Split a directed channel into parts with linear cost function. */
324373static void linearize_channel (const struct pay_parameters * params ,
@@ -348,9 +397,8 @@ static void linearize_channel(const struct pay_parameters *params,
348397 {
349398 set_capacity (& capacity [i ], params -> cap_fraction [i ]* (b - a ), & cap_on_capacity );
350399
351- cost [i ] = params -> cost_fraction [i ] * 1000
352- * amount_msat_ratio (params -> amount , params -> accuracy )
353- / (b - a );
400+ cost [i ] = params -> prob_cost_factor * params -> cost_fraction [i ] /
401+ (b - a );
354402 }
355403}
356404
@@ -867,6 +915,46 @@ get_flow_paths(const tal_t *ctx,
867915 return flows ;
868916}
869917
918+ /* Given a single path build a flow set. */
919+ static struct flow * *
920+ get_flow_singlepath (const tal_t * ctx , const tal_t * working_ctx ,
921+ const struct graph * graph , const struct gossmap * gossmap ,
922+ const struct node source , const struct node destination ,
923+ const u64 pay_amount , const struct arc * prev )
924+ {
925+ struct flow * * flows = tal_arr (ctx , struct flow * , 0 );
926+
927+ size_t length = 0 ;
928+
929+ for (u32 cur_idx = destination .idx ; cur_idx != source .idx ;) {
930+ assert (cur_idx != INVALID_INDEX );
931+ length ++ ;
932+ struct arc arc = prev [cur_idx ];
933+ struct node next = arc_tail (graph , arc );
934+ cur_idx = next .idx ;
935+ }
936+ struct flow * f = tal (ctx , struct flow );
937+ f -> path = tal_arr (f , const struct gossmap_chan * , length );
938+ f -> dirs = tal_arr (f , int , length );
939+
940+ for (u32 cur_idx = destination .idx ; cur_idx != source .idx ;) {
941+ int chandir ;
942+ u32 chanidx ;
943+ struct arc arc = prev [cur_idx ];
944+ arc_to_parts (arc , & chanidx , & chandir , NULL , NULL );
945+
946+ length -- ;
947+ f -> path [length ] = gossmap_chan_byidx (gossmap , chanidx );
948+ f -> dirs [length ] = chandir ;
949+
950+ struct node next = arc_tail (graph , arc );
951+ cur_idx = next .idx ;
952+ }
953+
954+ tal_arr_expand (& flows , f );
955+ return flows ;
956+ }
957+
870958// TODO(eduardo): choose some default values for the minflow parameters
871959/* eduardo: I think it should be clear that this module deals with linear
872960 * flows, ie. base fees are not considered. Hence a flow along a path is
@@ -914,6 +1002,8 @@ struct flow **minflow(const tal_t *ctx,
9141002 /params -> cap_fraction [i ];
9151003 }
9161004
1005+ params -> prob_cost_factor =
1006+ 1000 * amount_msat_ratio (params -> amount , params -> accuracy );
9171007 params -> delay_feefactor = delay_feefactor ;
9181008 params -> base_fee_penalty = base_fee_penalty_estimate (amount );
9191009
@@ -1025,6 +1115,173 @@ static struct amount_msat linear_flows_cost(struct flow **flows,
10251115 return total ;
10261116}
10271117
1118+ /* Initialize the data vectors for the single-path solver. */
1119+ static void init_linear_network_single_path (
1120+ const tal_t * ctx , const struct pay_parameters * params , struct graph * * graph ,
1121+ double * * arc_prob_cost , s64 * * arc_fee_cost , s64 * * arc_capacity )
1122+ {
1123+ const size_t max_num_chans = gossmap_max_chan_idx (params -> rq -> gossmap );
1124+ const size_t max_num_arcs = max_num_chans * ARCS_PER_CHANNEL ;
1125+ const size_t max_num_nodes = gossmap_max_node_idx (params -> rq -> gossmap );
1126+
1127+ * graph = graph_new (ctx , max_num_nodes , max_num_arcs , ARC_DUAL_BITOFF );
1128+ * arc_prob_cost = tal_arr (ctx , double , max_num_arcs );
1129+ for (size_t i = 0 ; i < max_num_arcs ; ++ i )
1130+ (* arc_prob_cost )[i ] = DBL_MAX ;
1131+
1132+ * arc_fee_cost = tal_arr (ctx , s64 , max_num_arcs );
1133+ for (size_t i = 0 ; i < max_num_arcs ; ++ i )
1134+ (* arc_fee_cost )[i ] = INT64_MAX ;
1135+ * arc_capacity = tal_arrz (ctx , s64 , max_num_arcs );
1136+
1137+ /* We use this quantity to compute the cost of routing the entire
1138+ * amount, as opposed to the cost per unit of flow. */
1139+ const u64 pay_amount =
1140+ amount_msat_ratio_ceil (params -> amount , params -> accuracy );
1141+
1142+ const struct gossmap * gossmap = params -> rq -> gossmap ;
1143+
1144+ for (struct gossmap_node * node = gossmap_first_node (gossmap ); node ;
1145+ node = gossmap_next_node (gossmap , node )) {
1146+ const u32 node_id = gossmap_node_idx (gossmap , node );
1147+
1148+ for (size_t j = 0 ; j < node -> num_chans ; ++ j ) {
1149+ int half ;
1150+ const struct gossmap_chan * c =
1151+ gossmap_nth_chan (gossmap , node , j , & half );
1152+
1153+ if (!gossmap_chan_set (c , half ) ||
1154+ !c -> half [half ].enabled )
1155+ continue ;
1156+
1157+ /* If a channel cannot forward the total amount we don't
1158+ * use it. */
1159+ if (amount_msat_less (params -> amount ,
1160+ gossmap_chan_htlc_min (c , half )) ||
1161+ amount_msat_greater (params -> amount ,
1162+ gossmap_chan_htlc_max (c , half )))
1163+ continue ;
1164+
1165+ const u32 chan_id = gossmap_chan_idx (gossmap , c );
1166+
1167+ const struct gossmap_node * next =
1168+ gossmap_nth_node (gossmap , c , !half );
1169+
1170+ const u32 next_id = gossmap_node_idx (gossmap , next );
1171+
1172+ /* channel to self? */
1173+ if (node_id == next_id )
1174+ continue ;
1175+
1176+ struct arc arc =
1177+ arc_from_parts (chan_id , half , 0 , false);
1178+
1179+ graph_add_arc (* graph , arc , node_obj (node_id ),
1180+ node_obj (next_id ));
1181+
1182+ (* arc_capacity )[arc .idx ] = 1 ;
1183+ (* arc_prob_cost )[arc .idx ] =
1184+ params -> prob_cost_factor * (-1.0 ) *
1185+ log (channel_probability (params , c , half ,
1186+ params -> amount ));
1187+
1188+ (* arc_fee_cost )[arc .idx ] =
1189+ pay_amount *
1190+ linear_fee_cost (c -> half [half ].base_fee ,
1191+ c -> half [half ].proportional_fee ,
1192+ c -> half [half ].delay ,
1193+ params -> base_fee_penalty ,
1194+ params -> delay_feefactor );
1195+ }
1196+ }
1197+ }
1198+
1199+ /* Similar to minflow but computes routes that have a single path. */
1200+ struct flow * * single_path_flow (const tal_t * ctx , const struct route_query * rq ,
1201+ const struct gossmap_node * source ,
1202+ const struct gossmap_node * target ,
1203+ struct amount_msat amount , u32 mu ,
1204+ double delay_feefactor )
1205+ {
1206+ struct flow * * flow_paths ;
1207+ /* We allocate everything off this, and free it at the end,
1208+ * as we can be called multiple times without cleaning tmpctx! */
1209+ tal_t * working_ctx = tal (NULL , char );
1210+ struct pay_parameters * params = tal (working_ctx , struct pay_parameters );
1211+
1212+ params -> rq = rq ;
1213+ params -> source = source ;
1214+ params -> target = target ;
1215+ params -> amount = amount ;
1216+ /* for the single-path solver the accuracy does not detriment
1217+ * performance */
1218+ params -> accuracy = AMOUNT_MSAT (1000 );
1219+ params -> delay_feefactor = delay_feefactor ;
1220+ params -> base_fee_penalty = base_fee_penalty_estimate (amount );
1221+ params -> prob_cost_factor =
1222+ 1000 * amount_msat_ratio (params -> amount , params -> accuracy );
1223+
1224+ struct graph * graph ;
1225+ double * arc_prob_cost ;
1226+ s64 * arc_fee_cost ;
1227+ s64 * arc_capacity ;
1228+
1229+ init_linear_network_single_path (working_ctx , params , & graph ,
1230+ & arc_prob_cost , & arc_fee_cost ,
1231+ & arc_capacity );
1232+
1233+ const struct node dst = {.idx = gossmap_node_idx (rq -> gossmap , target )};
1234+ const struct node src = {.idx = gossmap_node_idx (rq -> gossmap , source )};
1235+
1236+ const size_t max_num_nodes = graph_max_num_nodes (graph );
1237+ const size_t max_num_arcs = graph_max_num_arcs (graph );
1238+
1239+ s64 * potential = tal_arrz (working_ctx , s64 , max_num_nodes );
1240+ s64 * distance = tal_arrz (working_ctx , s64 , max_num_nodes );
1241+ s64 * arc_cost = tal_arrz (working_ctx , s64 , max_num_arcs );
1242+ struct arc * prev = tal_arrz (working_ctx , struct arc , max_num_nodes );
1243+
1244+ combine_cost_function (working_ctx , graph , arc_prob_cost , arc_fee_cost ,
1245+ rq -> biases , mu , arc_cost );
1246+
1247+ /* We solve a linear cost flow problem. */
1248+ if (!dijkstra_path (working_ctx , graph , src , dst ,
1249+ /* prune = */ true, arc_capacity ,
1250+ /*threshold = */ 1 , arc_cost , potential , prev ,
1251+ distance )) {
1252+ rq_log (tmpctx , rq , LOG_BROKEN ,
1253+ "%s: could not find a feasible single path" , __func__ );
1254+ goto fail ;
1255+ }
1256+ const u64 pay_amount =
1257+ amount_msat_ratio_ceil (params -> amount , params -> accuracy );
1258+
1259+ /* We dissect the flow into payment routes.
1260+ * Actual amounts considering fees are computed for every
1261+ * channel in the routes. */
1262+ flow_paths = get_flow_singlepath (ctx , working_ctx , graph , rq -> gossmap ,
1263+ src , dst , pay_amount , prev );
1264+ if (!flow_paths ) {
1265+ rq_log (tmpctx , rq , LOG_BROKEN ,
1266+ "%s: failed to extract flow paths from the single-path "
1267+ "solution" ,
1268+ __func__ );
1269+ goto fail ;
1270+ }
1271+ if (tal_count (flow_paths ) != 1 ) {
1272+ rq_log (
1273+ tmpctx , rq , LOG_BROKEN ,
1274+ "%s: single-path solution returned a multi route solution" ,
1275+ __func__ );
1276+ goto fail ;
1277+ }
1278+ tal_free (working_ctx );
1279+ return flow_paths ;
1280+
1281+ fail :
1282+ tal_free (working_ctx );
1283+ return NULL ;
1284+ }
10281285
10291286const char * default_routes (const tal_t * ctx , struct route_query * rq ,
10301287 const struct gossmap_node * srcnode ,
0 commit comments