@@ -628,6 +628,43 @@ int main(int argc, char *argv[])
628628 path [0 ].dir ,
629629 gossmap_find_chan (gossmap , & path [0 ].scid ));
630630 assert (dij [0 ].score == score );
631+
632+ /*
633+ * Test for a 'NaN-cast' bug in route_score().
634+ *
635+ * This test reproduces a bug that occurs when attempting to
636+ * route a payment whose amount exceeds the capacity of the channel
637+ * it's routed through. The expected behavior is for route() to
638+ * return NULL and set errmsg to "No path found".
639+ *
640+ * However, due to the imprecision of the htlc_max type (fp16_t), the
641+ * channel is not correctly discarded. This causes the route's score
642+ * to be calculated as NaN, and when this NaN is subsequently cast to
643+ * a u64, it results in a runtime error.
644+ *
645+ * The expected UBSan error is:
646+ * runtime error: nan is outside the range of representable values of type 'unsigned long'
647+ */
648+ add_connection (store_fd , 'X' , 'Y' ,
649+ /* base fee */ 40333 ,
650+ /* prop fee */ 57981 ,
651+ /* delay */ 138 ,
652+ /* capacity */ AMOUNT_SAT (7875 ));
653+
654+ node_id ('X' , & src );
655+ node_id ('Y' , & dst );
656+
657+ gossmap_refresh (global_gossmap );
658+
659+ r = route (tmpctx , gossmap ,
660+ gossmap_find_node (gossmap , & src ),
661+ gossmap_find_node (gossmap , & dst ),
662+ /* amount */ AMOUNT_MSAT (7876357 ),
663+ /* Final delay */ 2655 ,
664+ /* riskfactor */ 57.00 ,
665+ /* Max hops */ ROUTING_MAX_HOPS ,
666+ /* payment */ p ,
667+ & errmsg );
631668 }
632669
633670 common_shutdown ();
0 commit comments