Skip to content

Commit

Permalink
Merge branch 'master' into evansmj/autogenerate-schemas-docs-clarity-…
Browse files Browse the repository at this point in the history
…and-spellings
  • Loading branch information
evansmj authored Aug 26, 2024
2 parents 4d6c917 + 9d88ce3 commit 78ac895
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 26 deletions.
3 changes: 2 additions & 1 deletion plugins/askrene/askrene.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ static fp16_t *get_capacities(const tal_t *ctx,
"get_capacity failed for channel?");
cap = AMOUNT_SAT(0);
}
/* Pessimistic: round down! */
caps[gossmap_chan_idx(gossmap, c)]
= u64_to_fp16(cap.satoshis, true); /* Raw: fp16 */
= u64_to_fp16(cap.satoshis, false); /* Raw: fp16 */
}
return caps;
}
Expand Down
25 changes: 19 additions & 6 deletions plugins/askrene/mcf.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,13 @@ static struct arc node_adjacency_next(
return linear_network->node_adjacency_next_arc[arc.idx];
}

/* Set *capacity to value, up to *cap_on_capacity. Reduce cap_on_capacity */
static void set_capacity(s64 *capacity, u64 value, u64 *cap_on_capacity)
{
*capacity = MIN(value, *cap_on_capacity);
*cap_on_capacity -= *capacity;
}

// TODO(eduardo): unit test this
/* Split a directed channel into parts with linear cost function. */
static void linearize_channel(const struct pay_parameters *params,
Expand All @@ -446,9 +453,17 @@ static void linearize_channel(const struct pay_parameters *params,

/* This takes into account any payments in progress. */
get_constraints(params->rq, c, dir, &mincap, &maxcap);
/* Assume if min > max, max is wrong */

/* We seem to have some rounding error (perhaps due to our use
* of sats and fee interactions?). Since it's unusual to see
* a large unmber of flows, even if each overflows by 1 sat,
* 5 sats should be plenty. */
if (!amount_msat_sub(&maxcap, maxcap, AMOUNT_MSAT(5000)))
maxcap = AMOUNT_MSAT(0);

/* Assume if min > max, min is wrong */
if (amount_msat_greater(mincap, maxcap))
maxcap = mincap;
mincap = maxcap;

u64 a = mincap.millisatoshis/1000, /* Raw: linearize_channel */
b = 1 + maxcap.millisatoshis/1000; /* Raw: linearize_channel */
Expand All @@ -457,13 +472,11 @@ static void linearize_channel(const struct pay_parameters *params,
* that it does not exceed htlcmax. */
u64 cap_on_capacity = fp16_to_u64(c->half[dir].htlc_max) / 1000;

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

cost[i] = params->cost_fraction[i]
*params->amount.millisatoshis /* Raw: linearize_channel */
Expand Down
50 changes: 31 additions & 19 deletions tests/test_askrene.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ def test_getroutes(node_factory):
amount_msat=1000,
layers=[],
maxfee_msat=1000,
final_cltv=99) == {'probability_ppm': 999999,
'routes': [{'probability_ppm': 999999,
final_cltv=99) == {'probability_ppm': 999998,
'routes': [{'probability_ppm': 999998,
'final_cltv': 99,
'amount_msat': 1000,
'path': [{'short_channel_id': '0x1x0',
Expand All @@ -184,8 +184,8 @@ def test_getroutes(node_factory):
amount_msat=100000,
layers=[],
maxfee_msat=5000,
final_cltv=99) == {'probability_ppm': 999798,
'routes': [{'probability_ppm': 999798,
final_cltv=99) == {'probability_ppm': 999797,
'routes': [{'probability_ppm': 999797,
'final_cltv': 99,
'amount_msat': 100000,
'path': [{'short_channel_id': '0x1x0',
Expand Down Expand Up @@ -247,11 +247,11 @@ def test_getroutes(node_factory):
10000000,
[[{'short_channel_id': '0x2x1',
'next_node_id': nodemap[2],
'amount_msat': 500000,
'amount_msat': 505000,
'delay': 99 + 6}],
[{'short_channel_id': '0x2x3',
'next_node_id': nodemap[2],
'amount_msat': 9500009,
'amount_msat': 9495009,
'delay': 99 + 6}]])


Expand Down Expand Up @@ -313,8 +313,8 @@ def test_getroutes_auto_sourcefree(node_factory):
amount_msat=1000,
layers=['auto.sourcefree'],
maxfee_msat=1000,
final_cltv=99) == {'probability_ppm': 999999,
'routes': [{'probability_ppm': 999999,
final_cltv=99) == {'probability_ppm': 999998,
'routes': [{'probability_ppm': 999998,
'final_cltv': 99,
'amount_msat': 1000,
'path': [{'short_channel_id': '0x1x0',
Expand All @@ -328,8 +328,8 @@ def test_getroutes_auto_sourcefree(node_factory):
amount_msat=100000,
layers=['auto.sourcefree'],
maxfee_msat=5000,
final_cltv=99) == {'probability_ppm': 999798,
'routes': [{'probability_ppm': 999798,
final_cltv=99) == {'probability_ppm': 999797,
'routes': [{'probability_ppm': 999797,
'final_cltv': 99,
'amount_msat': 100000,
'path': [{'short_channel_id': '0x1x0',
Expand Down Expand Up @@ -451,7 +451,8 @@ def test_fees_dont_exceed_constraints(node_factory):
assert amount <= max_msat


def test_mpp_pay2(node_factory, bitcoind):
def test_live_spendable(node_factory, bitcoind):
"""Test we don't exceed spendable limits on a real network on nodes"""
l1, l2, l3 = node_factory.get_nodes(3)
l1.fundwallet(10_000_000)
l2.fundwallet(10_000_000)
Expand Down Expand Up @@ -480,11 +481,22 @@ def test_mpp_pay2(node_factory, bitcoind):

# Don't exceed spendable_msat
maxes = {}
for chan in l1.rpc.listpeerchannels()['channels']:
maxes["{}/{}".format(chan['short_channel_id'], chan['direction'])] = chan['spendable_msat']

for r in routes['routes']:
for p in r['path']:
scidd = "{}/{}".format(p['short_channel_id'], p['direction'])
if scidd in maxes:
assert p['amount_msat'] <= maxes[scidd]
for chan in l1.rpc.listpeerchannels()["channels"]:
maxes["{}/{}".format(chan["short_channel_id"], chan["direction"])] = chan[
"spendable_msat"
]

path_total = {}
for r in routes["routes"]:
key = "{}/{}".format(
r["path"][0]["short_channel_id"], r["path"][0]["direction"]
)
path_total[key] = path_total.get(key, 0) + r["path"][0]["amount_msat"]

exceeded = {}
for scidd in maxes.keys():
if scidd in path_total:
if path_total[scidd] > maxes[scidd]:
exceeded[scidd] = f"Path total {path_total[scidd]} > spendable {maxes[scidd]}"

assert exceeded == {}
2 changes: 2 additions & 0 deletions tests/test_renepay.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import subprocess
import os
import re
import unittest


def test_simple(node_factory):
Expand Down Expand Up @@ -770,6 +771,7 @@ def test_privatechan(node_factory, bitcoind):
assert invoice["amount_received_msat"] >= Millisatoshi("1000sat")


@unittest.skipIf(TEST_NETWORK == 'liquid-regtest', "broken for some reason")
def test_hardmpp2(node_factory, bitcoind):
"""Credits to @daywalker90 for this test case."""
opts = {"disable-mpp": None, "fee-base": 0, "fee-per-satoshi": 10}
Expand Down

0 comments on commit 78ac895

Please sign in to comment.