@@ -1247,6 +1247,89 @@ struct flow **single_path_flow(const tal_t *ctx, const struct route_query *rq,
1247
1247
return NULL ;
1248
1248
}
1249
1249
1250
+ /* Get the scidd for the i'th hop in flow */
1251
+ static void get_scidd (const struct gossmap * gossmap , const struct flow * flow ,
1252
+ size_t i , struct short_channel_id_dir * scidd )
1253
+ {
1254
+ scidd -> scid = gossmap_chan_scid (gossmap , flow -> path [i ]);
1255
+ scidd -> dir = flow -> dirs [i ];
1256
+ }
1257
+
1258
+ /* We use an fp16_t approximatin for htlc_max/min: this gets the exact value. */
1259
+ static struct amount_msat
1260
+ get_chan_htlc_max (const struct route_query * rq , const struct gossmap_chan * c ,
1261
+ const struct short_channel_id_dir * scidd )
1262
+ {
1263
+ struct amount_msat htlc_max ;
1264
+
1265
+ gossmap_chan_get_update_details (rq -> gossmap , c , scidd -> dir , NULL , NULL ,
1266
+ NULL , NULL , NULL , NULL , NULL ,
1267
+ & htlc_max );
1268
+ return htlc_max ;
1269
+ }
1270
+
1271
+ static struct amount_msat
1272
+ get_chan_htlc_min (const struct route_query * rq , const struct gossmap_chan * c ,
1273
+ const struct short_channel_id_dir * scidd )
1274
+ {
1275
+ struct amount_msat htlc_min ;
1276
+
1277
+ gossmap_chan_get_update_details (rq -> gossmap , c , scidd -> dir , NULL , NULL ,
1278
+ NULL , NULL , NULL , NULL , & htlc_min ,
1279
+ NULL );
1280
+ return htlc_min ;
1281
+ }
1282
+
1283
+ static bool check_htlc_min_limits (struct route_query * rq , struct flow * * flows )
1284
+ {
1285
+
1286
+ for (size_t k = 0 ; k < tal_count (flows ); k ++ ) {
1287
+ struct flow * flow = flows [k ];
1288
+ size_t pathlen = tal_count (flow -> path );
1289
+ struct amount_msat hop_amt = flow -> delivers ;
1290
+ for (size_t i = pathlen - 1 ; i < pathlen ; i -- ) {
1291
+ const struct half_chan * h = flow_edge (flow , i );
1292
+ struct short_channel_id_dir scidd ;
1293
+
1294
+ get_scidd (rq -> gossmap , flow , i , & scidd );
1295
+ struct amount_msat htlc_min =
1296
+ get_chan_htlc_min (rq , flow -> path [i ], & scidd );
1297
+ if (amount_msat_less (hop_amt , htlc_min ))
1298
+ return false;
1299
+
1300
+ if (!amount_msat_add_fee (& hop_amt , h -> base_fee ,
1301
+ h -> proportional_fee ))
1302
+ abort ();
1303
+ }
1304
+ }
1305
+ return true;
1306
+ }
1307
+
1308
+ static bool check_htlc_max_limits (struct route_query * rq , struct flow * * flows )
1309
+ {
1310
+
1311
+ for (size_t k = 0 ; k < tal_count (flows ); k ++ ) {
1312
+ struct flow * flow = flows [k ];
1313
+ size_t pathlen = tal_count (flow -> path );
1314
+ struct amount_msat hop_amt = flow -> delivers ;
1315
+ for (size_t i = pathlen - 1 ; i < pathlen ; i -- ) {
1316
+ const struct half_chan * h = flow_edge (flow , i );
1317
+ struct short_channel_id_dir scidd ;
1318
+
1319
+ get_scidd (rq -> gossmap , flow , i , & scidd );
1320
+ struct amount_msat htlc_max =
1321
+ get_chan_htlc_max (rq , flow -> path [i ], & scidd );
1322
+ if (amount_msat_greater (hop_amt , htlc_max ))
1323
+ return false;
1324
+
1325
+ if (!amount_msat_add_fee (& hop_amt , h -> base_fee ,
1326
+ h -> proportional_fee ))
1327
+ abort ();
1328
+ }
1329
+ }
1330
+ return true;
1331
+ }
1332
+
1250
1333
/* FIXME: add extra constraint maximum route length, use an activation
1251
1334
* probability cost for each channel. Recall that every activation cost, eg.
1252
1335
* base fee and activation probability can only be properly added modifying the
@@ -1333,6 +1416,21 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
1333
1416
* right now if all_deliver > amount_to_deliver means a bug. */
1334
1417
assert (amount_msat_greater_eq (amount_to_deliver , all_deliver ));
1335
1418
1419
+ /* we should have fixed all htlc violations, "don't trust,
1420
+ * verify" */
1421
+ if (!check_htlc_min_limits (rq , new_flows )) {
1422
+ error_message = rq_log (
1423
+ rq , rq , LOG_BROKEN ,
1424
+ "%s: check_htlc_min_limits failed" , __func__ );
1425
+ goto fail ;
1426
+ }
1427
+ if (!check_htlc_max_limits (rq , new_flows )) {
1428
+ error_message = rq_log (
1429
+ rq , rq , LOG_BROKEN ,
1430
+ "%s: check_htlc_max_limits failed" , __func__ );
1431
+ goto fail ;
1432
+ }
1433
+
1336
1434
/* no flows should send 0 amount */
1337
1435
for (size_t i = 0 ; i < tal_count (new_flows ); i ++ ) {
1338
1436
// FIXME: replace all assertions with LOG_BROKEN
0 commit comments