@@ -1256,6 +1256,13 @@ struct flow **single_path_flow(const tal_t *ctx, const struct route_query *rq,
12561256 return NULL ;
12571257}
12581258
1259+ /* FIXME: add extra constraint maximum route length, use an activation
1260+ * probability cost for each channel. Recall that every activation cost, eg.
1261+ * base fee and activation probability can only be properly added modifying the
1262+ * graph topology by creating an activation node for every half channel. */
1263+ /* FIXME: add extra constraint maximum number of routes, fixes issue 8331. */
1264+ /* FIXME: add a boolean option to make recipient pay for fees, fixes issue 8353.
1265+ */
12591266static const char *
12601267linear_routes (const tal_t * ctx , struct route_query * rq ,
12611268 const struct gossmap_node * srcnode ,
@@ -1267,133 +1274,183 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
12671274 const struct gossmap_node * ,
12681275 struct amount_msat , u32 , double ))
12691276{
1270- * flows = NULL ;
1271- const char * ret ;
1272- double delay_feefactor = 1.0 / 1000000 ;
1273-
1274- /* First up, don't care about fees (well, just enough to tiebreak!) */
1277+ const tal_t * working_ctx = tal (ctx , tal_t );
1278+ const char * error_message ;
1279+ struct amount_msat amount_to_deliver = amount ;
1280+ struct amount_msat feebudget = maxfee ;
1281+
1282+ /* FIXME: mu is an integer from 0 to MU_MAX that we use to combine fees
1283+ * and probability costs, but I think we can make it a real number from
1284+ * 0 to 1. */
12751285 u32 mu = 1 ;
1276- tal_free (* flows );
1277- * flows = solver (ctx , rq , srcnode , dstnode , amount , mu , delay_feefactor );
1278- if (!* flows ) {
1279- ret = explain_failure (ctx , rq , srcnode , dstnode , amount );
1280- goto fail ;
1281- }
1286+ /* we start at 1e-6 and increase it exponentially (x2) up to 10. */
1287+ double delay_feefactor = 1e-6 ;
1288+
1289+ struct flow * * new_flows = NULL ;
1290+
1291+ * flows = tal_arr (working_ctx , struct flow * , 0 );
1292+
1293+ /* Re-use the reservation system to make flows aware of each other. */
1294+ struct reserve_hop * reservations = new_reservations (working_ctx , rq );
1295+
1296+ while (!amount_msat_is_zero (amount_to_deliver )) {
1297+ new_flows = tal_free (new_flows );
12821298
1283- /* Too much delay? */
1284- while (finalcltv + flows_worst_delay (* flows ) > maxdelay ) {
1285- delay_feefactor *= 2 ;
1286- rq_log (tmpctx , rq , LOG_UNUSUAL ,
1287- "The worst flow delay is %" PRIu64
1288- " (> %i), retrying with delay_feefactor %f..." ,
1289- flows_worst_delay (* flows ), maxdelay - finalcltv ,
1290- delay_feefactor );
1291- tal_free (* flows );
1292- * flows = solver (ctx , rq , srcnode , dstnode , amount , mu ,
1293- delay_feefactor );
1294- if (!* flows || delay_feefactor > 10 ) {
1295- ret = rq_log (
1296- ctx , rq , LOG_UNUSUAL ,
1297- "Could not find route without excessive delays" );
1299+ new_flows = solver (working_ctx , rq , srcnode , dstnode ,
1300+ amount_to_deliver , mu , delay_feefactor );
1301+ if (!new_flows ) {
1302+ error_message = explain_failure (
1303+ ctx , rq , srcnode , dstnode , amount_to_deliver );
12981304 goto fail ;
12991305 }
1300- }
13011306
1302- /* Too expensive? */
1303- too_expensive :
1304- while (amount_msat_greater (flowset_fee (rq -> plugin , * flows ), maxfee )) {
1305- struct flow * * new_flows ;
1306-
1307- if (mu == 1 )
1308- mu = 10 ;
1309- else
1310- mu += 10 ;
1311- rq_log (tmpctx , rq , LOG_UNUSUAL ,
1312- "The flows had a fee of %s, greater than max of %s, "
1313- "retrying with mu of %u%%..." ,
1314- fmt_amount_msat (tmpctx , flowset_fee (rq -> plugin , * flows )),
1315- fmt_amount_msat (tmpctx , maxfee ), mu );
1316- new_flows = solver (ctx , rq , srcnode , dstnode , amount ,
1317- mu > 100 ? 100 : mu , delay_feefactor );
1318- if (!* flows || mu >= 100 ) {
1319- ret = rq_log (
1320- ctx , rq , LOG_UNUSUAL ,
1321- "Could not find route without excessive cost" );
1322- goto fail ;
1307+ // TODO:
1308+ // trim flows to meet htlc_max constraints
1309+ // trim flows to deliver no more amount_to_deliver
1310+ //
1311+ // ? increase flows to deliver no less than amount_to_deliver,
1312+ // but
1313+ // take max_deliverable into consideration
1314+ //
1315+ // remove flows that have htlc_min violations, disable the
1316+ // culprit channel
1317+
1318+ // for each flow
1319+ // compute amounts and adjust to htlc max
1320+ // disable some channels to void violations of htlc_min
1321+ // call refine_with_fees_and_limits?
1322+ //
1323+
1324+ /* we finished removing flows and excess */
1325+ const struct amount_msat all_deliver =
1326+ flowset_delivers (rq -> plugin , new_flows );
1327+ if (amount_msat_is_zero (all_deliver )) {
1328+ /* We removed all flows and we have not modified the
1329+ * MCF parameters. We will not have an infinite loop
1330+ * here because at least we have disabled some channels.
1331+ */
1332+ continue ;
13231333 }
13241334
1325- /* This is possible, because MCF's linear fees are not the same.
1326- */
1327- if (amount_msat_greater (flowset_fee (rq -> plugin , new_flows ),
1328- flowset_fee (rq -> plugin , * flows ))) {
1329- struct amount_msat old_cost =
1330- linear_flows_cost (* flows , amount , delay_feefactor );
1331- struct amount_msat new_cost = linear_flows_cost (
1332- new_flows , amount , delay_feefactor );
1333- if (amount_msat_greater_eq (new_cost , old_cost )) {
1334- rq_log (tmpctx , rq , LOG_BROKEN ,
1335- "Old flows cost %s:" ,
1336- fmt_amount_msat (tmpctx , old_cost ));
1337- for (size_t i = 0 ; i < tal_count (* flows ); i ++ ) {
1338- rq_log (
1339- tmpctx , rq , LOG_BROKEN ,
1340- "Flow %zu/%zu: %s (linear cost %s)" ,
1341- i , tal_count (* flows ),
1342- fmt_flow_full (tmpctx , rq , (* flows )[i ]),
1343- fmt_amount_msat (
1344- tmpctx , linear_flow_cost (
1345- (* flows )[i ], amount ,
1346- delay_feefactor )));
1347- }
1348- rq_log (tmpctx , rq , LOG_BROKEN ,
1349- "Old flows cost %s:" ,
1350- fmt_amount_msat (tmpctx , new_cost ));
1351- for (size_t i = 0 ; i < tal_count (new_flows );
1352- i ++ ) {
1353- rq_log (
1354- tmpctx , rq , LOG_BROKEN ,
1355- "Flow %zu/%zu: %s (linear cost %s)" ,
1356- i , tal_count (new_flows ),
1357- fmt_flow_full (tmpctx , rq ,
1358- new_flows [i ]),
1359- fmt_amount_msat (
1360- tmpctx ,
1361- linear_flow_cost (
1362- new_flows [i ], amount ,
1363- delay_feefactor )));
1364- }
1335+ /* We might want to overpay sometimes, eg. shadow routing, but
1336+ * right now if all_deliver > amount_to_deliver means a bug. */
1337+ assert (amount_msat_greater_eq (amount_to_deliver , all_deliver ));
1338+
1339+ /* Is this set of flows too expensive?
1340+ * We can check if the new flows are within the fee budget,
1341+ * however in some cases we have discarded some flows at this
1342+ * point and the new flows do not deliver all the value we need
1343+ * so that a further solver iteration is needed. Hence we
1344+ * check if the fees paid by these new flows are below the
1345+ * feebudget proportionally adjusted by the amount this set of
1346+ * flows deliver with respect to the total remaining amount,
1347+ * ie. we avoid "consuming" all the feebudget if we still need
1348+ * to run MCF again for some remaining amount. */
1349+ const struct amount_msat all_fees =
1350+ flowset_fee (rq -> plugin , new_flows );
1351+ const double deliver_fraction =
1352+ amount_msat_ratio (all_deliver , amount_to_deliver );
1353+ struct amount_msat partial_feebudget ;
1354+ if (!amount_msat_scale (& partial_feebudget , feebudget ,
1355+ deliver_fraction )) {
1356+ error_message =
1357+ rq_log (ctx , rq , LOG_BROKEN ,
1358+ "%s: failed to scale the fee budget (%s) by "
1359+ "fraction (%ld)" ,
1360+ __func__ , fmt_amount_msat (tmpctx , feebudget ),
1361+ deliver_fraction );
1362+ goto fail ;
1363+ }
1364+ if (amount_msat_greater (all_fees , partial_feebudget )) {
1365+ if (mu < MU_MAX ) {
1366+ /* all_fees exceed the strong budget limit, try
1367+ * to fix it increasing mu. */
1368+ if (mu == 1 )
1369+ mu = 10 ;
1370+ else
1371+ mu += 10 ;
1372+ mu = MIN (mu , MU_MAX );
1373+ rq_log (
1374+ tmpctx , rq , LOG_UNUSUAL ,
1375+ "The flows had a fee of %s, greater than "
1376+ "max of %s, retrying with mu of %u%%..." ,
1377+ fmt_amount_msat (tmpctx , all_fees ),
1378+ fmt_amount_msat (tmpctx , partial_feebudget ),
1379+ mu );
1380+ continue ;
1381+ } else if (amount_msat_greater (all_fees , feebudget )) {
1382+ /* we cannot increase mu anymore and all_fees
1383+ * already exceeds feebudget we fail. */
1384+ error_message =
1385+ rq_log (ctx , rq , LOG_UNUSUAL ,
1386+ "Could not find route without "
1387+ "excessive cost" );
1388+ goto fail ;
1389+ } else {
1390+ /* mu cannot be increased but at least all_fees
1391+ * does not exceed feebudget, we give it a shot.
1392+ */
1393+ rq_log (
1394+ tmpctx , rq , LOG_UNUSUAL ,
1395+ "The flows had a fee of %s, greater than "
1396+ "max of %s, but still within the fee "
1397+ "budget %s, we accept those flows." ,
1398+ fmt_amount_msat (tmpctx , all_fees ),
1399+ fmt_amount_msat (tmpctx , partial_feebudget ),
1400+ fmt_amount_msat (tmpctx , feebudget ));
13651401 }
13661402 }
1367- tal_free (* flows );
1368- * flows = new_flows ;
1369- }
13701403
1371- if (finalcltv + flows_worst_delay (* flows ) > maxdelay ) {
1372- ret = rq_log (
1373- ctx , rq , LOG_UNUSUAL ,
1374- "Could not find route without excessive cost or delays" );
1375- goto fail ;
1376- }
1404+ /* Too much delay? */
1405+ if (finalcltv + flows_worst_delay (new_flows ) > maxdelay ) {
1406+ if (delay_feefactor > 10 ) {
1407+ error_message =
1408+ rq_log (ctx , rq , LOG_UNUSUAL ,
1409+ "Could not find route without "
1410+ "excessive delays" );
1411+ goto fail ;
1412+ }
13771413
1378- /* The above did not take into account the extra funds to pay
1379- * fees, so we try to adjust now. We could re-run MCF if this
1380- * fails, but failure basically never happens where payment is
1381- * still possible */
1382- ret = refine_with_fees_and_limits (ctx , rq , amount , flows , probability );
1383- if (ret )
1384- goto fail ;
1414+ delay_feefactor *= 2 ;
1415+ rq_log (tmpctx , rq , LOG_UNUSUAL ,
1416+ "The worst flow delay is %" PRIu64
1417+ " (> %i), retrying with delay_feefactor %f..." ,
1418+ flows_worst_delay (* flows ), maxdelay - finalcltv ,
1419+ delay_feefactor );
1420+ }
1421+
1422+ /* add the new flows to the final solution */
1423+ for (size_t i = 0 ; i < tal_count (new_flows ); i ++ ) {
1424+ tal_arr_expand (flows , new_flows [i ]);
1425+ tal_steal (flows , new_flows [i ]);
1426+ create_flow_reservations (rq , & reservations ,
1427+ new_flows [i ]);
1428+ }
13851429
1386- /* Again, a tiny corner case: refine step can make us exceed maxfee */
1387- if (amount_msat_greater (flowset_fee (rq -> plugin , * flows ), maxfee )) {
1388- rq_log (tmpctx , rq , LOG_UNUSUAL ,
1389- "After final refinement, fee was excessive: retrying" );
1390- goto too_expensive ;
1430+ if (!amount_msat_sub (& feebudget , feebudget , all_fees ) ||
1431+ !amount_msat_sub (& amount_to_deliver , amount_to_deliver ,
1432+ all_deliver )) {
1433+ error_message =
1434+ rq_log (ctx , rq , LOG_BROKEN ,
1435+ "%s: unexpected arithmetic operation "
1436+ "failure on amount_msat" ,
1437+ __func__ );
1438+ goto fail ;
1439+ }
13911440 }
13921441
1442+ /* transfer ownership */
1443+ * flows = tal_steal (ctx , * flows );
1444+
1445+ /* cleanup */
1446+ tal_free (working_ctx );
13931447 return NULL ;
13941448fail :
1395- assert (ret != NULL );
1396- return ret ;
1449+ /* cleanup */
1450+ tal_free (working_ctx );
1451+
1452+ assert (error_message != NULL );
1453+ return error_message ;
13971454}
13981455
13991456const char * default_routes (const tal_t * ctx , struct route_query * rq ,
0 commit comments