@@ -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
@@ -1336,6 +1419,21 @@ linear_routes(const tal_t *ctx, struct route_query *rq,
1336
1419
* right now if all_deliver > amount_to_deliver means a bug. */
1337
1420
assert (amount_msat_greater_eq (amount_to_deliver , all_deliver ));
1338
1421
1422
+ /* we should have fixed all htlc violations, "don't trust,
1423
+ * verify" */
1424
+ if (!check_htlc_min_limits (rq , new_flows )) {
1425
+ error_message = rq_log (
1426
+ rq , rq , LOG_BROKEN ,
1427
+ "%s: check_htlc_min_limits failed" , __func__ );
1428
+ goto fail ;
1429
+ }
1430
+ if (!check_htlc_max_limits (rq , new_flows )) {
1431
+ error_message = rq_log (
1432
+ rq , rq , LOG_BROKEN ,
1433
+ "%s: check_htlc_max_limits failed" , __func__ );
1434
+ goto fail ;
1435
+ }
1436
+
1339
1437
/* no flows should send 0 amount */
1340
1438
for (size_t i = 0 ; i < tal_count (new_flows ); i ++ ) {
1341
1439
// FIXME: replace all assertions with LOG_BROKEN
0 commit comments