@@ -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
@@ -1064,22 +1067,6 @@ struct flow **minflow(const tal_t *ctx,
10641067 return NULL ;
10651068}
10661069
1067- static struct amount_msat linear_flows_cost (struct flow * * flows ,
1068- struct amount_msat total_amount ,
1069- double delay_feefactor )
1070- {
1071- struct amount_msat total = AMOUNT_MSAT (0 );
1072-
1073- for (size_t i = 0 ; i < tal_count (flows ); i ++ ) {
1074- if (!amount_msat_accumulate (& total ,
1075- linear_flow_cost (flows [i ],
1076- total_amount ,
1077- delay_feefactor )))
1078- abort ();
1079- }
1080- return total ;
1081- }
1082-
10831070/* Initialize the data vectors for the single-path solver. */
10841071static void init_linear_network_single_path (
10851072 const tal_t * ctx , const struct pay_parameters * params , struct graph * * graph ,
@@ -1260,6 +1247,13 @@ struct flow **single_path_flow(const tal_t *ctx, const struct route_query *rq,
12601247 return NULL ;
12611248}
12621249
1250+ /* FIXME: add extra constraint maximum route length, use an activation
1251+ * probability cost for each channel. Recall that every activation cost, eg.
1252+ * base fee and activation probability can only be properly added modifying the
1253+ * graph topology by creating an activation node for every half channel. */
1254+ /* FIXME: add extra constraint maximum number of routes, fixes issue 8331. */
1255+ /* FIXME: add a boolean option to make recipient pay for fees, fixes issue 8353.
1256+ */
12631257static const char *
12641258linear_routes (const tal_t * ctx , struct route_query * rq ,
12651259 const struct gossmap_node * srcnode ,
@@ -1271,133 +1265,196 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
12711265 const struct gossmap_node * ,
12721266 struct amount_msat , u32 , double ))
12731267{
1274- * flows = NULL ;
1275- const char * ret ;
1276- double delay_feefactor = 1.0 / 1000000 ;
1277-
1278- /* First up, don't care about fees (well, just enough to tiebreak!) */
1268+ const tal_t * working_ctx = tal (ctx , tal_t );
1269+ const char * error_message ;
1270+ struct amount_msat amount_to_deliver = amount ;
1271+ struct amount_msat feebudget = maxfee ;
1272+
1273+ /* FIXME: mu is an integer from 0 to MU_MAX that we use to combine fees
1274+ * and probability costs, but I think we can make it a real number from
1275+ * 0 to 1. */
12791276 u32 mu = 1 ;
1280- tal_free (* flows );
1281- * flows = solver (ctx , rq , srcnode , dstnode , amount , mu , delay_feefactor );
1282- if (!* flows ) {
1283- ret = explain_failure (ctx , rq , srcnode , dstnode , amount );
1284- goto fail ;
1285- }
1277+ /* we start at 1e-6 and increase it exponentially (x2) up to 10. */
1278+ double delay_feefactor = 1e-6 ;
1279+
1280+ struct flow * * new_flows = NULL ;
1281+ struct amount_msat all_deliver ;
1282+
1283+ * flows = tal_arr (working_ctx , struct flow * , 0 );
1284+
1285+ /* Re-use the reservation system to make flows aware of each other. */
1286+ struct reserve_hop * reservations = new_reservations (working_ctx , rq );
1287+
1288+ /* compute the probability one flow at a time. */
1289+ * probability = 1.0 ;
1290+
1291+ while (!amount_msat_is_zero (amount_to_deliver )) {
1292+ new_flows = tal_free (new_flows );
1293+
1294+ /* If the amount_to_deliver is very small we better use a single
1295+ * path computation because:
1296+ * 1. we save cpu cycles
1297+ * 2. we have better control over htlc_min violations.
1298+ * We need to make the distinction here because after
1299+ * refine_with_fees_and_limits we might have a set of flows that
1300+ * do not deliver the entire payment amount by just a small
1301+ * amount. */
1302+ if (amount_msat_less_eq (amount_to_deliver , SINGLE_PATH_THRESHOLD )){
1303+ new_flows = single_path_flow (working_ctx , rq , srcnode , dstnode ,
1304+ amount_to_deliver , mu , delay_feefactor );
1305+ } else {
1306+ new_flows =
1307+ solver (working_ctx , rq , srcnode , dstnode ,
1308+ amount_to_deliver , mu , delay_feefactor );
1309+ }
12861310
1287- /* Too much delay? */
1288- while (finalcltv + flows_worst_delay (* flows ) > maxdelay ) {
1289- delay_feefactor *= 2 ;
1290- rq_log (tmpctx , rq , LOG_UNUSUAL ,
1291- "The worst flow delay is %" PRIu64
1292- " (> %i), retrying with delay_feefactor %f..." ,
1293- flows_worst_delay (* flows ), maxdelay - finalcltv ,
1294- delay_feefactor );
1295- tal_free (* flows );
1296- * flows = solver (ctx , rq , srcnode , dstnode , amount , mu ,
1297- delay_feefactor );
1298- if (!* flows || delay_feefactor > 10 ) {
1299- ret = rq_log (
1300- ctx , rq , LOG_UNUSUAL ,
1301- "Could not find route without excessive delays" );
1311+ if (!new_flows ) {
1312+ error_message = explain_failure (
1313+ ctx , rq , srcnode , dstnode , amount_to_deliver );
13021314 goto fail ;
13031315 }
1304- }
13051316
1306- /* Too expensive? */
1307- too_expensive :
1308- while (amount_msat_greater (flowset_fee (rq -> plugin , * flows ), maxfee )) {
1309- struct flow * * new_flows ;
1310-
1311- if (mu == 1 )
1312- mu = 10 ;
1313- else
1314- mu += 10 ;
1315- rq_log (tmpctx , rq , LOG_UNUSUAL ,
1316- "The flows had a fee of %s, greater than max of %s, "
1317- "retrying with mu of %u%%..." ,
1318- fmt_amount_msat (tmpctx , flowset_fee (rq -> plugin , * flows )),
1319- fmt_amount_msat (tmpctx , maxfee ), mu );
1320- new_flows = solver (ctx , rq , srcnode , dstnode , amount ,
1321- mu > 100 ? 100 : mu , delay_feefactor );
1322- if (!* flows || mu >= 100 ) {
1323- ret = rq_log (
1324- ctx , rq , LOG_UNUSUAL ,
1325- "Could not find route without excessive cost" );
1317+ error_message =
1318+ refine_flows (ctx , rq , amount_to_deliver , & new_flows );
1319+ if (error_message )
13261320 goto fail ;
1321+
1322+ /* we finished removing flows and excess */
1323+ all_deliver = flowset_delivers (rq -> plugin , new_flows );
1324+ if (amount_msat_is_zero (all_deliver )) {
1325+ /* We removed all flows and we have not modified the
1326+ * MCF parameters. We will not have an infinite loop
1327+ * here because at least we have disabled some channels.
1328+ */
1329+ continue ;
1330+ }
1331+
1332+ /* We might want to overpay sometimes, eg. shadow routing, but
1333+ * right now if all_deliver > amount_to_deliver means a bug. */
1334+ assert (amount_msat_greater_eq (amount_to_deliver , all_deliver ));
1335+
1336+ /* no flows should send 0 amount */
1337+ for (size_t i = 0 ; i < tal_count (new_flows ); i ++ ) {
1338+ // FIXME: replace all assertions with LOG_BROKEN
1339+ assert (!amount_msat_is_zero (new_flows [i ]-> delivers ));
13271340 }
13281341
1329- /* This is possible, because MCF's linear fees are not the same.
1330- */
1331- if (amount_msat_greater (flowset_fee (rq -> plugin , new_flows ),
1332- flowset_fee (rq -> plugin , * flows ))) {
1333- struct amount_msat old_cost =
1334- linear_flows_cost (* flows , amount , delay_feefactor );
1335- struct amount_msat new_cost = linear_flows_cost (
1336- new_flows , amount , delay_feefactor );
1337- if (amount_msat_greater_eq (new_cost , old_cost )) {
1338- rq_log (tmpctx , rq , LOG_BROKEN ,
1339- "Old flows cost %s:" ,
1340- fmt_amount_msat (tmpctx , old_cost ));
1341- for (size_t i = 0 ; i < tal_count (* flows ); i ++ ) {
1342- rq_log (
1343- tmpctx , rq , LOG_BROKEN ,
1344- "Flow %zu/%zu: %s (linear cost %s)" ,
1345- i , tal_count (* flows ),
1346- fmt_flow_full (tmpctx , rq , (* flows )[i ]),
1347- fmt_amount_msat (
1348- tmpctx , linear_flow_cost (
1349- (* flows )[i ], amount ,
1350- delay_feefactor )));
1351- }
1352- rq_log (tmpctx , rq , LOG_BROKEN ,
1353- "Old flows cost %s:" ,
1354- fmt_amount_msat (tmpctx , new_cost ));
1355- for (size_t i = 0 ; i < tal_count (new_flows );
1356- i ++ ) {
1357- rq_log (
1358- tmpctx , rq , LOG_BROKEN ,
1359- "Flow %zu/%zu: %s (linear cost %s)" ,
1360- i , tal_count (new_flows ),
1361- fmt_flow_full (tmpctx , rq ,
1362- new_flows [i ]),
1363- fmt_amount_msat (
1364- tmpctx ,
1365- linear_flow_cost (
1366- new_flows [i ], amount ,
1367- delay_feefactor )));
1368- }
1342+ /* Is this set of flows too expensive?
1343+ * We can check if the new flows are within the fee budget,
1344+ * however in some cases we have discarded some flows at this
1345+ * point and the new flows do not deliver all the value we need
1346+ * so that a further solver iteration is needed. Hence we
1347+ * check if the fees paid by these new flows are below the
1348+ * feebudget proportionally adjusted by the amount this set of
1349+ * flows deliver with respect to the total remaining amount,
1350+ * ie. we avoid "consuming" all the feebudget if we still need
1351+ * to run MCF again for some remaining amount. */
1352+ const struct amount_msat all_fees =
1353+ flowset_fee (rq -> plugin , new_flows );
1354+ const double deliver_fraction =
1355+ amount_msat_ratio (all_deliver , amount_to_deliver );
1356+ struct amount_msat partial_feebudget ;
1357+ if (!amount_msat_scale (& partial_feebudget , feebudget ,
1358+ deliver_fraction )) {
1359+ error_message =
1360+ rq_log (ctx , rq , LOG_BROKEN ,
1361+ "%s: failed to scale the fee budget (%s) by "
1362+ "fraction (%lf)" ,
1363+ __func__ , fmt_amount_msat (tmpctx , feebudget ),
1364+ deliver_fraction );
1365+ goto fail ;
1366+ }
1367+ if (amount_msat_greater (all_fees , partial_feebudget )) {
1368+ if (mu < MU_MAX ) {
1369+ /* all_fees exceed the strong budget limit, try
1370+ * to fix it increasing mu. */
1371+ if (mu == 1 )
1372+ mu = 10 ;
1373+ else
1374+ mu += 10 ;
1375+ mu = MIN (mu , MU_MAX );
1376+ rq_log (
1377+ tmpctx , rq , LOG_INFORM ,
1378+ "The flows had a fee of %s, greater than "
1379+ "max of %s, retrying with mu of %u%%..." ,
1380+ fmt_amount_msat (tmpctx , all_fees ),
1381+ fmt_amount_msat (tmpctx , partial_feebudget ),
1382+ mu );
1383+ continue ;
1384+ } else if (amount_msat_greater (all_fees , feebudget )) {
1385+ /* we cannot increase mu anymore and all_fees
1386+ * already exceeds feebudget we fail. */
1387+ error_message =
1388+ rq_log (ctx , rq , LOG_UNUSUAL ,
1389+ "Could not find route without "
1390+ "excessive cost" );
1391+ goto fail ;
1392+ } else {
1393+ /* mu cannot be increased but at least all_fees
1394+ * does not exceed feebudget, we give it a shot.
1395+ */
1396+ rq_log (
1397+ tmpctx , rq , LOG_UNUSUAL ,
1398+ "The flows had a fee of %s, greater than "
1399+ "max of %s, but still within the fee "
1400+ "budget %s, we accept those flows." ,
1401+ fmt_amount_msat (tmpctx , all_fees ),
1402+ fmt_amount_msat (tmpctx , partial_feebudget ),
1403+ fmt_amount_msat (tmpctx , feebudget ));
13691404 }
13701405 }
1371- tal_free (* flows );
1372- * flows = new_flows ;
1373- }
13741406
1375- if (finalcltv + flows_worst_delay (* flows ) > maxdelay ) {
1376- ret = rq_log (
1377- ctx , rq , LOG_UNUSUAL ,
1378- "Could not find route without excessive cost or delays" );
1379- goto fail ;
1380- }
1407+ /* Too much delay? */
1408+ if (finalcltv + flows_worst_delay (new_flows ) > maxdelay ) {
1409+ if (delay_feefactor > 10 ) {
1410+ error_message =
1411+ rq_log (ctx , rq , LOG_UNUSUAL ,
1412+ "Could not find route without "
1413+ "excessive delays" );
1414+ goto fail ;
1415+ }
13811416
1382- /* The above did not take into account the extra funds to pay
1383- * fees, so we try to adjust now. We could re-run MCF if this
1384- * fails, but failure basically never happens where payment is
1385- * still possible */
1386- ret = refine_with_fees_and_limits ( ctx , rq , amount , flows , probability );
1387- if ( ret )
1388- goto fail ;
1417+ delay_feefactor *= 2 ;
1418+ rq_log ( tmpctx , rq , LOG_INFORM ,
1419+ "The worst flow delay is %" PRIu64
1420+ " (> %i), retrying with delay_feefactor %f..." ,
1421+ flows_worst_delay ( * flows ), maxdelay - finalcltv ,
1422+ delay_feefactor );
1423+ }
13891424
1390- /* Again, a tiny corner case: refine step can make us exceed maxfee */
1391- if (amount_msat_greater (flowset_fee (rq -> plugin , * flows ), maxfee )) {
1392- rq_log (tmpctx , rq , LOG_UNUSUAL ,
1393- "After final refinement, fee was excessive: retrying" );
1394- goto too_expensive ;
1425+ /* add the new flows to the final solution */
1426+ for (size_t i = 0 ; i < tal_count (new_flows ); i ++ ) {
1427+ tal_arr_expand (flows , new_flows [i ]);
1428+ tal_steal (* flows , new_flows [i ]);
1429+ * probability *= flow_probability (new_flows [i ], rq );
1430+ create_flow_reservations (rq , & reservations ,
1431+ new_flows [i ]);
1432+ }
1433+
1434+ if (!amount_msat_sub (& feebudget , feebudget , all_fees ) ||
1435+ !amount_msat_sub (& amount_to_deliver , amount_to_deliver ,
1436+ all_deliver )) {
1437+ error_message =
1438+ rq_log (ctx , rq , LOG_BROKEN ,
1439+ "%s: unexpected arithmetic operation "
1440+ "failure on amount_msat" ,
1441+ __func__ );
1442+ goto fail ;
1443+ }
13951444 }
13961445
1446+ /* transfer ownership */
1447+ * flows = tal_steal (ctx , * flows );
1448+
1449+ /* cleanup */
1450+ tal_free (working_ctx );
13971451 return NULL ;
13981452fail :
1399- assert (ret != NULL );
1400- return ret ;
1453+ /* cleanup */
1454+ tal_free (working_ctx );
1455+
1456+ assert (error_message != NULL );
1457+ return error_message ;
14011458}
14021459
14031460const char * default_routes (const tal_t * ctx , struct route_query * rq ,
0 commit comments