Skip to content

Commit

Permalink
openingd: work harder to intuit OPT_SCID_ALIAS.
Browse files Browse the repository at this point in the history
option_scid_alias inside a channel_type allows for more private
channels: in particular, it tells the peer that it MUST NOT allow
routing via the real short channel id, and MUST use the alias.

It only makes sense (and is only permitted!) on unannounced channels.

Unfortunately, we didn't set this bit in the channel_type in v12.0
when it was introduced, instead relying on the presence of the feature
bit with the peer.  This was fixed in 23.05, but:

1. Prior to 23.05 we didn't allow it to be set at all, and
2. LND has a limited set of features they allow, and this isn't allowed without
   option_anchors_zero_fee_htlc_tx.

We could simply drop this channel_type until we merge anchors, *but*
that has nasty privacy implications (you can probe the real channel id).

So, if we don't negotiate anchors (we don't!), we don't set this
channel_type bit even if we want it, and *intuit* it, based on:

1. Is this a non-anchor channel_type?
2. Did we both send channel_type?
3. Is this an unannounced channel?
4. Did both peers announce support for scid aliases?

In addition, while looking at the previous backwards-compat code, I
realized that v23.05 violated the spec and send accept_channel with
OPT_SCID_ALIAS if it intuited it, even if it wasn't offered.  Stop
doing this, but allow our peers to.

Signed-off-by: Rusty Russell <[email protected]>
Changelog-Fixed: Fix incompatibility with LND which prevented us opening private channels
Fixes: ElementsProject#6208
  • Loading branch information
rustyrussell committed Jun 5, 2023
1 parent 50a7681 commit adeb7d8
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 31 deletions.
3 changes: 1 addition & 2 deletions lightningd/opening_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -964,8 +964,7 @@ bool peer_start_openingd(struct peer *peer, struct peer_fd *peer_fd)
feerate_min(peer->ld, NULL),
feerate_max(peer->ld, NULL),
IFDEV(peer->ld->dev_force_tmp_channel_id, NULL),
peer->ld->config.allowdustreserve,
!deprecated_apis);
peer->ld->config.allowdustreserve);
subd_send_msg(uc->open_daemon, take(msg));
return true;
}
Expand Down
102 changes: 75 additions & 27 deletions openingd/openingd.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ struct state {
struct amount_sat *reserve;

bool allowdustreserve;

/* Are we allowed to set option_scid_alias is channel_type? */
bool can_set_scid_alias_channel_type;
};

/*~ If we can't agree on parameters, we fail to open the channel.
Expand Down Expand Up @@ -300,6 +297,33 @@ static void set_remote_upfront_shutdown(struct state *state,
peer_failed_err(state->pps, &state->channel_id, "%s", err);
}

/* Since we can't send OPT_SCID_ALIAS due to compat issues, intuit whether
* we really actually want it anyway, we just can't say that. */
static bool intuit_scid_alias_type(struct state *state, u8 channel_flags,
bool peer_sent_channel_type)
{
/* Don't need to untuit if actually set */
if (channel_type_has(state->channel_type, OPT_SCID_ALIAS))
return false;

/* Old clients didn't send channel_type at all */
if (!peer_sent_channel_type)
return false;

/* Modern peer: no intuit hacks necessary. */
if (channel_type_has(state->channel_type, OPT_ANCHORS_ZERO_FEE_HTLC_TX))
return false;

/* Public channel: don't want OPT_SCID_ALIAS which means "only use
* alias". */
if (channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL)
return false;

/* If we both support it, presumably we want it? */
return feature_negotiated(state->our_features, state->their_features,
OPT_SCID_ALIAS);
}

/* We start the 'open a channel' negotation with the supplied peer, but
* stop when we get to the part where we need the funding txid */
static u8 *funder_channel_start(struct state *state, u8 channel_flags)
Expand Down Expand Up @@ -336,9 +360,16 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags)
state->their_features);

/* Spec says we should use the option_scid_alias variation if we
* want them to *only* use the scid_alias. But we didn't accept this
* in CLN prior to v23.05, so we don't send that in deprecated mode! */
if (state->can_set_scid_alias_channel_type) {
* want them to *only* use the scid_alias (which we do for unannounced
* channels!).
*
* But:
* 1. We didn't accept this in CLN prior to v23.05.
* 2. LND won't accept that without OPT_ANCHORS_ZERO_FEE_HTLC_TX.
*
* So we keep it off for now, until anchors merge.
*/
if (channel_type_has(state->channel_type, OPT_ANCHORS_ZERO_FEE_HTLC_TX)) {
if (!(channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL))
channel_type_set_scid_alias(state->channel_type);
}
Expand Down Expand Up @@ -433,14 +464,26 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags)
* `open_channel`, and they are not equal types:
* - MUST reject the channel.
*/
if (accept_tlvs->channel_type
&& !featurebits_eq(accept_tlvs->channel_type,
state->channel_type->features)) {
negotiation_failed(state,
"Return unoffered channel_type: %s",
fmt_featurebits(tmpctx,
accept_tlvs->channel_type));
return NULL;
if (accept_tlvs->channel_type) {
/* Except that v23.05 could set OPT_SCID_ALIAS in reply! */
struct channel_type *atype;

atype = channel_type_from(tmpctx, accept_tlvs->channel_type);
if (!channel_type_has(atype, OPT_ANCHORS_ZERO_FEE_HTLC_TX))
featurebits_unset(&atype->features, OPT_SCID_ALIAS);

if (!channel_type_eq(atype, state->channel_type)) {
negotiation_failed(state,
"Return unoffered channel_type: %s",
fmt_featurebits(tmpctx,
accept_tlvs->channel_type));
return NULL;
}

/* If they "accepted" SCID_ALIAS, roll with it. */
tal_free(state->channel_type);
state->channel_type = channel_type_from(state,
accept_tlvs->channel_type);
}

/* BOLT #2:
Expand Down Expand Up @@ -547,6 +590,12 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags)
"Funding channel start: awaiting funding_txid with output to %s",
tal_hex(tmpctx, funding_output_script));

/* Backwards/cross compat hack */
if (intuit_scid_alias_type(state, channel_flags,
accept_tlvs->channel_type != NULL)) {
channel_type_set_scid_alias(state->channel_type);
}

return towire_openingd_funder_start_reply(state,
funding_output_script,
feature_negotiated(
Expand Down Expand Up @@ -860,6 +909,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
struct tlv_accept_channel_tlvs *accept_tlvs;
struct tlv_open_channel_tlvs *open_tlvs;
struct amount_sat *reserve;
bool open_channel_had_channel_type;

/* BOLT #2:
*
Expand Down Expand Up @@ -901,6 +951,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
* - if `type` includes `option_zeroconf` and it does not trust the sender to open an unconfirmed channel.
*/
if (open_tlvs->channel_type) {
open_channel_had_channel_type = true;
state->channel_type =
channel_type_accept(state,
open_tlvs->channel_type,
Expand All @@ -914,21 +965,13 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
open_tlvs->channel_type));
return NULL;
}

/* If we're not using scid_alias in channel type, intuit it here.
* We have to do this, because we used not to accept that bit, so older
* clients won't send it! */
if (!state->can_set_scid_alias_channel_type
&& !(channel_flags & CHANNEL_FLAGS_ANNOUNCE_CHANNEL)
&& feature_negotiated(state->our_features, state->their_features,
OPT_SCID_ALIAS)) {
channel_type_set_scid_alias(state->channel_type);
}
} else
} else {
open_channel_had_channel_type = false;
state->channel_type
= default_channel_type(state,
state->our_features,
state->their_features);
}

/* BOLT #2:
*
Expand Down Expand Up @@ -1143,6 +1186,12 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
&state->channel_id),
type_to_string(msg, struct channel_id, &id_in));

/* Backwards/cross compat hack */
if (intuit_scid_alias_type(state, channel_flags,
open_channel_had_channel_type)) {
channel_type_set_scid_alias(state->channel_type);
}

/*~ Channel is ready; Report the channel parameters to the signer. */
msg = towire_hsmd_ready_channel(NULL,
false, /* is_outbound */
Expand Down Expand Up @@ -1475,8 +1524,7 @@ int main(int argc, char *argv[])
&state->minimum_depth,
&state->min_feerate, &state->max_feerate,
&force_tmp_channel_id,
&state->allowdustreserve,
&state->can_set_scid_alias_channel_type))
&state->allowdustreserve))
master_badmsg(WIRE_OPENINGD_INIT, msg);

#if DEVELOPER
Expand Down
2 changes: 0 additions & 2 deletions openingd/openingd_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ msgdata,openingd_init,dev_temporary_channel_id,?byte,32
# reserves? This is explicitly required by the spec for safety
# reasons, but some implementations and users keep asking for it.
msgdata,openingd_init,allowdustreserve,bool,
# Core LN prior to 23.05 didn't like this bit set!
msgdata,openingd_init,can_set_scid_alias_channel_type,bool,

# Openingd->master: they offered channel, should we continue?
msgtype,openingd_got_offer,6005
Expand Down

0 comments on commit adeb7d8

Please sign in to comment.