Skip to content

Commit 44d53dc

Browse files
Lagrang3ShahanaFarooqui
authored andcommitted
renepay: add a channel filtering paymod
We add a channel filtering paymod that disables channels that have very low max_htlc. It can be expanded to consider other properties as well, for instance high base fee, low capacity or high latency. Changelog-Added: renepay: prune the network by disabling channels we don't like, eg. very low max_htlc. Signed-off-by: Lagrang3 <[email protected]>
1 parent c0dd3cd commit 44d53dc

File tree

1 file changed

+77
-14
lines changed

1 file changed

+77
-14
lines changed

plugins/renepay/mods.c

Lines changed: 77 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,71 @@ static struct command_result *knowledgerelax_cb(struct payment *payment)
10801080

10811081
REGISTER_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

Comments
 (0)