@@ -169,6 +169,9 @@ static const double CHANNEL_PIVOTS[]={0,0.5,0.8,0.95};
169169static const s64 INFINITE = INT64_MAX ;
170170static const s64 MU_MAX = 100 ;
171171
172+ /* every payment under 1000sat will be routed through a single path */
173+ static const struct amount_msat SINGLE_PATH_THRESHOLD = AMOUNT_MSAT (1000000 );
174+
172175/* Let's try this encoding of arcs:
173176 * Each channel `c` has two possible directions identified by a bit
174177 * `half` or `!half`, and each one of them has to be
@@ -1070,22 +1073,6 @@ struct flow **minflow(const tal_t *ctx,
10701073 return NULL ;
10711074}
10721075
1073- static struct amount_msat linear_flows_cost (struct flow * * flows ,
1074- struct amount_msat total_amount ,
1075- double delay_feefactor )
1076- {
1077- struct amount_msat total = AMOUNT_MSAT (0 );
1078-
1079- for (size_t i = 0 ; i < tal_count (flows ); i ++ ) {
1080- if (!amount_msat_accumulate (& total ,
1081- linear_flow_cost (flows [i ],
1082- total_amount ,
1083- delay_feefactor )))
1084- abort ();
1085- }
1086- return total ;
1087- }
1088-
10891076/* Initialize the data vectors for the single-path solver. */
10901077static void init_linear_network_single_path (
10911078 const tal_t * ctx , const struct pay_parameters * params , struct graph * * graph ,
@@ -1266,6 +1253,13 @@ struct flow **single_path_flow(const tal_t *ctx, const struct route_query *rq,
12661253 return NULL ;
12671254}
12681255
1256+ /* FIXME: add extra constraint maximum route length, use an activation
1257+ * probability cost for each channel. Recall that every activation cost, eg.
1258+ * base fee and activation probability can only be properly added modifying the
1259+ * graph topology by creating an activation node for every half channel. */
1260+ /* FIXME: add extra constraint maximum number of routes, fixes issue 8331. */
1261+ /* FIXME: add a boolean option to make recipient pay for fees, fixes issue 8353.
1262+ */
12691263static const char *
12701264linear_routes (const tal_t * ctx , struct route_query * rq ,
12711265 const struct gossmap_node * srcnode ,
@@ -1277,133 +1271,196 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
12771271 const struct gossmap_node * ,
12781272 struct amount_msat , u32 , double ))
12791273{
1280- * flows = NULL ;
1281- const char * ret ;
1282- double delay_feefactor = 1.0 / 1000000 ;
1283-
1284- /* First up, don't care about fees (well, just enough to tiebreak!) */
1274+ const tal_t * working_ctx = tal (ctx , tal_t );
1275+ const char * error_message ;
1276+ struct amount_msat amount_to_deliver = amount ;
1277+ struct amount_msat feebudget = maxfee ;
1278+
1279+ /* FIXME: mu is an integer from 0 to MU_MAX that we use to combine fees
1280+ * and probability costs, but I think we can make it a real number from
1281+ * 0 to 1. */
12851282 u32 mu = 1 ;
1286- tal_free (* flows );
1287- * flows = solver (ctx , rq , srcnode , dstnode , amount , mu , delay_feefactor );
1288- if (!* flows ) {
1289- ret = explain_failure (ctx , rq , srcnode , dstnode , amount );
1290- goto fail ;
1291- }
1283+ /* we start at 1e-6 and increase it exponentially (x2) up to 10. */
1284+ double delay_feefactor = 1e-6 ;
1285+
1286+ struct flow * * new_flows = NULL ;
1287+ struct amount_msat all_deliver ;
1288+
1289+ * flows = tal_arr (working_ctx , struct flow * , 0 );
1290+
1291+ /* Re-use the reservation system to make flows aware of each other. */
1292+ struct reserve_hop * reservations = new_reservations (working_ctx , rq );
1293+
1294+ /* compute the probability one flow at a time. */
1295+ * probability = 1.0 ;
1296+
1297+ while (!amount_msat_is_zero (amount_to_deliver )) {
1298+ new_flows = tal_free (new_flows );
1299+
1300+ /* If the amount_to_deliver is very small we better use a single
1301+ * path computation because:
1302+ * 1. we save cpu cycles
1303+ * 2. we have better control over htlc_min violations.
1304+ * We need to make the distinction here because after
1305+ * refine_with_fees_and_limits we might have a set of flows that
1306+ * do not deliver the entire payment amount by just a small
1307+ * amount. */
1308+ if (amount_msat_less_eq (amount_to_deliver , SINGLE_PATH_THRESHOLD )){
1309+ new_flows = single_path_flow (working_ctx , rq , srcnode , dstnode ,
1310+ amount_to_deliver , mu , delay_feefactor );
1311+ } else {
1312+ new_flows =
1313+ solver (working_ctx , rq , srcnode , dstnode ,
1314+ amount_to_deliver , mu , delay_feefactor );
1315+ }
12921316
1293- /* Too much delay? */
1294- while (finalcltv + flows_worst_delay (* flows ) > maxdelay ) {
1295- delay_feefactor *= 2 ;
1296- rq_log (tmpctx , rq , LOG_UNUSUAL ,
1297- "The worst flow delay is %" PRIu64
1298- " (> %i), retrying with delay_feefactor %f..." ,
1299- flows_worst_delay (* flows ), maxdelay - finalcltv ,
1300- delay_feefactor );
1301- tal_free (* flows );
1302- * flows = solver (ctx , rq , srcnode , dstnode , amount , mu ,
1303- delay_feefactor );
1304- if (!* flows || delay_feefactor > 10 ) {
1305- ret = rq_log (
1306- ctx , rq , LOG_UNUSUAL ,
1307- "Could not find route without excessive delays" );
1317+ if (!new_flows ) {
1318+ error_message = explain_failure (
1319+ ctx , rq , srcnode , dstnode , amount_to_deliver );
13081320 goto fail ;
13091321 }
1310- }
13111322
1312- /* Too expensive? */
1313- too_expensive :
1314- while (amount_msat_greater (flowset_fee (rq -> plugin , * flows ), maxfee )) {
1315- struct flow * * new_flows ;
1316-
1317- if (mu == 1 )
1318- mu = 10 ;
1319- else
1320- mu += 10 ;
1321- rq_log (tmpctx , rq , LOG_UNUSUAL ,
1322- "The flows had a fee of %s, greater than max of %s, "
1323- "retrying with mu of %u%%..." ,
1324- fmt_amount_msat (tmpctx , flowset_fee (rq -> plugin , * flows )),
1325- fmt_amount_msat (tmpctx , maxfee ), mu );
1326- new_flows = solver (ctx , rq , srcnode , dstnode , amount ,
1327- mu > 100 ? 100 : mu , delay_feefactor );
1328- if (!* flows || mu >= 100 ) {
1329- ret = rq_log (
1330- ctx , rq , LOG_UNUSUAL ,
1331- "Could not find route without excessive cost" );
1323+ error_message =
1324+ refine_flows (ctx , rq , amount_to_deliver , & new_flows );
1325+ if (error_message )
13321326 goto fail ;
1327+
1328+ /* we finished removing flows and excess */
1329+ all_deliver = flowset_delivers (rq -> plugin , new_flows );
1330+ if (amount_msat_is_zero (all_deliver )) {
1331+ /* We removed all flows and we have not modified the
1332+ * MCF parameters. We will not have an infinite loop
1333+ * here because at least we have disabled some channels.
1334+ */
1335+ continue ;
1336+ }
1337+
1338+ /* We might want to overpay sometimes, eg. shadow routing, but
1339+ * right now if all_deliver > amount_to_deliver means a bug. */
1340+ assert (amount_msat_greater_eq (amount_to_deliver , all_deliver ));
1341+
1342+ /* no flows should send 0 amount */
1343+ for (size_t i = 0 ; i < tal_count (new_flows ); i ++ ) {
1344+ // FIXME: replace all assertions with LOG_BROKEN
1345+ assert (!amount_msat_is_zero (new_flows [i ]-> delivers ));
13331346 }
13341347
1335- /* This is possible, because MCF's linear fees are not the same.
1336- */
1337- if (amount_msat_greater (flowset_fee (rq -> plugin , new_flows ),
1338- flowset_fee (rq -> plugin , * flows ))) {
1339- struct amount_msat old_cost =
1340- linear_flows_cost (* flows , amount , delay_feefactor );
1341- struct amount_msat new_cost = linear_flows_cost (
1342- new_flows , amount , delay_feefactor );
1343- if (amount_msat_greater_eq (new_cost , old_cost )) {
1344- rq_log (tmpctx , rq , LOG_BROKEN ,
1345- "Old flows cost %s:" ,
1346- fmt_amount_msat (tmpctx , old_cost ));
1347- for (size_t i = 0 ; i < tal_count (* flows ); i ++ ) {
1348- rq_log (
1349- tmpctx , rq , LOG_BROKEN ,
1350- "Flow %zu/%zu: %s (linear cost %s)" ,
1351- i , tal_count (* flows ),
1352- fmt_flow_full (tmpctx , rq , (* flows )[i ]),
1353- fmt_amount_msat (
1354- tmpctx , linear_flow_cost (
1355- (* flows )[i ], amount ,
1356- delay_feefactor )));
1357- }
1358- rq_log (tmpctx , rq , LOG_BROKEN ,
1359- "Old flows cost %s:" ,
1360- fmt_amount_msat (tmpctx , new_cost ));
1361- for (size_t i = 0 ; i < tal_count (new_flows );
1362- i ++ ) {
1363- rq_log (
1364- tmpctx , rq , LOG_BROKEN ,
1365- "Flow %zu/%zu: %s (linear cost %s)" ,
1366- i , tal_count (new_flows ),
1367- fmt_flow_full (tmpctx , rq ,
1368- new_flows [i ]),
1369- fmt_amount_msat (
1370- tmpctx ,
1371- linear_flow_cost (
1372- new_flows [i ], amount ,
1373- delay_feefactor )));
1374- }
1348+ /* Is this set of flows too expensive?
1349+ * We can check if the new flows are within the fee budget,
1350+ * however in some cases we have discarded some flows at this
1351+ * point and the new flows do not deliver all the value we need
1352+ * so that a further solver iteration is needed. Hence we
1353+ * check if the fees paid by these new flows are below the
1354+ * feebudget proportionally adjusted by the amount this set of
1355+ * flows deliver with respect to the total remaining amount,
1356+ * ie. we avoid "consuming" all the feebudget if we still need
1357+ * to run MCF again for some remaining amount. */
1358+ const struct amount_msat all_fees =
1359+ flowset_fee (rq -> plugin , new_flows );
1360+ const double deliver_fraction =
1361+ amount_msat_ratio (all_deliver , amount_to_deliver );
1362+ struct amount_msat partial_feebudget ;
1363+ if (!amount_msat_scale (& partial_feebudget , feebudget ,
1364+ deliver_fraction )) {
1365+ error_message =
1366+ rq_log (ctx , rq , LOG_BROKEN ,
1367+ "%s: failed to scale the fee budget (%s) by "
1368+ "fraction (%lf)" ,
1369+ __func__ , fmt_amount_msat (tmpctx , feebudget ),
1370+ deliver_fraction );
1371+ goto fail ;
1372+ }
1373+ if (amount_msat_greater (all_fees , partial_feebudget )) {
1374+ if (mu < MU_MAX ) {
1375+ /* all_fees exceed the strong budget limit, try
1376+ * to fix it increasing mu. */
1377+ if (mu == 1 )
1378+ mu = 10 ;
1379+ else
1380+ mu += 10 ;
1381+ mu = MIN (mu , MU_MAX );
1382+ rq_log (
1383+ tmpctx , rq , LOG_INFORM ,
1384+ "The flows had a fee of %s, greater than "
1385+ "max of %s, retrying with mu of %u%%..." ,
1386+ fmt_amount_msat (tmpctx , all_fees ),
1387+ fmt_amount_msat (tmpctx , partial_feebudget ),
1388+ mu );
1389+ continue ;
1390+ } else if (amount_msat_greater (all_fees , feebudget )) {
1391+ /* we cannot increase mu anymore and all_fees
1392+ * already exceeds feebudget we fail. */
1393+ error_message =
1394+ rq_log (ctx , rq , LOG_UNUSUAL ,
1395+ "Could not find route without "
1396+ "excessive cost" );
1397+ goto fail ;
1398+ } else {
1399+ /* mu cannot be increased but at least all_fees
1400+ * does not exceed feebudget, we give it a shot.
1401+ */
1402+ rq_log (
1403+ tmpctx , rq , LOG_UNUSUAL ,
1404+ "The flows had a fee of %s, greater than "
1405+ "max of %s, but still within the fee "
1406+ "budget %s, we accept those flows." ,
1407+ fmt_amount_msat (tmpctx , all_fees ),
1408+ fmt_amount_msat (tmpctx , partial_feebudget ),
1409+ fmt_amount_msat (tmpctx , feebudget ));
13751410 }
13761411 }
1377- tal_free (* flows );
1378- * flows = new_flows ;
1379- }
13801412
1381- if (finalcltv + flows_worst_delay (* flows ) > maxdelay ) {
1382- ret = rq_log (
1383- ctx , rq , LOG_UNUSUAL ,
1384- "Could not find route without excessive cost or delays" );
1385- goto fail ;
1386- }
1413+ /* Too much delay? */
1414+ if (finalcltv + flows_worst_delay (new_flows ) > maxdelay ) {
1415+ if (delay_feefactor > 10 ) {
1416+ error_message =
1417+ rq_log (ctx , rq , LOG_UNUSUAL ,
1418+ "Could not find route without "
1419+ "excessive delays" );
1420+ goto fail ;
1421+ }
13871422
1388- /* The above did not take into account the extra funds to pay
1389- * fees, so we try to adjust now. We could re-run MCF if this
1390- * fails, but failure basically never happens where payment is
1391- * still possible */
1392- ret = refine_with_fees_and_limits ( ctx , rq , amount , flows , probability );
1393- if ( ret )
1394- goto fail ;
1423+ delay_feefactor *= 2 ;
1424+ rq_log ( tmpctx , rq , LOG_INFORM ,
1425+ "The worst flow delay is %" PRIu64
1426+ " (> %i), retrying with delay_feefactor %f..." ,
1427+ flows_worst_delay ( * flows ), maxdelay - finalcltv ,
1428+ delay_feefactor );
1429+ }
13951430
1396- /* Again, a tiny corner case: refine step can make us exceed maxfee */
1397- if (amount_msat_greater (flowset_fee (rq -> plugin , * flows ), maxfee )) {
1398- rq_log (tmpctx , rq , LOG_UNUSUAL ,
1399- "After final refinement, fee was excessive: retrying" );
1400- goto too_expensive ;
1431+ /* add the new flows to the final solution */
1432+ for (size_t i = 0 ; i < tal_count (new_flows ); i ++ ) {
1433+ tal_arr_expand (flows , new_flows [i ]);
1434+ tal_steal (* flows , new_flows [i ]);
1435+ * probability *= flow_probability (new_flows [i ], rq );
1436+ create_flow_reservations (rq , & reservations ,
1437+ new_flows [i ]);
1438+ }
1439+
1440+ if (!amount_msat_sub (& feebudget , feebudget , all_fees ) ||
1441+ !amount_msat_sub (& amount_to_deliver , amount_to_deliver ,
1442+ all_deliver )) {
1443+ error_message =
1444+ rq_log (ctx , rq , LOG_BROKEN ,
1445+ "%s: unexpected arithmetic operation "
1446+ "failure on amount_msat" ,
1447+ __func__ );
1448+ goto fail ;
1449+ }
14011450 }
14021451
1452+ /* transfer ownership */
1453+ * flows = tal_steal (ctx , * flows );
1454+
1455+ /* cleanup */
1456+ tal_free (working_ctx );
14031457 return NULL ;
14041458fail :
1405- assert (ret != NULL );
1406- return ret ;
1459+ /* cleanup */
1460+ tal_free (working_ctx );
1461+
1462+ assert (error_message != NULL );
1463+ return error_message ;
14071464}
14081465
14091466const char * default_routes (const tal_t * ctx , struct route_query * rq ,
0 commit comments