@@ -1247,6 +1247,89 @@ struct flow **single_path_flow(const tal_t *ctx, const struct route_query *rq,
12471247 return NULL ;
12481248}
12491249
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+
12501333/* FIXME: add extra constraint maximum route length, use an activation
12511334 * probability cost for each channel. Recall that every activation cost, eg.
12521335 * 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,
13331416 * right now if all_deliver > amount_to_deliver means a bug. */
13341417 assert (amount_msat_greater_eq (amount_to_deliver , all_deliver ));
13351418
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+
13361434 /* no flows should send 0 amount */
13371435 for (size_t i = 0 ; i < tal_count (new_flows ); i ++ ) {
13381436 // FIXME: replace all assertions with LOG_BROKEN
0 commit comments