@@ -1080,6 +1080,71 @@ static struct command_result *knowledgerelax_cb(struct payment *payment)
10801080
10811081REGISTER_PAYMENT_MODIFIER (knowledgerelax , knowledgerelax_cb );
10821082
1083+ /*****************************************************************************
1084+ * channelfilter
1085+ *
1086+ * Disable some channels. The possible motivations are:
1087+ * - avoid the overhead of unproductive routes that go through channels with
1088+ * very low max_htlc that would lead us to a payment partition with too
1089+ * many HTCLs,
1090+ * - avoid channels with very small capacity as well, for which the probability
1091+ * of success is always small anyways,
1092+ * - discard channels with very high base fee that would break our cost
1093+ * estimation,
1094+ * - avoid high latency tor nodes.
1095+ * All combined should reduce the size of the network we explore hopefully
1096+ * reducing the runtime of the MCF solver (FIXME: I should measure this
1097+ * eventually).
1098+ * FIXME: shall we set these threshold parameters as plugin options?
1099+ */
1100+
1101+ static struct command_result * channelfilter_cb (struct payment * payment )
1102+ {
1103+ assert (payment );
1104+ assert (pay_plugin -> gossmap );
1105+ const double HTLC_MAX_FRACTION = 0.01 ; // 1%
1106+ const u64 HTLC_MAX_STOP_MSAT = 1000000000 ; // 1M sats
1107+
1108+ u64 disabled_count = 0 ;
1109+
1110+
1111+ u64 htlc_max_threshold = HTLC_MAX_FRACTION * payment -> payment_info
1112+ .amount .millisatoshis ; /* Raw: a fraction of this amount. */
1113+ /* Don't exclude channels with htlc_max above HTLC_MAX_STOP_MSAT even if
1114+ * that represents a fraction of the payment smaller than
1115+ * HTLC_MAX_FRACTION. */
1116+ htlc_max_threshold = MIN (htlc_max_threshold , HTLC_MAX_STOP_MSAT );
1117+
1118+ for (const struct gossmap_node * node =
1119+ gossmap_first_node (pay_plugin -> gossmap );
1120+ node ; node = gossmap_next_node (pay_plugin -> gossmap , node )) {
1121+ for (size_t i = 0 ; i < node -> num_chans ; i ++ ) {
1122+ int dir ;
1123+ const struct gossmap_chan * chan = gossmap_nth_chan (
1124+ pay_plugin -> gossmap , node , i , & dir );
1125+ const u64 htlc_max =
1126+ fp16_to_u64 (chan -> half [dir ].htlc_max );
1127+ if (htlc_max < htlc_max_threshold ) {
1128+ struct short_channel_id_dir scidd = {
1129+ .scid = gossmap_chan_scid (
1130+ pay_plugin -> gossmap , chan ),
1131+ .dir = dir };
1132+ disabledmap_add_channel (payment -> disabledmap ,
1133+ scidd );
1134+ disabled_count ++ ;
1135+ }
1136+ }
1137+ }
1138+ // FIXME: prune the network over other parameters, eg. capacity,
1139+ // fees, ...
1140+ plugin_log (pay_plugin -> plugin , LOG_DBG ,
1141+ "channelfilter: disabling %" PRIu64 " channels." ,
1142+ disabled_count );
1143+ return payment_continue (payment );
1144+ }
1145+
1146+ REGISTER_PAYMENT_MODIFIER (channelfilter , channelfilter_cb );
1147+
10831148/*****************************************************************************
10841149 * alwaystrue
10851150 *
@@ -1135,22 +1200,20 @@ void *payment_virtual_program[] = {
11351200 /*4*/ OP_CALL , & knowledgerelax_pay_mod ,
11361201 /*6*/ OP_CALL , & getmychannels_pay_mod ,
11371202 /*8*/ OP_CALL , & routehints_pay_mod ,
1138- // TODO: add a channel filter, for example disable channels that have
1139- // htlcmax < 0.1% of payment amount, or base fee > 100msat, or
1140- // proportional_fee > 10%, or capacity < 10% payment amount
1203+ /*10*/ OP_CALL , & channelfilter_pay_mod ,
11411204 // TODO shadow_additions
11421205 /* do */
1143- /*10 */ OP_CALL , & pendingsendpays_pay_mod ,
1144- /*12 */ OP_CALL , & checktimeout_pay_mod ,
1145- /*14 */ OP_CALL , & refreshgossmap_pay_mod ,
1146- /*16 */ OP_CALL , & compute_routes_pay_mod ,
1147- /*18 */ OP_CALL , & send_routes_pay_mod ,
1206+ /*12 */ OP_CALL , & pendingsendpays_pay_mod ,
1207+ /*14 */ OP_CALL , & checktimeout_pay_mod ,
1208+ /*16 */ OP_CALL , & refreshgossmap_pay_mod ,
1209+ /*18 */ OP_CALL , & compute_routes_pay_mod ,
1210+ /*20 */ OP_CALL , & send_routes_pay_mod ,
11481211 /*do*/
1149- /*20 */ OP_CALL , & sleep_pay_mod ,
1150- /*22 */ OP_CALL , & collect_results_pay_mod ,
1212+ /*22 */ OP_CALL , & sleep_pay_mod ,
1213+ /*24 */ OP_CALL , & collect_results_pay_mod ,
11511214 /*while*/
1152- /*24 */ OP_IF , & nothaveresults_pay_cond , (void * )20 ,
1215+ /*26 */ OP_IF , & nothaveresults_pay_cond , (void * )22 ,
11531216 /* while */
1154- /*27 */ OP_IF , & retry_pay_cond , (void * )10 ,
1155- /*30 */ OP_CALL , & end_pay_mod , /* safety net, default failure if reached */
1156- /*32 */ NULL };
1217+ /*29 */ OP_IF , & retry_pay_cond , (void * )12 ,
1218+ /*32 */ OP_CALL , & end_pay_mod , /* safety net, default failure if reached */
1219+ /*34 */ NULL };
0 commit comments