@@ -1253,6 +1253,89 @@ struct flow **single_path_flow(const tal_t *ctx, const struct route_query *rq,
1253
1253
return NULL ;
1254
1254
}
1255
1255
1256
+ /* Get the scidd for the i'th hop in flow */
1257
+ static void get_scidd (const struct gossmap * gossmap , const struct flow * flow ,
1258
+ size_t i , struct short_channel_id_dir * scidd )
1259
+ {
1260
+ scidd -> scid = gossmap_chan_scid (gossmap , flow -> path [i ]);
1261
+ scidd -> dir = flow -> dirs [i ];
1262
+ }
1263
+
1264
+ /* We use an fp16_t approximatin for htlc_max/min: this gets the exact value. */
1265
+ static struct amount_msat
1266
+ get_chan_htlc_max (const struct route_query * rq , const struct gossmap_chan * c ,
1267
+ const struct short_channel_id_dir * scidd )
1268
+ {
1269
+ struct amount_msat htlc_max ;
1270
+
1271
+ gossmap_chan_get_update_details (rq -> gossmap , c , scidd -> dir , NULL , NULL ,
1272
+ NULL , NULL , NULL , NULL , NULL ,
1273
+ & htlc_max );
1274
+ return htlc_max ;
1275
+ }
1276
+
1277
+ static struct amount_msat
1278
+ get_chan_htlc_min (const struct route_query * rq , const struct gossmap_chan * c ,
1279
+ const struct short_channel_id_dir * scidd )
1280
+ {
1281
+ struct amount_msat htlc_min ;
1282
+
1283
+ gossmap_chan_get_update_details (rq -> gossmap , c , scidd -> dir , NULL , NULL ,
1284
+ NULL , NULL , NULL , NULL , & htlc_min ,
1285
+ NULL );
1286
+ return htlc_min ;
1287
+ }
1288
+
1289
+ static bool check_htlc_min_limits (struct route_query * rq , struct flow * * flows )
1290
+ {
1291
+
1292
+ for (size_t k = 0 ; k < tal_count (flows ); k ++ ) {
1293
+ struct flow * flow = flows [k ];
1294
+ size_t pathlen = tal_count (flow -> path );
1295
+ struct amount_msat hop_amt = flow -> delivers ;
1296
+ for (size_t i = pathlen - 1 ; i < pathlen ; i -- ) {
1297
+ const struct half_chan * h = flow_edge (flow , i );
1298
+ struct short_channel_id_dir scidd ;
1299
+
1300
+ get_scidd (rq -> gossmap , flow , i , & scidd );
1301
+ struct amount_msat htlc_min =
1302
+ get_chan_htlc_min (rq , flow -> path [i ], & scidd );
1303
+ if (amount_msat_less (hop_amt , htlc_min ))
1304
+ return false;
1305
+
1306
+ if (!amount_msat_add_fee (& hop_amt , h -> base_fee ,
1307
+ h -> proportional_fee ))
1308
+ abort ();
1309
+ }
1310
+ }
1311
+ return true;
1312
+ }
1313
+
1314
+ static bool check_htlc_max_limits (struct route_query * rq , struct flow * * flows )
1315
+ {
1316
+
1317
+ for (size_t k = 0 ; k < tal_count (flows ); k ++ ) {
1318
+ struct flow * flow = flows [k ];
1319
+ size_t pathlen = tal_count (flow -> path );
1320
+ struct amount_msat hop_amt = flow -> delivers ;
1321
+ for (size_t i = pathlen - 1 ; i < pathlen ; i -- ) {
1322
+ const struct half_chan * h = flow_edge (flow , i );
1323
+ struct short_channel_id_dir scidd ;
1324
+
1325
+ get_scidd (rq -> gossmap , flow , i , & scidd );
1326
+ struct amount_msat htlc_max =
1327
+ get_chan_htlc_max (rq , flow -> path [i ], & scidd );
1328
+ if (amount_msat_greater (hop_amt , htlc_max ))
1329
+ return false;
1330
+
1331
+ if (!amount_msat_add_fee (& hop_amt , h -> base_fee ,
1332
+ h -> proportional_fee ))
1333
+ abort ();
1334
+ }
1335
+ }
1336
+ return true;
1337
+ }
1338
+
1256
1339
/* FIXME: add extra constraint maximum route length, use an activation
1257
1340
* probability cost for each channel. Recall that every activation cost, eg.
1258
1341
* base fee and activation probability can only be properly added modifying the
@@ -1471,6 +1554,23 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
1471
1554
* hence after we freed working_ctx. */
1472
1555
* probability = flows_probability (ctx , rq , flows );
1473
1556
1557
+ /* we should have fixed all htlc violations, "don't trust,
1558
+ * verify" */
1559
+ if (!check_htlc_min_limits (rq , * flows )) {
1560
+ error_message =
1561
+ rq_log (rq , rq , LOG_BROKEN ,
1562
+ "%s: check_htlc_min_limits failed" , __func__ );
1563
+ * flows = tal_free (* flows );
1564
+ goto fail ;
1565
+ }
1566
+ if (!check_htlc_max_limits (rq , * flows )) {
1567
+ error_message =
1568
+ rq_log (rq , rq , LOG_BROKEN ,
1569
+ "%s: check_htlc_max_limits failed" , __func__ );
1570
+ * flows = tal_free (* flows );
1571
+ goto fail ;
1572
+ }
1573
+
1474
1574
return NULL ;
1475
1575
fail :
1476
1576
/* cleanup */
0 commit comments