diff --git a/channeld/channeld.c b/channeld/channeld.c index 025395067..93c1477ce 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -2506,6 +2506,25 @@ static void peer_reconnect(struct peer *peer, * `commitment_signed` it expects to send. */ send_tlvs->next_to_send = tal_dup(send_tlvs, u64, &peer->next_index[REMOTE]); + + /* BOLT-upgrade_protocol #2: + * - if it initiated the channel: + * - MUST set `desired_type` to the channel_type it wants for the + * channel. + */ + if (peer->channel->opener == LOCAL) + send_tlvs->desired_type = channel_type(send_tlvs, peer->channel); + else { + /* BOLT-upgrade_protocol #2: + * - otherwise: + * - MUST set `current_type` to the current channel_type of the + * channel. + * - MUST set `upgradable` to the channel types it could change + * to. + * - MAY not set `upgradable` if it would be empty. + */ + send_tlvs->current_type = channel_type(send_tlvs, peer->channel); + } #endif /* BOLT #2: diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index acee63ef0..89eb791e7 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -29,6 +29,9 @@ void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memt /* Generated stub for memleak_remove_htable */ void memleak_remove_htable(struct htable *memtable UNNEEDED, const struct htable *ht UNNEEDED) { fprintf(stderr, "memleak_remove_htable called!\n"); abort(); } +/* Generated stub for set_feature_bit */ +void set_feature_bit(u8 **ptr UNNEEDED, u32 bit UNNEEDED) +{ fprintf(stderr, "set_feature_bit called!\n"); abort(); } /* Generated stub for status_failed */ void status_failed(enum status_failreason code UNNEEDED, const char *fmt UNNEEDED, ...) diff --git a/common/initial_channel.c b/common/initial_channel.c index fef91fb3c..9ca0da0df 100644 --- a/common/initial_channel.c +++ b/common/initial_channel.c @@ -6,12 +6,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include struct channel *new_initial_channel(const tal_t *ctx, const struct channel_id *cid, @@ -136,6 +138,56 @@ u32 channel_feerate(const struct channel *channel, enum side side) return get_feerate(channel->fee_states, channel->opener, side); } +#if EXPERIMENTAL_FEATURES +/* BOLT-upgrade_protocol #2: + * Channel features are explicitly enumerated as `channel_type` bitfields, + * using odd features bits. The currently defined types are: + * - no features (no bits set) + * - `option_static_remotekey` (bit 13) + * - `option_anchor_outputs` and `option_static_remotekey` (bits 21 and 13) + * - `option_anchors_zero_fee_htlc_tx` and `option_static_remotekey` (bits 23 + * and 13) + */ +static struct channel_type *new_channel_type(const tal_t *ctx) +{ + struct channel_type *type = tal(ctx, struct channel_type); + + type->features = tal_arr(type, u8, 0); + return type; +} + +static struct channel_type *type_static_remotekey(const tal_t *ctx) +{ + struct channel_type *type = new_channel_type(ctx); + + set_feature_bit(&type->features, + OPTIONAL_FEATURE(OPT_STATIC_REMOTEKEY)); + return type; +} + +static struct channel_type *type_anchor_outputs(const tal_t *ctx) +{ + struct channel_type *type = new_channel_type(ctx); + + set_feature_bit(&type->features, + OPTIONAL_FEATURE(OPT_ANCHOR_OUTPUTS)); + set_feature_bit(&type->features, + OPTIONAL_FEATURE(OPT_STATIC_REMOTEKEY)); + return type; +} + +struct channel_type *channel_type(const tal_t *ctx, + const struct channel *channel) +{ + if (channel->option_anchor_outputs) + return type_anchor_outputs(ctx); + if (channel->option_static_remotekey) + return type_static_remotekey(ctx); + + return new_channel_type(ctx); +} +#endif /* EXPERIMENTAL_FEATURES */ + static char *fmt_channel_view(const tal_t *ctx, const struct channel_view *view) { return tal_fmt(ctx, "{ owed_local=%s," diff --git a/common/initial_channel.h b/common/initial_channel.h index a70649afe..788c33f71 100644 --- a/common/initial_channel.h +++ b/common/initial_channel.h @@ -140,4 +140,13 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx, */ u32 channel_feerate(const struct channel *channel, enum side side); +#if EXPERIMENTAL_FEATURES +/* BOLT-upgrade_protocol #2: + * Channel features are explicitly enumerated as `channel_type` bitfields, + * using odd features bits. + */ +struct channel_type *channel_type(const tal_t *ctx, + const struct channel *channel); +#endif /* EXPERIMENTAL_FEATURES */ + #endif /* LIGHTNING_COMMON_INITIAL_CHANNEL_H */