diff --git a/channeld/channeld.c b/channeld/channeld.c index 9dc7ae3ac..63a9ae599 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -413,7 +413,7 @@ static void send_announcement_signatures(struct peer *peer) static u8 *create_channel_announcement(const tal_t *ctx, struct peer *peer) { int first, second; - u8 *cannounce, *features = tal_arr(ctx, u8, 0); + u8 *cannounce, *features = get_agreed_channelfeatures(tmpctx, peer->features); if (peer->channel_direction == 0) { first = LOCAL; @@ -435,7 +435,6 @@ static u8 *create_channel_announcement(const tal_t *ctx, struct peer *peer) &peer->node_ids[second], &peer->channel->funding_pubkey[first], &peer->channel->funding_pubkey[second]); - tal_free(features); return cannounce; } diff --git a/common/features.c b/common/features.c index fd0add267..9387e013b 100644 --- a/common/features.c +++ b/common/features.c @@ -28,6 +28,7 @@ enum feature_place { INIT_FEATURE, GLOBAL_INIT_FEATURE, NODE_ANNOUNCE_FEATURE, + CHANNEL_FEATURE, BOLT11_FEATURE, }; #define NUM_FEATURE_PLACE (BOLT11_FEATURE+1) @@ -140,6 +141,44 @@ u8 *get_offered_globalinitfeatures(const tal_t *ctx) return mkfeatures(ctx, GLOBAL_INIT_FEATURE); } +static void clear_feature_bit(u8 *features, u32 bit) +{ + size_t bytenum = bit / 8, bitnum = bit % 8, len = tal_count(features); + + if (bytenum >= len) + return; + + features[len - 1 - bytenum] &= ~(1 << bitnum); +} + +/* BOLT #7: + * + * - MUST set `features` based on what features were negotiated for this channel, according to [BOLT #9](09-features.md#assigned-features-flags) + * - MUST set `len` to the minimum length required to hold the `features` bits + * it sets. + */ +u8 *get_agreed_channelfeatures(const tal_t *ctx, const u8 *theirfeatures) +{ + u8 *f = mkfeatures(ctx, CHANNEL_FEATURE); + size_t max_len = 0; + + /* Clear any features which they didn't offer too */ + for (size_t i = 0; i < 8 * tal_count(f); i += 2) { + if (!feature_offered(f, i)) + continue; + if (!feature_offered(theirfeatures, i)) { + clear_feature_bit(f, COMPULSORY_FEATURE(i)); + clear_feature_bit(f, OPTIONAL_FEATURE(i)); + continue; + } + max_len = (i / 8) + 1; + } + + /* Trim to length */ + tal_resize(&f, max_len); + return f; +} + u8 *get_offered_bolt11features(const tal_t *ctx) { return mkfeatures(ctx, BOLT11_FEATURE); @@ -276,3 +315,4 @@ u8 *featurebits_or(const tal_t *ctx, const u8 *f1 TAKES, const u8 *f2 TAKES) return result; } + diff --git a/common/features.h b/common/features.h index 1ca900602..96b8a9e8e 100644 --- a/common/features.h +++ b/common/features.h @@ -14,6 +14,9 @@ u8 *get_offered_globalinitfeatures(const tal_t *ctx); u8 *get_offered_nodefeatures(const tal_t *ctx); u8 *get_offered_bolt11features(const tal_t *ctx); +/* For the features in channel_announcement */ +u8 *get_agreed_channelfeatures(const tal_t *ctx, const u8 *theirfeatures); + /* Is this feature bit requested? (Either compulsory or optional) */ bool feature_offered(const u8 *features, size_t f);