lightningd: don't route private channels via real scid.

Again, we should use the real channel_type, but we approximate.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Protocol: private channels will only route using short-channel-ids if channel opened with option_scid_alias-supporting peer.
This commit is contained in:
Rusty Russell 2022-08-09 05:28:09 +09:30 committed by neil saitug
parent cfe6b06fb5
commit 8a9ce55345
8 changed files with 34 additions and 15 deletions

View File

@ -17,6 +17,7 @@
#include <lightningd/peer_control.h>
#include <lightningd/subd.h>
#include <wallet/txfilter.h>
#include <wire/peer_wire.h>
#include <wire/wire_sync.h>
void channel_set_owner(struct channel *channel, struct subd *owner)
@ -601,20 +602,35 @@ struct channel_inflight *channel_inflight_find(struct channel *channel,
}
struct channel *any_channel_by_scid(struct lightningd *ld,
const struct short_channel_id *scid)
const struct short_channel_id *scid,
bool privacy_leak_ok)
{
struct peer *p;
struct channel *chan;
list_for_each(&ld->peers, p, list) {
list_for_each(&p->channels, chan, list) {
if (chan->scid
&& short_channel_id_eq(scid, chan->scid))
return chan;
/* We also want to find the channel by its local alias
* when we forward. */
/* BOLT-channel-type #2:
* - MUST always recognize the `alias` as a
* `short_channel_id` for incoming HTLCs to this
* channel.
*/
if (chan->alias[LOCAL] &&
short_channel_id_eq(scid, chan->alias[LOCAL]))
return chan;
/* BOLT-channel-type #2:
* - if `channel_type` has `option_scid_alias` set:
* - MUST NOT allow incoming HTLCs to this channel
* using the real `short_channel_id`
*/
/* FIXME: We don't keep type is db, so assume all
* private channels which support aliases want this! */
if (!privacy_leak_ok
&& chan->alias[REMOTE]
&& !(chan->channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL))
continue;
if (chan->scid
&& short_channel_id_eq(scid, chan->scid))
return chan;
}
}
return NULL;

View File

@ -411,8 +411,11 @@ struct channel *peer_any_unsaved_channel(struct peer *peer, bool *others);
struct channel *channel_by_dbid(struct lightningd *ld, const u64 dbid);
/* Includes both real scids and aliases. If !privacy_leak_ok, then private
* channels' real scids are not included. */
struct channel *any_channel_by_scid(struct lightningd *ld,
const struct short_channel_id *scid);
const struct short_channel_id *scid,
bool privacy_leak_ok);
/* Get channel by channel_id */
struct channel *channel_by_cid(struct lightningd *ld,

View File

@ -123,7 +123,7 @@ static void handle_local_channel_update(struct lightningd *ld, const u8 *msg)
/* In theory this could vanish before gossipd gets around to telling
* us. */
channel = any_channel_by_scid(ld, &scid);
channel = any_channel_by_scid(ld, &scid, true);
if (!channel) {
log_broken(ld->log, "Local update for bad scid %s",
type_to_string(tmpctx, struct short_channel_id,

View File

@ -2027,7 +2027,7 @@ command_find_channel(struct command *cmd,
tok->end - tok->start,
buffer + tok->start);
} else if (json_to_short_channel_id(buffer, tok, &scid)) {
*channel = any_channel_by_scid(ld, &scid);
*channel = any_channel_by_scid(ld, &scid, true);
if (!*channel)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Short channel ID not found: '%.*s'",

View File

@ -663,7 +663,7 @@ static void forward_htlc(struct htlc_in *hin,
/* This is a shortcut for specifying next peer; doesn't mean
* the actual channel! */
next = any_channel_by_scid(ld, scid);
next = any_channel_by_scid(ld, scid, false);
if (next) {
struct peer *peer = next->peer;
struct channel *channel;

View File

@ -10,7 +10,8 @@
/* AUTOGENERATED MOCKS START */
/* Generated stub for any_channel_by_scid */
struct channel *any_channel_by_scid(struct lightningd *ld UNNEEDED,
const struct short_channel_id *scid UNNEEDED)
const struct short_channel_id *scid UNNEEDED,
bool privacy_leak_ok UNNEEDED)
{ fprintf(stderr, "any_channel_by_scid called!\n"); abort(); }
/* Generated stub for bitcoind_getutxout_ */
void bitcoind_getutxout_(struct bitcoind *bitcoind UNNEEDED,

View File

@ -1478,7 +1478,6 @@ def test_buy_liquidity_ad_no_v2(node_factory, bitcoind):
compact_lease='029a002d000000004b2003e8')
@pytest.mark.xfail(strict=True, reason="We don't implement yet")
def test_scid_alias_private(node_factory, bitcoind):
"""Test that we don't allow use of real scid for scid_alias-type channels"""
l1, l2, l3 = node_factory.line_graph(3, fundchannel=False, opts=[{}, {},

View File

@ -1857,7 +1857,7 @@ def test_pay_routeboost(node_factory, bitcoind):
assert 'routehint_modifications' not in only_one(status['pay'])
assert 'local_exclusions' not in only_one(status['pay'])
attempts = only_one(status['pay'])['attempts']
scid34 = only_one(l3.rpc.listpeers(l4.info['id'])['peers'])['channels'][0]['short_channel_id']
scid34 = only_one(l3.rpc.listpeers(l4.info['id'])['peers'])['channels'][0]['alias']['local']
assert(len(attempts) == 1)
a = attempts[0]
assert(a['strategy'] == "Initial attempt")
@ -1866,7 +1866,7 @@ def test_pay_routeboost(node_factory, bitcoind):
# With dev-route option we can test longer routehints.
if DEVELOPER:
scid45 = only_one(l4.rpc.listpeers(l5.info['id'])['peers'])['channels'][0]['short_channel_id']
scid45 = only_one(l4.rpc.listpeers(l5.info['id'])['peers'])['channels'][0]['alias']['local']
routel3l4l5 = [{'id': l3.info['id'],
'short_channel_id': scid34,
'fee_base_msat': 1000,
@ -3606,7 +3606,7 @@ def test_keysend_routehint(node_factory):
routehints = [
[
{
'scid': l3.rpc.listpeers()['peers'][0]['channels'][0]['short_channel_id'],
'scid': l3.rpc.listpeers()['peers'][0]['channels'][0]['alias']['remote'],
'id': l2.info['id'],
'feebase': '1msat',
'feeprop': 10,