Skip to content

Commit

Permalink
renepay: limit arc capacities by htlc_max
Browse files Browse the repository at this point in the history
In the Min. Cost Flow solver we put a constraint on arcs capacities,
such that the total flow that can be allocated through a channel does
not exceed htlc_max. This solves two previous problem of the htlc_max
constraint at the MCF level.
  • Loading branch information
Lagrang3 authored and rustyrussell committed Apr 2, 2024
1 parent 56ac5ee commit 22a7033
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 5 deletions.
9 changes: 8 additions & 1 deletion plugins/renepay/mcf.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,11 +483,18 @@ static bool linearize_channel(const struct pay_parameters *params,
a = MAX(a,0);
b = MAX(a+1,b);

/* An extra bound on capacity, here we use it to reduce the flow such
* that it does not exceed htlcmax. */
s64 cap_on_capacity =
channel_htlc_max(c, dir).millisatoshis/1000; /* Raw: linearize_channel */

capacity[0]=a;
cost[0]=0;
for(size_t i=1;i<CHANNEL_PARTS;++i)
{
capacity[i] = params->cap_fraction[i]*(b-a);
capacity[i] = MIN(params->cap_fraction[i]*(b-a), cap_on_capacity);
cap_on_capacity -= capacity[i];
assert(cap_on_capacity>=0);

cost[i] = params->cost_fraction[i]
*params->amount.millisatoshis /* Raw: linearize_channel */
Expand Down
4 changes: 2 additions & 2 deletions plugins/renepay/pay.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,9 +483,9 @@ static void gossmod_cb(struct gossmap_localmods *mods,
}

/* FIXME: features? */
gossmap_local_addchan(mods, self, peer, &scidd->scid, NULL);
gossmap_local_addchan(mods, self, peer, scidd->scid, NULL);

gossmap_local_updatechan(mods, &scidd->scid, min, max,
gossmap_local_updatechan(mods, scidd->scid, min, max,
fee_base.millisatoshis, /* Raw: gossmap */
fee_proportional,
cltv_delta,
Expand Down
50 changes: 48 additions & 2 deletions tests/test_renepay.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,12 +489,12 @@ def test_htlc_max(node_factory):
]
)

inv = l6.rpc.invoice("1800000sat", "inv", "description")
inv = l6.rpc.invoice("800000sat", "inv", "description")

l1.rpc.call("renepay", {"invstring": inv["bolt11"]})
l1.wait_for_htlcs()
invoice = only_one(l6.rpc.listinvoices("inv")["invoices"])
assert invoice["amount_received_msat"] >= Millisatoshi("1800000sat")
assert invoice["amount_received_msat"] >= Millisatoshi("800000sat")


def test_previous_sendpays(node_factory, bitcoind):
Expand Down Expand Up @@ -635,3 +635,49 @@ def test_local_htlcmax0(node_factory):
assert details["status"] == "complete"
assert details["amount_msat"] == Millisatoshi(123000)
assert details["destination"] == l3.info["id"]


def test_htlcmax0(node_factory):
"""
Topology:
1----2----4
| |
3----5----6
Tests the plugin when some routes have htlc_max=0.
"""
opts = [
{"disable-mpp": None, "fee-base": 0, "fee-per-satoshi": 0},
{"disable-mpp": None, "fee-base": 0, "fee-per-satoshi": 0},
{"disable-mpp": None, "fee-base": 0, "fee-per-satoshi": 0},
{
"disable-mpp": None,
"fee-base": 0,
"fee-per-satoshi": 0,
"htlc-maximum-msat": 0,
},
{
"disable-mpp": None,
"fee-base": 0,
"fee-per-satoshi": 0,
"htlc-maximum-msat": 800000000,
},
{"disable-mpp": None, "fee-base": 0, "fee-per-satoshi": 0},
]
l1, l2, l3, l4, l5, l6 = node_factory.get_nodes(6, opts=opts)
start_channels(
[
(l1, l2, 10000000),
(l2, l4, 1000000),
(l4, l6, 1000000),
(l1, l3, 10000000),
(l3, l5, 1000000),
(l5, l6, 1000000),
]
)

inv = l6.rpc.invoice("600000sat", "inv", "description")

l1.rpc.call("renepay", {"invstring": inv["bolt11"]})
l1.wait_for_htlcs()
invoice = only_one(l6.rpc.listinvoices("inv")["invoices"])
assert invoice["amount_received_msat"] >= Millisatoshi("600000sat")

0 comments on commit 22a7033

Please sign in to comment.