invoice: ignore dead-end heuristic on explicitly specified channels.

This makes testing easier, and makes sense: lightningd might not
*know* about other connected channels, depending on gossip, but if the
user specifies it we should obey it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: JSON: `invoice` `exposeprivatechannels` now includes explicitly named channels even if they seem like dead-ends.
This commit is contained in:
Rusty Russell 2020-04-08 17:10:58 +09:30 committed by neil saitug
parent 1d29228136
commit df31af5221
4 changed files with 29 additions and 7 deletions

View File

@ -61,7 +61,7 @@ logic, which will use unpublished channels only if there are no
published channels\. If \fItrue\fR unpublished channels are always considered
as a route hint candidate; if \fIfalse\fR, never\. If it is a short channel id
(e\.g\. \fI1x1x3\fR) or array of short channel ids, only those specific channels
will be considered candidates, even if they are public\.
will be considered candidates, even if they are public or dead-ends\.
The route hint is selected from the set of incoming channels of which:

View File

@ -56,7 +56,7 @@ logic, which will use unpublished channels only if there are no
published channels. If *true* unpublished channels are always considered
as a route hint candidate; if *false*, never. If it is a short channel id
(e.g. *1x1x3*) or array of short channel ids, only those specific channels
will be considered candidates, even if they are public.
will be considered candidates, even if they are public or dead-ends.
The route hint is selected from the set of incoming channels of which:
peers balance minus their reserves is at least *msatoshi*, state is

View File

@ -640,7 +640,11 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
&inchans[i].short_channel_id)) {
tal_arr_remove(&inchans, i);
tal_arr_remove(&inchan_deadends, i);
}
i--;
} else
/* If they specify directly, we don't
* care if it's a deadend */
inchan_deadends[i] = false;
}
/* If they told us to use scids and we couldn't, fail. */

View File

@ -284,13 +284,13 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
assert r['cltv_expiry_delta'] == 6
# Ask it explicitly to use a channel it can't (insufficient capacity)
inv = l2.rpc.invoice(msatoshi=10, label="inv5", description="?", exposeprivatechannels=scid2)
assert 'warning_deadends' in inv
assert 'warning_capacity' not in inv
inv = l2.rpc.invoice(msatoshi=(10**5) * 1000 + 1, label="inv5", description="?", exposeprivatechannels=scid2)
assert 'warning_deadends' not in inv
assert 'warning_capacity' in inv
assert 'warning_offline' not in inv
# Give it two options and it will pick one with suff capacity.
inv = l2.rpc.invoice(msatoshi=10, label="inv6", description="?", exposeprivatechannels=[scid2, scid])
inv = l2.rpc.invoice(msatoshi=(10**5) * 1000 + 1, label="inv6", description="?", exposeprivatechannels=[scid2, scid])
assert 'warning_capacity' not in inv
assert 'warning_offline' not in inv
assert 'warning_deadends' not in inv
@ -302,6 +302,24 @@ def test_invoice_routeboost_private(node_factory, bitcoind):
assert r['fee_proportional_millionths'] == 10
assert r['cltv_expiry_delta'] == 6
# It will use an explicit exposeprivatechannels even if it thinks its a dead-end
l0.rpc.close(l1.info['id'])
l0.wait_for_channel_onchain(l1.info['id'])
bitcoind.generate_block(1)
wait_for(lambda: l2.rpc.listchannels(scid_dummy)['channels'] == [])
inv = l2.rpc.invoice(msatoshi=123456, label="inv7", description="?", exposeprivatechannels=scid)
assert 'warning_capacity' not in inv
assert 'warning_offline' not in inv
assert 'warning_deadends' not in inv
# Route array has single route with single element.
r = only_one(only_one(l1.rpc.decodepay(inv['bolt11'])['routes']))
assert r['pubkey'] == l1.info['id']
assert r['short_channel_id'] == l1.rpc.listchannels()['channels'][0]['short_channel_id']
assert r['fee_base_msat'] == 1
assert r['fee_proportional_millionths'] == 10
assert r['cltv_expiry_delta'] == 6
def test_invoice_expiry(node_factory, executor):
l1, l2 = node_factory.line_graph(2, fundchannel=True)