From cf43e4437893a36bb9920e12a81a08741edcc20a Mon Sep 17 00:00:00 2001
From: Rusty Russell <rusty@rustcorp.com.au>
Date: Thu, 2 Apr 2020 14:34:47 +1030
Subject: [PATCH] common/features: don't use internal global.

Turns out that unnecessary: all callers can access the feature_set,
so make it much more like a normal primitive.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 channeld/channeld.c                         |  13 +-
 common/bolt11.c                             |  17 +--
 common/bolt11.h                             |   7 +-
 common/features.c                           | 134 +++++++-------------
 common/features.h                           |  37 +++---
 common/test/run-bolt11.c                    |  37 ++++--
 common/test/run-features.c                  |  91 +++++++++----
 connectd/connectd.c                         |  18 +--
 connectd/peer_exchange_initmsg.c            |   5 +-
 connectd/peer_exchange_initmsg.h            |   1 +
 connectd/test/run-initiator-success.c       |   3 -
 devtools/bolt11-cli.c                       |   2 +-
 gossipd/gossip_generation.c                 |   3 +-
 gossipd/gossipd.c                           |   4 +-
 gossipd/gossipd.h                           |   3 +
 gossipd/test/run-extended-info.c            |   3 -
 gossipd/test/run-next_block_range.c         |   3 -
 lightningd/invoice.c                        |   6 +-
 lightningd/lightningd.c                     |  36 ++++++
 lightningd/lightningd.h                     |   2 +-
 lightningd/opening_control.c                |   6 +-
 lightningd/options.c                        |  25 +---
 lightningd/pay.c                            |   2 +-
 lightningd/plugin.c                         |   2 +-
 lightningd/test/run-find_my_abspath.c       |   7 +
 lightningd/test/run-invoice-select-inchan.c |   4 +-
 openingd/openingd.c                         |  12 +-
 plugins/pay.c                               |   3 +-
 28 files changed, 253 insertions(+), 233 deletions(-)

diff --git a/channeld/channeld.c b/channeld/channeld.c
index a6643e9c2706..dc04e03f9956 100644
--- a/channeld/channeld.c
+++ b/channeld/channeld.c
@@ -76,6 +76,9 @@ struct peer {
 	/* Features peer supports. */
 	u8 *features;
 
+	/* Features we support. */
+	struct feature_set *fset;
+
 	/* Tolerable amounts for feerate (only relevant for fundee). */
 	u32 feerate_min, feerate_max;
 
@@ -415,7 +418,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 = get_agreed_channelfeatures(tmpctx, peer->features);
+	u8 *cannounce, *features = get_agreed_channelfeatures(tmpctx, peer->fset, peer->features);
 
 	if (peer->channel_direction == 0) {
 		first = LOCAL;
@@ -2325,7 +2328,7 @@ static void peer_reconnect(struct peer *peer,
 	bool dataloss_protect, check_extra_fields;
 	const u8 **premature_msgs = tal_arr(peer, const u8 *, 0);
 
-	dataloss_protect = feature_negotiated(peer->features,
+	dataloss_protect = feature_negotiated(peer->fset, peer->features,
 					      OPT_DATA_LOSS_PROTECT);
 
 	/* Both these options give us extra fields to check. */
@@ -3045,7 +3048,6 @@ static void init_channel(struct peer *peer)
 	secp256k1_ecdsa_signature *remote_ann_node_sig;
 	secp256k1_ecdsa_signature *remote_ann_bitcoin_sig;
 	bool option_static_remotekey;
-	struct feature_set *feature_set;
 #if !DEVELOPER
 	bool dev_fail_process_onionpacket; /* Ignored */
 #endif
@@ -3057,7 +3059,7 @@ static void init_channel(struct peer *peer)
 	msg = wire_sync_read(tmpctx, MASTER_FD);
 	if (!fromwire_channel_init(peer, msg,
 				   &chainparams,
-				   &feature_set,
+				   &peer->fset,
 				   &funding_txid, &funding_txout,
 				   &funding,
 				   &minimum_depth,
@@ -3113,9 +3115,6 @@ static void init_channel(struct peer *peer)
 		master_badmsg(WIRE_CHANNEL_INIT, msg);
 	}
 
-	/* Now we know what features to advertize. */
-	features_init(take(feature_set));
-
 	/* stdin == requests, 3 == peer, 4 = gossip, 5 = gossip_store, 6 = HSM */
 	per_peer_state_set_fds(peer->pps, 3, 4, 5);
 
diff --git a/common/bolt11.c b/common/bolt11.c
index c1020c6cf513..08173ef72bd2 100644
--- a/common/bolt11.c
+++ b/common/bolt11.c
@@ -489,6 +489,7 @@ static void shift_bitmap_down(u8 *bitmap, size_t bits)
  *  See [Feature Bits](#feature-bits).
  */
 static char *decode_9(struct bolt11 *b11,
+		      const struct feature_set *fset,
 		      struct hash_u5 *hu5,
 		      u5 **data, size_t *data_len,
 		      size_t data_length)
@@ -511,13 +512,12 @@ static char *decode_9(struct bolt11 *b11,
 	 * - if the `9` field contains unknown _even_ bits that are non-zero:
 	 *   - MUST fail the payment.
 	 */
-	/* BOLT #11:
-	 * The field is big-endian.  The least-significant bit is numbered 0,
-	 * which is _even_, and the next most significant bit is numbered 1,
-	 * which is _odd_. */
-	badf = features_unsupported(b11->features);
-	if (badf != -1)
-		return tal_fmt(b11, "9: unknown feature bit %i", badf);
+	/* We skip this check for the cli tool, which sets fset to NULL */
+	if (fset) {
+		badf = features_unsupported(fset, b11->features, BOLT11_FEATURE);
+		if (badf != -1)
+			return tal_fmt(b11, "9: unknown feature bit %i", badf);
+	}
 
 	return NULL;
 }
@@ -545,6 +545,7 @@ struct bolt11 *new_bolt11(const tal_t *ctx,
 
 /* Decodes and checks signature; returns NULL on error. */
 struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
+			     const struct feature_set *fset,
 			     const char *description, char **fail)
 {
 	char *hrp, *amountstr, *prefix;
@@ -739,7 +740,7 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
 					   data_length);
 			break;
 		case '9':
-			problem = decode_9(b11, &hu5, &data, &data_len,
+			problem = decode_9(b11, fset, &hu5, &data, &data_len,
 					   data_length);
 			break;
 		case 's':
diff --git a/common/bolt11.h b/common/bolt11.h
index 2b337ff28c83..dae6da562039 100644
--- a/common/bolt11.h
+++ b/common/bolt11.h
@@ -14,6 +14,8 @@
 /* We only have 10 bits for the field length, meaning < 640 bytes */
 #define BOLT11_FIELD_BYTE_LIMIT ((1 << 10) * 5 / 8)
 
+struct feature_set;
+
 struct bolt11_field {
 	struct list_node list;
 
@@ -74,8 +76,11 @@ struct bolt11 {
 };
 
 /* Decodes and checks signature; returns NULL on error; description is
- * (optional) out-of-band description of payment, for `h` field. */
+ * (optional) out-of-band description of payment, for `h` field.
+ * fset is NULL to accept any features (usually not desirable!).
+ */
 struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
+			     const struct feature_set *fset,
 			     const char *description, char **fail);
 
 /* Initialize an empty bolt11 struct with optional amount */
diff --git a/common/features.c b/common/features.c
index 3f0a792b88f2..8a24fb6d4277 100644
--- a/common/features.c
+++ b/common/features.c
@@ -5,10 +5,6 @@
 #include <common/utils.h>
 #include <wire/peer_wire.h>
 
-/* We keep a map of our features for each context, with the assumption that
- * the init features is a superset of the others. */
-static struct feature_set *our_features;
-
 enum feature_copy_style {
 	/* Feature is not exposed (importantly, being 0, this is the default!). */
 	FEATURE_DONT_REPRESENT,
@@ -67,84 +63,53 @@ static enum feature_copy_style feature_copy_style(u32 f, enum feature_place p)
 	abort();
 }
 
-static u8 *mkfeatures(const tal_t *ctx, enum feature_place place)
+struct feature_set *feature_set_for_feature(const tal_t *ctx, int feature)
 {
-	u8 *f = tal_arr(ctx, u8, 0);
-	const u8 *base = our_features->bits[INIT_FEATURE];
-
-	assert(place != INIT_FEATURE);
-	for (size_t i = 0; i < tal_bytelen(base)*8; i++) {
-		if (!feature_is_set(base, i))
-			continue;
+	struct feature_set *fs = tal(ctx, struct feature_set);
 
-		switch (feature_copy_style(i, place)) {
+	for (size_t i = 0; i < ARRAY_SIZE(fs->bits); i++) {
+		fs->bits[i] = tal_arr(fs, u8, 0);
+		switch (feature_copy_style(feature, i)) {
 		case FEATURE_DONT_REPRESENT:
 			continue;
 		case FEATURE_REPRESENT:
-			set_feature_bit(&f, i);
+			set_feature_bit(&fs->bits[i], feature);
 			continue;
 		case FEATURE_REPRESENT_AS_OPTIONAL:
-			set_feature_bit(&f, OPTIONAL_FEATURE(i));
+			set_feature_bit(&fs->bits[i], OPTIONAL_FEATURE(feature));
 			continue;
 		}
 		abort();
 	}
-	return f;
-}
-
-struct feature_set *features_core_init(const u8 *feature_bits)
-{
-	assert(!our_features);
-	our_features = notleak(tal(NULL, struct feature_set));
-
-	our_features->bits[INIT_FEATURE]
-		= tal_dup_talarr(our_features, u8, feature_bits);
-
-	/* Make other masks too */
-	for (enum feature_place f = INIT_FEATURE+1; f < NUM_FEATURE_PLACE; f++)
-		our_features->bits[f] = mkfeatures(our_features, f);
-
-	return our_features;
-}
-
-void features_init(struct feature_set *fset TAKES)
-{
-	assert(!our_features);
-
-	if (taken(fset))
-		our_features = notleak(tal_steal(NULL, fset));
-	else {
-		our_features = notleak(tal(NULL, struct feature_set));
-		for (size_t i = 0; i < ARRAY_SIZE(fset->bits); i++)
-			our_features->bits[i] = tal_dup_talarr(our_features, u8,
-							       fset->bits[i]);
-	}
-}
-
-void features_cleanup(void)
-{
-	our_features = tal_free(our_features);
+	return fs;
 }
 
-bool features_additional(const struct feature_set *newfset)
+bool feature_set_or(struct feature_set *a,
+		    const struct feature_set *b TAKES)
 {
 	/* Check first, before we change anything! */
-	for (size_t i = 0; i < ARRAY_SIZE(newfset->bits); i++) {
+	for (size_t i = 0; i < ARRAY_SIZE(b->bits); i++) {
 		/* FIXME: We could allow a plugin to upgrade an optional feature
 		 * to a compulsory one? */
-		for (size_t b = 0; b < tal_bytelen(newfset->bits[i])*8; b++) {
-			if (feature_is_set(newfset->bits[i], b)
-			    && feature_is_set(our_features->bits[i], b))
+		for (size_t j = 0; j < tal_bytelen(b->bits[i])*8; j++) {
+			if (feature_is_set(b->bits[i], j)
+			    && feature_offered(a->bits[i], j)) {
+				if (taken(b))
+					tal_free(b);
 				return false;
+			}
 		}
 	}
 
-	for (size_t i = 0; i < ARRAY_SIZE(newfset->bits); i++) {
-		for (size_t b = 0; b < tal_bytelen(newfset->bits[i])*8; b++) {
-			if (feature_is_set(newfset->bits[i], b))
-				set_feature_bit(&our_features->bits[i], b);
+	for (size_t i = 0; i < ARRAY_SIZE(a->bits); i++) {
+		for (size_t j = 0; j < tal_bytelen(b->bits[i])*8; j++) {
+			if (feature_is_set(b->bits[i], j))
+				set_feature_bit(&a->bits[i], j);
 		}
 	}
+
+	if (taken(b))
+		tal_free(b);
 	return true;
 }
 
@@ -172,21 +137,6 @@ static bool test_bit(const u8 *features, size_t byte, unsigned int bit)
 	return features[tal_count(features) - 1 - byte] & (1 << (bit % 8));
 }
 
-u8 *get_offered_nodefeatures(const tal_t *ctx)
-{
-	return tal_dup_talarr(ctx, u8, our_features->bits[NODE_ANNOUNCE_FEATURE]);
-}
-
-u8 *get_offered_initfeatures(const tal_t *ctx)
-{
-	return tal_dup_talarr(ctx, u8, our_features->bits[INIT_FEATURE]);
-}
-
-u8 *get_offered_globalinitfeatures(const tal_t *ctx)
-{
-	return tal_dup_talarr(ctx, u8, our_features->bits[GLOBAL_INIT_FEATURE]);
-}
-
 static void clear_feature_bit(u8 *features, u32 bit)
 {
 	size_t bytenum = bit / 8, bitnum = bit % 8, len = tal_count(features);
@@ -203,9 +153,11 @@ static void clear_feature_bit(u8 *features, u32 bit)
  *  - 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 *get_agreed_channelfeatures(const tal_t *ctx,
+			       const struct feature_set *ours,
+			       const u8 *theirfeatures)
 {
-	u8 *f = tal_dup_talarr(ctx, u8, our_features->bits[CHANNEL_FEATURE]);
+	u8 *f = tal_dup_talarr(ctx, u8, ours->bits[CHANNEL_FEATURE]);
 	size_t max_len = 0;
 
 	/* Clear any features which they didn't offer too */
@@ -225,11 +177,6 @@ u8 *get_agreed_channelfeatures(const tal_t *ctx, const u8 *theirfeatures)
 	return f;
 }
 
-u8 *get_offered_bolt11features(const tal_t *ctx)
-{
-	return tal_dup_talarr(ctx, u8, our_features->bits[BOLT11_FEATURE]);
-}
-
 bool feature_is_set(const u8 *features, size_t bit)
 {
 	size_t bytenum = bit / 8;
@@ -246,10 +193,11 @@ bool feature_offered(const u8 *features, size_t f)
 		|| feature_is_set(features, OPTIONAL_FEATURE(f));
 }
 
-bool feature_negotiated(const u8 *lfeatures, size_t f)
+bool feature_negotiated(const struct feature_set *ours,
+			const u8 *lfeatures, size_t f)
 {
 	return feature_offered(lfeatures, f)
-		&& feature_offered(our_features->bits[INIT_FEATURE], f);
+		&& feature_offered(ours->bits[INIT_FEATURE], f);
 }
 
 /**
@@ -263,7 +211,9 @@ bool feature_negotiated(const u8 *lfeatures, size_t f)
  *
  * Returns -1 on success, or first unsupported feature.
  */
-static int all_supported_features(const u8 *bitmap)
+static int all_supported_features(const struct feature_set *ours,
+				  const u8 *bitmap,
+				  enum feature_place p)
 {
 	size_t len = tal_count(bitmap) * 8;
 
@@ -272,7 +222,7 @@ static int all_supported_features(const u8 *bitmap)
 		if (!test_bit(bitmap, bitnum/8, bitnum%8))
 			continue;
 
-		if (feature_offered(our_features->bits[INIT_FEATURE], bitnum))
+		if (feature_offered(ours->bits[p], bitnum))
 			continue;
 
 		return bitnum;
@@ -280,15 +230,16 @@ static int all_supported_features(const u8 *bitmap)
 	return -1;
 }
 
-int features_unsupported(const u8 *features)
+int features_unsupported(const struct feature_set *ours, const u8 *theirs,
+			 enum feature_place p)
 {
 	/* BIT 2 would logically be "compulsory initial_routing_sync", but
 	 * that does not exist, so we special case it. */
-	if (feature_is_set(features,
+	if (feature_is_set(theirs,
 			   COMPULSORY_FEATURE(OPT_INITIAL_ROUTING_SYNC)))
 		return COMPULSORY_FEATURE(OPT_INITIAL_ROUTING_SYNC);
 
-	return all_supported_features(features);
+	return all_supported_features(ours, theirs, p);
 }
 
 static const char *feature_name(const tal_t *ctx, size_t f)
@@ -313,12 +264,13 @@ static const char *feature_name(const tal_t *ctx, size_t f)
 		       fnames[f / 2], (f & 1) ? "odd" : "even");
 }
 
-const char **list_supported_features(const tal_t *ctx)
+const char **list_supported_features(const tal_t *ctx,
+				     const struct feature_set *ours)
 {
 	const char **list = tal_arr(ctx, const char *, 0);
 
-	for (size_t i = 0; i < tal_bytelen(our_features->bits[INIT_FEATURE]) * 8; i++) {
-		if (test_bit(our_features->bits[INIT_FEATURE], i / 8, i % 8))
+	for (size_t i = 0; i < tal_bytelen(ours->bits[INIT_FEATURE]) * 8; i++) {
+		if (test_bit(ours->bits[INIT_FEATURE], i / 8, i % 8))
 			tal_arr_expand(&list, feature_name(list, i));
 	}
 
diff --git a/common/features.h b/common/features.h
index ba2c5165f725..cfdcdfb2c9cc 100644
--- a/common/features.h
+++ b/common/features.h
@@ -18,43 +18,38 @@ struct feature_set {
 	u8 *bits[NUM_FEATURE_PLACE];
 };
 
-/* Initialize core features (for lightningd). */
-struct feature_set *features_core_init(const u8 *features TAKES);
-
-/* Initialize subdaemon features. */
-void features_init(struct feature_set *fset TAKES);
-
-/* Free feature allocations */
-void features_cleanup(void);
+/* Create feature set for a known feature. */
+struct feature_set *feature_set_for_feature(const tal_t *ctx, int feature);
 
+/* Marshalling a feature set */
 struct feature_set *fromwire_feature_set(const tal_t *ctx,
 					 const u8 **ptr, size_t *max);
 void towire_feature_set(u8 **pptr, const struct feature_set *fset);
 
-/* Add features supplied by a plugin: returns false if we already have them */
-bool features_additional(const struct feature_set *feature_set);
+/* a |= b, or returns false if features already in a */
+bool feature_set_or(struct feature_set *a,
+		    const struct feature_set *b TAKES);
 
 /* Returns -1 if we're OK with all these offered features, otherwise first
  * unsupported (even) feature. */
-int features_unsupported(const u8 *features);
-
-/* For sending our features: tal_count() returns length. */
-u8 *get_offered_initfeatures(const tal_t *ctx);
-u8 *get_offered_globalinitfeatures(const tal_t *ctx);
-u8 *get_offered_nodefeatures(const tal_t *ctx);
-u8 *get_offered_bolt11features(const tal_t *ctx);
+int features_unsupported(const struct feature_set *ours, const u8 *theirs,
+			 enum feature_place p);
 
 /* For the features in channel_announcement */
-u8 *get_agreed_channelfeatures(const tal_t *ctx, const u8 *theirfeatures);
+u8 *get_agreed_channelfeatures(const tal_t *ctx,
+			       const struct feature_set *ours,
+			       const u8 *theirfeatures);
 
 /* Is this feature bit requested? (Either compulsory or optional) */
 bool feature_offered(const u8 *features, size_t f);
 
 /* Was this feature bit offered by them and us? */
-bool feature_negotiated(const u8 *lfeatures, size_t f);
+bool feature_negotiated(const struct feature_set *ours,
+			const u8 *features, size_t f);
 
-/* Return a list of what features we advertize. */
-const char **list_supported_features(const tal_t *ctx);
+/* Return a list of what (init) features we advertize. */
+const char **list_supported_features(const tal_t *ctx,
+				     const struct feature_set *ours);
 
 /* Low-level helpers to deal with big-endian bitfields. */
 bool feature_is_set(const u8 *features, size_t bit);
diff --git a/common/test/run-bolt11.c b/common/test/run-bolt11.c
index 69fd502b5e84..7ce3b17dff18 100644
--- a/common/test/run-bolt11.c
+++ b/common/test/run-bolt11.c
@@ -64,7 +64,7 @@ static void test_b11(const char *b11str,
 	char *reproduce;
 	struct bolt11_field *b11_extra, *expect_extra;
 
-	b11 = bolt11_decode(tmpctx, b11str, hashed_desc, &fail);
+	b11 = bolt11_decode(tmpctx, b11str, NULL, hashed_desc, &fail);
 	if (!b11)
 		errx(1, "%s:%u:%s", __FILE__, __LINE__, fail);
 
@@ -145,11 +145,11 @@ int main(void)
 	const char *badstr;
         struct bolt11_field *extra;
 	char *fail;
+	struct feature_set *fset;
 
 	wally_init(0);
 	secp256k1_ctx = wally_get_secp_context();
 	setup_tmpctx();
-	features_core_init(NULL);
 
 	/* BOLT #11:
 	 *
@@ -268,7 +268,7 @@ int main(void)
 
 	for (size_t i = 0; i <= strlen(badstr); i++) {
 		if (bolt11_decode(tmpctx, tal_strndup(tmpctx, badstr, i),
-				  NULL, &fail))
+				  NULL, NULL, &fail))
 			abort();
 		assert(strstr(fail, "Bad bech32")
 		       || strstr(fail, "Invoices must start with ln"));
@@ -461,9 +461,23 @@ int main(void)
 	set_feature_bit(&b11->features, 100);
 	badstr = bolt11_encode(tmpctx, b11, false, test_sign, NULL);
 	assert(streq(badstr, "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q4psqqqqqqqqqqqqqqqpqsqq40wa3khl49yue3zsgm26jrepqr2eghqlx86rttutve3ugd05em86nsefzh4pfurpd9ek9w2vp95zxqnfe2u7ckudyahsa52q66tgzcp6t2dyk"));
-	assert(!bolt11_decode(tmpctx, badstr, NULL, &fail));
+	/* Empty set of allowed bits, ensures this fails! */
+	fset = tal(tmpctx, struct feature_set);
+	fset->bits[BOLT11_FEATURE] = tal_arr(fset, u8, 0);
+	assert(!bolt11_decode(tmpctx, badstr, fset, NULL, &fail));
 	assert(streq(fail, "9: unknown feature bit 100"));
 
+	/* We'd actually allow this if we either (1) don't check, or (2) accept that feature in
+	 * either compulsory or optional forms. */
+	assert(bolt11_decode(tmpctx, badstr, NULL, NULL, &fail));
+
+	set_feature_bit(&fset->bits[BOLT11_FEATURE], 100);
+	assert(bolt11_decode(tmpctx, badstr, fset, NULL,&fail));
+
+	clear_feature_bit(fset->bits[BOLT11_FEATURE], 100);
+	set_feature_bit(&fset->bits[BOLT11_FEATURE], 101);
+	assert(bolt11_decode(tmpctx, badstr, fset, NULL, &fail));
+
 	/* BOLT-1fbccd30bb503203e4a255de67f9adb504563425 #11:
 	 *
 	 * > ### Please send 0.00967878534 BTC for a list of items within one week, amount in pico-BTC
@@ -527,53 +541,52 @@ int main(void)
 	 * > ### Bech32 checksum is invalid.
 	 * > lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrnt
 	 */
-	assert(!bolt11_decode(tmpctx, "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrnt", NULL, &fail));
+	assert(!bolt11_decode(tmpctx, "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrnt", NULL, NULL, &fail));
 	assert(streq(fail, "Bad bech32 string"));
 
 	/* BOLT-4e228a7fb4ea78af914d1ce82a63cbce8026279e #11:
 	 * > ### Malformed bech32 string (no 1)
 	 * > pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny
 	 */
-	assert(!bolt11_decode(tmpctx, "pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny", NULL, &fail));
+	assert(!bolt11_decode(tmpctx, "pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny", NULL, NULL, &fail));
 	assert(streq(fail, "Bad bech32 string"));
 
 	/* BOLT-4e228a7fb4ea78af914d1ce82a63cbce8026279e #11:
 	 * > ### Malformed bech32 string (mixed case)
 	 * > LNBC2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny
 	 */
-	assert(!bolt11_decode(tmpctx, "LNBC2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny", NULL, &fail));
+	assert(!bolt11_decode(tmpctx, "LNBC2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpquwpc4curk03c9wlrswe78q4eyqc7d8d0xqzpuyk0sg5g70me25alkluzd2x62aysf2pyy8edtjeevuv4p2d5p76r4zkmneet7uvyakky2zr4cusd45tftc9c5fh0nnqpnl2jfll544esqchsrny", NULL, NULL, &fail));
 	assert(streq(fail, "Bad bech32 string"));
 
 	/* BOLT-4e228a7fb4ea78af914d1ce82a63cbce8026279e #11:
 	 * > ### Signature is not recoverable.
 	 * > lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuaxtrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rspk28uwq
 	 */
-	assert(!bolt11_decode(tmpctx, "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuaxtrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rspk28uwq", NULL, &fail));
+	assert(!bolt11_decode(tmpctx, "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuaxtrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rspk28uwq", NULL, NULL, &fail));
 	assert(streq(fail, "signature recovery failed"));
 
 	/* BOLT-4e228a7fb4ea78af914d1ce82a63cbce8026279e #11:
 	 * > ### String is too short.
 	 * > lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6na6hlh
 	 */
-	assert(!bolt11_decode(tmpctx, "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6na6hlh", NULL, &fail));
+	assert(!bolt11_decode(tmpctx, "lnbc1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdpl2pkx2ctnv5sxxmmwwd5kgetjypeh2ursdae8g6na6hlh", NULL, NULL, &fail));
 
 	/* BOLT-4e228a7fb4ea78af914d1ce82a63cbce8026279e #11:
 	 * > ### Invalid multiplier
 	 * > lnbc2500x1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpujr6jxr9gq9pv6g46y7d20jfkegkg4gljz2ea2a3m9lmvvr95tq2s0kvu70u3axgelz3kyvtp2ywwt0y8hkx2869zq5dll9nelr83zzqqpgl2zg
 	 */
-	assert(!bolt11_decode(tmpctx, "lnbc2500x1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpujr6jxr9gq9pv6g46y7d20jfkegkg4gljz2ea2a3m9lmvvr95tq2s0kvu70u3axgelz3kyvtp2ywwt0y8hkx2869zq5dll9nelr83zzqqpgl2zg", NULL, &fail));
+	assert(!bolt11_decode(tmpctx, "lnbc2500x1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpujr6jxr9gq9pv6g46y7d20jfkegkg4gljz2ea2a3m9lmvvr95tq2s0kvu70u3axgelz3kyvtp2ywwt0y8hkx2869zq5dll9nelr83zzqqpgl2zg", NULL, NULL, &fail));
 	assert(streq(fail, "Invalid amount postfix 'x'"));
 
 	/* BOLT- #11:
 	 * > ### Invalid sub-millisatoshi precision.
 	 * > lnbc2500000001p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpu7hqtk93pkf7sw55rdv4k9z2vj050rxdr6za9ekfs3nlt5lr89jqpdmxsmlj9urqumg0h9wzpqecw7th56tdms40p2ny9q4ddvjsedzcplva53s
 	 */
-	assert(!bolt11_decode(tmpctx, "lnbc2500000001p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpu7hqtk93pkf7sw55rdv4k9z2vj050rxdr6za9ekfs3nlt5lr89jqpdmxsmlj9urqumg0h9wzpqecw7th56tdms40p2ny9q4ddvjsedzcplva53s", NULL, &fail));
+	assert(!bolt11_decode(tmpctx, "lnbc2500000001p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpu7hqtk93pkf7sw55rdv4k9z2vj050rxdr6za9ekfs3nlt5lr89jqpdmxsmlj9urqumg0h9wzpqecw7th56tdms40p2ny9q4ddvjsedzcplva53s", NULL, NULL, &fail));
 	assert(streq(fail, "Invalid sub-millisatoshi amount '2500000001p'"));
 
 	/* FIXME: Test the others! */
 	wally_cleanup(0);
 	tal_free(tmpctx);
-	features_cleanup();
 	return 0;
 }
diff --git a/common/test/run-features.c b/common/test/run-features.c
index f75f96804dc3..341b2f959f64 100644
--- a/common/test/run-features.c
+++ b/common/test/run-features.c
@@ -65,32 +65,70 @@ static void test_featurebits_or(void)
 	    memeq(result, tal_bytelen(result), control, tal_bytelen(control)));
 }
 
-static void setup_features(void)
+static bool feature_set_eq(const struct feature_set *f1,
+			   const struct feature_set *f2)
 {
-	static const u32 default_features[] = {
-		OPTIONAL_FEATURE(OPT_DATA_LOSS_PROTECT),
-		OPTIONAL_FEATURE(OPT_UPFRONT_SHUTDOWN_SCRIPT),
-		OPTIONAL_FEATURE(OPT_GOSSIP_QUERIES),
-		OPTIONAL_FEATURE(OPT_VAR_ONION),
-		OPTIONAL_FEATURE(OPT_PAYMENT_SECRET),
-		OPTIONAL_FEATURE(OPT_BASIC_MPP),
-		OPTIONAL_FEATURE(OPT_GOSSIP_QUERIES_EX),
-		OPTIONAL_FEATURE(OPT_STATIC_REMOTEKEY),
-	};
-	u8 *f = tal_arr(NULL, u8, 0);
-	for (size_t i = 0; i < ARRAY_SIZE(default_features); i++)
-		set_feature_bit(&f, default_features[i]);
-	features_core_init(take(f));
+	/* We assume minimal sizing */
+	for (size_t i = 0; i < ARRAY_SIZE(f1->bits); i++) {
+		if (!memeq(f1->bits[i], tal_bytelen(f1->bits[i]),
+			   f2->bits[i], tal_bytelen(f2->bits[i])))
+			return false;
+	}
+	return true;
+}
+
+static void test_feature_set_or(void)
+{
+	struct feature_set *f1, *f2, *control;
+
+	for (size_t i = 0; i < ARRAY_SIZE(f1->bits); i++) {
+		f1 = talz(tmpctx, struct feature_set);
+		f2 = talz(tmpctx, struct feature_set);
+		control = talz(tmpctx, struct feature_set);
+
+		f1->bits[i] = tal_arr(f1, u8, 0);
+		f2->bits[i] = tal_arr(f2, u8, 0);
+		control->bits[i] = tal_arr(control, u8, 0);
+
+		/* or with nothing is a nop */
+		set_feature_bit(&f1->bits[i], 0);
+		set_feature_bit(&control->bits[i], 0);
+		assert(feature_set_or(f1, f2));
+		assert(feature_set_eq(f1, control));
+
+		/* or compulsory with either compulsory or optional is a fail */
+		set_feature_bit(&f2->bits[i], 0);
+		assert(!feature_set_or(f1, f2));
+		assert(feature_set_eq(f1, control));
+		assert(!feature_set_or(f2, f1));
+
+		clear_feature_bit(f2->bits[i], 0);
+		set_feature_bit(&f2->bits[i], 1);
+		assert(!feature_set_or(f1, f2));
+		assert(feature_set_eq(f1, control));
+		assert(!feature_set_or(f2, f1));
+
+		clear_feature_bit(f2->bits[i], 1);
+		set_feature_bit(&f2->bits[i], 10);
+		set_feature_bit(&control->bits[i], 10);
+		assert(feature_set_or(f1, f2));
+		assert(feature_set_eq(f1, control));
+	}
 }
 
 int main(void)
 {
-	u8 *bits, *lf;
+	u8 *bits;
+	struct feature_set *fset;
+
 	setup_locale();
 	wally_init(0);
 	secp256k1_ctx = wally_get_secp_context();
 	setup_tmpctx();
-	setup_features();
+
+	/* Just some bits to set. */
+	fset = feature_set_for_feature(tmpctx,
+				       OPTIONAL_FEATURE(OPT_DATA_LOSS_PROTECT));
 
 	bits = tal_arr(tmpctx, u8, 0);
 	for (size_t i = 0; i < 100; i += 3)
@@ -136,38 +174,37 @@ int main(void)
 
 	/* We always support no features. */
 	memset(bits, 0, tal_count(bits));
-	assert(features_unsupported(bits) == -1);
+	assert(features_unsupported(fset, bits, INIT_FEATURE) == -1);
 
 	/* We must support our own features. */
-	lf = get_offered_initfeatures(tmpctx);
-	assert(features_unsupported(lf) == -1);
+	assert(features_unsupported(fset, fset->bits[INIT_FEATURE], INIT_FEATURE) == -1);
 
 	/* We can add random odd features, no problem. */
 	for (size_t i = 1; i < 16; i += 2) {
-		bits = tal_dup_talarr(tmpctx, u8, lf);
+		bits = tal_dup_talarr(tmpctx, u8, fset->bits[INIT_FEATURE]);
 		set_feature_bit(&bits, i);
-		assert(features_unsupported(bits) == -1);
+		assert(features_unsupported(fset, bits, INIT_FEATURE) == -1);
 	}
 
 	/* We can't add random even features. */
 	for (size_t i = 0; i < 16; i += 2) {
-		bits = tal_dup_talarr(tmpctx, u8, lf);
+		bits = tal_dup_talarr(tmpctx, u8, fset->bits[INIT_FEATURE]);
 		set_feature_bit(&bits, i);
 
 		/* Special case for missing compulsory feature */
 		if (i == 2) {
-			assert(features_unsupported(bits) == i);
+			assert(features_unsupported(fset, bits, INIT_FEATURE) == i);
 		} else {
-			assert((features_unsupported(bits) == -1)
-			       == feature_offered(our_features->bits[INIT_FEATURE], i));
+			assert((features_unsupported(fset, bits, INIT_FEATURE) == -1)
+			       == feature_offered(fset->bits[INIT_FEATURE], i));
 		}
 	}
 
 	test_featurebits_or();
+	test_feature_set_or();
 
 	wally_cleanup(0);
 	tal_free(tmpctx);
 	take_cleanup();
-	features_cleanup();
 	return 0;
 }
diff --git a/connectd/connectd.c b/connectd/connectd.c
index aec7bcb236f6..c6bb4eca6dac 100644
--- a/connectd/connectd.c
+++ b/connectd/connectd.c
@@ -154,6 +154,9 @@ struct daemon {
 
 	/* Allow to define the default behavior of tor services calls*/
 	bool use_v3_autotor;
+
+	/* Our features, as lightningd told us */
+	struct feature_set *fset;
 };
 
 /* Peers we're trying to reach: we iterate through addrs until we succeed
@@ -300,7 +303,7 @@ static bool get_gossipfds(struct daemon *daemon,
 	/*~ The way features generally work is that both sides need to offer it;
 	 * we always offer `gossip_queries`, but this check is explicit. */
 	gossip_queries_feature
-		= feature_negotiated(features, OPT_GOSSIP_QUERIES);
+		= feature_negotiated(daemon->fset, features, OPT_GOSSIP_QUERIES);
 
 	/*~ `initial_routing_sync` is supported by every node, since it was in
 	 * the initial lightning specification: it means the peer wants the
@@ -436,7 +439,7 @@ struct io_plan *peer_connected(struct io_conn *conn,
 	 *  - upon receiving unknown _even_ feature bits that are non-zero:
 	 *    - MUST fail the connection.
 	 */
-	unsup = features_unsupported(features);
+	unsup = features_unsupported(daemon->fset, features, INIT_FEATURE);
 	if (unsup != -1) {
 		msg = towire_errorfmt(NULL, NULL, "Unsupported feature %u",
 				      unsup);
@@ -490,7 +493,7 @@ static struct io_plan *handshake_in_success(struct io_conn *conn,
 	struct node_id id;
 	node_id_from_pubkey(&id, id_key);
 	status_peer_debug(&id, "Connect IN");
-	return peer_exchange_initmsg(conn, daemon, cs, &id, addr);
+	return peer_exchange_initmsg(conn, daemon, daemon->fset, cs, &id, addr);
 }
 
 /*~ When we get a connection in we set up its network address then call
@@ -550,7 +553,8 @@ static struct io_plan *handshake_out_success(struct io_conn *conn,
 	node_id_from_pubkey(&id, key);
 	connect->connstate = "Exchanging init messages";
 	status_peer_debug(&id, "Connect OUT");
-	return peer_exchange_initmsg(conn, connect->daemon, cs, &id, addr);
+	return peer_exchange_initmsg(conn, connect->daemon,
+				     connect->daemon->fset, cs, &id, addr);
 }
 
 struct io_plan *connection_out(struct io_conn *conn, struct connecting *connect)
@@ -1201,14 +1205,13 @@ static struct io_plan *connect_init(struct io_conn *conn,
 	struct wireaddr_internal *proposed_wireaddr;
 	enum addr_listen_announce *proposed_listen_announce;
 	struct wireaddr *announcable;
-	struct feature_set *feature_set;
 	char *tor_password;
 
 	/* Fields which require allocation are allocated off daemon */
 	if (!fromwire_connectctl_init(
 		daemon, msg,
 		&chainparams,
-		&feature_set,
+		&daemon->fset,
 		&daemon->id,
 		&proposed_wireaddr,
 		&proposed_listen_announce,
@@ -1221,9 +1224,6 @@ static struct io_plan *connect_init(struct io_conn *conn,
 		master_badmsg(WIRE_CONNECTCTL_INIT, msg);
 	}
 
-	/* Now we know what features to advertize. */
-	features_init(take(feature_set));
-
 	if (!pubkey_from_node_id(&daemon->mykey, &daemon->id))
 		status_failed(STATUS_FAIL_INTERNAL_ERROR,
 			      "Invalid id for me %s",
diff --git a/connectd/peer_exchange_initmsg.c b/connectd/peer_exchange_initmsg.c
index a9c425873077..a8c96f19d451 100644
--- a/connectd/peer_exchange_initmsg.c
+++ b/connectd/peer_exchange_initmsg.c
@@ -135,6 +135,7 @@ static struct io_plan *peer_write_postclose(struct io_conn *conn,
 
 struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
 				      struct daemon *daemon,
+				      const struct feature_set *fset,
 				      const struct crypto_state *cs,
 				      const struct node_id *id,
 				      const struct wireaddr_internal *addr)
@@ -181,8 +182,8 @@ struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
 	 * Finally, we agreed that bits below 13 could be put in both, but
 	 * from now on they'll all go in initfeatures. */
 	peer->msg = towire_init(NULL,
-				get_offered_globalinitfeatures(tmpctx),
-				get_offered_initfeatures(tmpctx),
+				fset->bits[GLOBAL_INIT_FEATURE],
+				fset->bits[INIT_FEATURE],
 				tlvs);
 	status_peer_io(LOG_IO_OUT, &peer->id, peer->msg);
 	peer->msg = cryptomsg_encrypt_msg(peer, &peer->cs, take(peer->msg));
diff --git a/connectd/peer_exchange_initmsg.h b/connectd/peer_exchange_initmsg.h
index 29edbf03eb40..ee7c5ae09906 100644
--- a/connectd/peer_exchange_initmsg.h
+++ b/connectd/peer_exchange_initmsg.h
@@ -12,6 +12,7 @@ struct wireaddr_internal;
 /* If successful, calls peer_connected() */
 struct io_plan *peer_exchange_initmsg(struct io_conn *conn,
 				      struct daemon *daemon,
+				      const struct feature_set *fset,
 				      const struct crypto_state *cs,
 				      const struct node_id *id,
 				      const struct wireaddr_internal *addr);
diff --git a/connectd/test/run-initiator-success.c b/connectd/test/run-initiator-success.c
index a7fa6fa0af57..07c081b80509 100644
--- a/connectd/test/run-initiator-success.c
+++ b/connectd/test/run-initiator-success.c
@@ -40,9 +40,6 @@ u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED,
 /* Generated stub for fromwire_u16 */
 u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
 { fprintf(stderr, "fromwire_u16 called!\n"); abort(); }
-/* Generated stub for notleak_ */
-void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED)
-{ fprintf(stderr, "notleak_ called!\n"); abort(); }
 /* Generated stub for towire_u16 */
 void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED)
 { fprintf(stderr, "towire_u16 called!\n"); abort(); }
diff --git a/devtools/bolt11-cli.c b/devtools/bolt11-cli.c
index 0d64dc0c1e42..ce72a8d69756 100644
--- a/devtools/bolt11-cli.c
+++ b/devtools/bolt11-cli.c
@@ -93,7 +93,7 @@ int main(int argc, char *argv[])
 		errx(ERROR_USAGE, "Need argument\n%s",
 		     opt_usage(argv[0], NULL));
 
-	b11 = bolt11_decode(ctx, argv[2], description, &fail);
+	b11 = bolt11_decode(ctx, argv[2], NULL, description, &fail);
 	if (!b11)
 		errx(ERROR_BAD_DECODE, "%s", fail);
 
diff --git a/gossipd/gossip_generation.c b/gossipd/gossip_generation.c
index 2734541b3532..3fab950e2e8a 100644
--- a/gossipd/gossip_generation.c
+++ b/gossipd/gossip_generation.c
@@ -38,7 +38,8 @@ static u8 *create_node_announcement(const tal_t *ctx, struct daemon *daemon,
 		towire_wireaddr(&addresses, &daemon->announcable[i]);
 
 	announcement =
-	    towire_node_announcement(ctx, sig, get_offered_nodefeatures(tmpctx),
+	    towire_node_announcement(ctx, sig,
+				     daemon->fset->bits[NODE_ANNOUNCE_FEATURE],
 				     timestamp,
 				     &daemon->id, daemon->rgb, daemon->alias,
 				     addresses);
diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c
index 73d55187de21..46a10f584337 100644
--- a/gossipd/gossipd.c
+++ b/gossipd/gossipd.c
@@ -831,11 +831,10 @@ static struct io_plan *gossip_init(struct io_conn *conn,
 	u32 *dev_gossip_time;
 	bool dev_fast_gossip, dev_fast_gossip_prune;
 	u32 timestamp;
-	struct feature_set *feature_set;
 
 	if (!fromwire_gossipctl_init(daemon, msg,
 				     &chainparams,
-				     &feature_set,
+				     &daemon->fset,
 				     &daemon->id,
 				     daemon->rgb,
 				     daemon->alias,
@@ -846,7 +845,6 @@ static struct io_plan *gossip_init(struct io_conn *conn,
 		master_badmsg(WIRE_GOSSIPCTL_INIT, msg);
 	}
 
-	features_init(take(feature_set));
 	daemon->rstate = new_routing_state(daemon,
 					   &daemon->id,
 					   &daemon->peers,
diff --git a/gossipd/gossipd.h b/gossipd/gossipd.h
index ea262eae7a79..14ae9f736302 100644
--- a/gossipd/gossipd.h
+++ b/gossipd/gossipd.h
@@ -57,6 +57,9 @@ struct daemon {
 
 	/* What, if any, gossip we're seeker from peers. */
 	struct seeker *seeker;
+
+	/* Features lightningd told us to set. */
+	struct feature_set *fset;
 };
 
 /* This represents each peer we're gossiping with */
diff --git a/gossipd/test/run-extended-info.c b/gossipd/test/run-extended-info.c
index 6b42ed098e63..9d9e0cd41fee 100644
--- a/gossipd/test/run-extended-info.c
+++ b/gossipd/test/run-extended-info.c
@@ -78,9 +78,6 @@ void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UN
 /* Generated stub for master_badmsg */
 void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg)
 { fprintf(stderr, "master_badmsg called!\n"); abort(); }
-/* Generated stub for notleak_ */
-void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED)
-{ fprintf(stderr, "notleak_ called!\n"); abort(); }
 /* Generated stub for peer_supplied_good_gossip */
 void peer_supplied_good_gossip(struct peer *peer UNNEEDED, size_t amount UNNEEDED)
 { fprintf(stderr, "peer_supplied_good_gossip called!\n"); abort(); }
diff --git a/gossipd/test/run-next_block_range.c b/gossipd/test/run-next_block_range.c
index b8bec9120e2d..0395c292cdfb 100644
--- a/gossipd/test/run-next_block_range.c
+++ b/gossipd/test/run-next_block_range.c
@@ -38,9 +38,6 @@ struct oneshot *new_reltimer_(struct timers *timers UNNEEDED,
 			      struct timerel expire UNNEEDED,
 			      void (*cb)(void *) UNNEEDED, void *arg UNNEEDED)
 { fprintf(stderr, "new_reltimer_ called!\n"); abort(); }
-/* Generated stub for notleak_ */
-void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED)
-{ fprintf(stderr, "notleak_ called!\n"); abort(); }
 /* Generated stub for query_channel_range */
 bool query_channel_range(struct daemon *daemon UNNEEDED,
 			 struct peer *peer UNNEEDED,
diff --git a/lightningd/invoice.c b/lightningd/invoice.c
index 69db2ffd97ea..2edeb92d1df3 100644
--- a/lightningd/invoice.c
+++ b/lightningd/invoice.c
@@ -1013,7 +1013,9 @@ static struct command_result *json_invoice(struct command *cmd,
 	info->b11->description_hash = NULL;
 	info->b11->payment_secret = tal_dup(info->b11, struct secret,
 					    &payment_secret);
-	info->b11->features = get_offered_bolt11features(info->b11);
+	info->b11->features = tal_dup_talarr(info->b11, u8,
+					     cmd->ld->feature_set
+					     ->bits[BOLT11_FEATURE]);
 
 #if DEVELOPER
 	info->b11->routes = unpack_routes(info->b11, buffer, routes);
@@ -1319,7 +1321,7 @@ static struct command_result *json_decodepay(struct command *cmd,
 		   NULL))
 		return command_param_failed();
 
-	b11 = bolt11_decode(cmd, str, desc, &fail);
+	b11 = bolt11_decode(cmd, str, cmd->ld->feature_set, desc, &fail);
 
 	if (!b11) {
 		return command_fail(cmd, LIGHTNINGD, "Invalid bolt11: %s", fail);
diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c
index 051cf630523e..649fd5099ea9 100644
--- a/lightningd/lightningd.c
+++ b/lightningd/lightningd.c
@@ -703,6 +703,39 @@ static void setup_sig_handlers(void)
 	}
 }
 
+/*~ We actually keep more than one set of features, used in different
+ * contexts.  common/features.c knows how each standard feature is
+ * presented, so we have it generate the set for each one at a time, and
+ * combine them.
+ *
+ * This is inefficient, but the primitives are useful for adding single
+ * features later, or adding them when supplied by plugins. */
+static struct feature_set *default_features(const tal_t *ctx)
+{
+	struct feature_set *ret = NULL;
+	static const u32 features[] = {
+		OPTIONAL_FEATURE(OPT_DATA_LOSS_PROTECT),
+		OPTIONAL_FEATURE(OPT_UPFRONT_SHUTDOWN_SCRIPT),
+		OPTIONAL_FEATURE(OPT_GOSSIP_QUERIES),
+		OPTIONAL_FEATURE(OPT_VAR_ONION),
+		OPTIONAL_FEATURE(OPT_PAYMENT_SECRET),
+		OPTIONAL_FEATURE(OPT_BASIC_MPP),
+		OPTIONAL_FEATURE(OPT_GOSSIP_QUERIES_EX),
+		OPTIONAL_FEATURE(OPT_STATIC_REMOTEKEY),
+	};
+
+	for (size_t i = 0; i < ARRAY_SIZE(features); i++) {
+		struct feature_set *f
+			= feature_set_for_feature(NULL, features[i]);
+		if (!ret)
+			ret = tal_steal(ctx, f);
+		else
+			feature_set_or(ret, take(f));
+	}
+
+	return ret;
+}
+
 int main(int argc, char *argv[])
 {
 	struct lightningd *ld;
@@ -751,6 +784,9 @@ int main(int argc, char *argv[])
 	if (!ld->daemon_dir)
 		errx(1, "Could not find daemons");
 
+	/* Set up the feature bits for what we support */
+	ld->feature_set = default_features(ld);
+
 	/*~ Handle early options; this moves us into --lightning-dir.
 	 * Plugins may add new options, which is why we are splitting
 	 * between early args (including --plugin registration) and
diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h
index ab280eff4271..75f6c145d642 100644
--- a/lightningd/lightningd.h
+++ b/lightningd/lightningd.h
@@ -120,7 +120,7 @@ struct lightningd {
 	struct node_id id;
 
 	/* Feature set we offer. */
-	const struct feature_set *feature_set;
+	struct feature_set *feature_set;
 
 	/* My name is... my favorite color is... */
 	u8 *alias; /* At least 32 bytes (zero-filled) */
diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c
index c020fb423834..f25e86f3d53e 100644
--- a/lightningd/opening_control.c
+++ b/lightningd/opening_control.c
@@ -220,7 +220,8 @@ wallet_commit_channel(struct lightningd *ld,
 	 */
 	/* i.e. We set it now for the channel permanently. */
 	option_static_remotekey
-		= feature_negotiated(uc->peer->features, OPT_STATIC_REMOTEKEY);
+		= feature_negotiated(ld->feature_set,
+				     uc->peer->features, OPT_STATIC_REMOTEKEY);
 
 	channel = new_channel(uc->peer, uc->dbid,
 			      NULL, /* No shachain yet */
@@ -1009,7 +1010,8 @@ void peer_start_openingd(struct peer *peer,
 				  feerate_min(peer->ld, NULL),
 				  feerate_max(peer->ld, NULL),
 				  peer->features,
-				  feature_negotiated(peer->features,
+				  feature_negotiated(peer->ld->feature_set,
+						     peer->features,
 						     OPT_STATIC_REMOTEKEY),
 				  send_msg,
 				  IFDEV(peer->ld->dev_force_tmp_channel_id, NULL),
diff --git a/lightningd/options.c b/lightningd/options.c
index 5be2fed728a8..0f65e96f7ba4 100644
--- a/lightningd/options.c
+++ b/lightningd/options.c
@@ -692,7 +692,7 @@ static char *test_subdaemons_and_exit(struct lightningd *ld)
 
 static char *list_features_and_exit(struct lightningd *ld)
 {
-	const char **features = list_supported_features(ld);
+	const char **features = list_supported_features(tmpctx, ld->feature_set);
 	for (size_t i = 0; i < tal_count(features); i++)
 		printf("%s\n", features[i]);
 	exit(0);
@@ -1004,34 +1004,11 @@ void setup_color_and_alias(struct lightningd *ld)
 	}
 }
 
-static struct feature_set *setup_default_features(void)
-{
-	static const u32 default_features[] = {
-		OPTIONAL_FEATURE(OPT_DATA_LOSS_PROTECT),
-		OPTIONAL_FEATURE(OPT_UPFRONT_SHUTDOWN_SCRIPT),
-		OPTIONAL_FEATURE(OPT_GOSSIP_QUERIES),
-		OPTIONAL_FEATURE(OPT_VAR_ONION),
-		OPTIONAL_FEATURE(OPT_PAYMENT_SECRET),
-		OPTIONAL_FEATURE(OPT_BASIC_MPP),
-		OPTIONAL_FEATURE(OPT_GOSSIP_QUERIES_EX),
-		OPTIONAL_FEATURE(OPT_STATIC_REMOTEKEY),
-	};
-	u8 *f = tal_arr(NULL, u8, 0);
-
-	for (size_t i = 0; i < ARRAY_SIZE(default_features); i++)
-		set_feature_bit(&f, default_features[i]);
-
-	return features_core_init(take(f));
-}
-
 void handle_early_opts(struct lightningd *ld, int argc, char *argv[])
 {
 	/* Make ccan/opt use tal for allocations */
 	setup_option_allocators();
 
-	/* Make sure options are populated. */
-	ld->feature_set = setup_default_features();
-
 	/*~ List features immediately, before doing anything interesting */
 	opt_register_early_noarg("--list-features-only",
 				 list_features_and_exit,
diff --git a/lightningd/pay.c b/lightningd/pay.c
index cce8c641f68d..ff926c2813f4 100644
--- a/lightningd/pay.c
+++ b/lightningd/pay.c
@@ -1406,7 +1406,7 @@ static struct command_result *json_listsendpays(struct command *cmd,
 		struct bolt11 *b11;
 		char *fail;
 
-		b11 = bolt11_decode(cmd, b11str, NULL, &fail);
+		b11 = bolt11_decode(cmd, b11str, cmd->ld->feature_set, NULL, &fail);
 		if (!b11) {
 			return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
 					    "Invalid bolt11: %s", fail);
diff --git a/lightningd/plugin.c b/lightningd/plugin.c
index 73d66b93808f..f00b66e9b18a 100644
--- a/lightningd/plugin.c
+++ b/lightningd/plugin.c
@@ -916,7 +916,7 @@ bool plugin_parse_getmanifest_response(const char *buffer,
 			return true;
 		}
 
-		if (!features_additional(fset)) {
+		if (!feature_set_or(plugin->plugins->ld->feature_set, fset)) {
 			plugin_kill(plugin,
 				    "Custom featurebits already present");
 			return true;
diff --git a/lightningd/test/run-find_my_abspath.c b/lightningd/test/run-find_my_abspath.c
index 4425befbc56b..c68a73c67290 100644
--- a/lightningd/test/run-find_my_abspath.c
+++ b/lightningd/test/run-find_my_abspath.c
@@ -60,6 +60,13 @@ bool db_in_transaction(struct db *db UNNEEDED)
 /* Generated stub for fatal */
 void   fatal(const char *fmt UNNEEDED, ...)
 { fprintf(stderr, "fatal called!\n"); abort(); }
+/* Generated stub for feature_set_for_feature */
+struct feature_set *feature_set_for_feature(const tal_t *ctx UNNEEDED, int feature UNNEEDED)
+{ fprintf(stderr, "feature_set_for_feature called!\n"); abort(); }
+/* Generated stub for feature_set_or */
+bool feature_set_or(struct feature_set *a UNNEEDED,
+		    const struct feature_set *b TAKES UNNEEDED)
+{ fprintf(stderr, "feature_set_or called!\n"); abort(); }
 /* Generated stub for free_htlcs */
 void free_htlcs(struct lightningd *ld UNNEEDED, const struct channel *channel UNNEEDED)
 { fprintf(stderr, "free_htlcs called!\n"); abort(); }
diff --git a/lightningd/test/run-invoice-select-inchan.c b/lightningd/test/run-invoice-select-inchan.c
index c8635c20930d..daf9e0c81b98 100644
--- a/lightningd/test/run-invoice-select-inchan.c
+++ b/lightningd/test/run-invoice-select-inchan.c
@@ -23,6 +23,7 @@ void bitcoind_getutxout_(struct bitcoind *bitcoind UNNEEDED,
 { fprintf(stderr, "bitcoind_getutxout_ called!\n"); abort(); }
 /* Generated stub for bolt11_decode */
 struct bolt11 *bolt11_decode(const tal_t *ctx UNNEEDED, const char *str UNNEEDED,
+			     const struct feature_set *fset UNNEEDED,
 			     const char *description UNNEEDED, char **fail UNNEEDED)
 { fprintf(stderr, "bolt11_decode called!\n"); abort(); }
 /* Generated stub for bolt11_encode_ */
@@ -137,9 +138,6 @@ u32 get_feerate(const struct fee_states *fee_states UNNEEDED,
 		enum side funder UNNEEDED,
 		enum side side UNNEEDED)
 { fprintf(stderr, "get_feerate called!\n"); abort(); }
-/* Generated stub for get_offered_bolt11features */
-u8 *get_offered_bolt11features(const tal_t *ctx UNNEEDED)
-{ fprintf(stderr, "get_offered_bolt11features called!\n"); abort(); }
 /* Generated stub for htlc_is_trimmed */
 bool htlc_is_trimmed(enum side htlc_owner UNNEEDED,
 		     struct amount_msat htlc_amount UNNEEDED,
diff --git a/openingd/openingd.c b/openingd/openingd.c
index 6a67c995e9ea..82dcdb3212a0 100644
--- a/openingd/openingd.c
+++ b/openingd/openingd.c
@@ -113,6 +113,8 @@ struct state {
 	struct channel *channel;
 
 	bool option_static_remotekey;
+
+	struct feature_set *fset;
 };
 
 static u8 *dev_upfront_shutdown_script(const tal_t *ctx)
@@ -563,7 +565,7 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags)
 	 *    `payment_basepoint`, or `delayed_payment_basepoint` are not
 	 *    valid secp256k1 pubkeys in compressed format.
 	 */
-	if (feature_negotiated(state->features,
+	if (feature_negotiated(state->fset, state->features,
 			       OPT_UPFRONT_SHUTDOWN_SCRIPT)) {
 		if (!fromwire_accept_channel_option_upfront_shutdown_script(state,
 				     msg, &id_in,
@@ -644,6 +646,7 @@ static u8 *funder_channel_start(struct state *state, u8 channel_flags)
 	return towire_opening_funder_start_reply(state,
 						 funding_output_script,
 						 feature_negotiated(
+							 state->fset,
 							 state->features,
 							 OPT_UPFRONT_SHUTDOWN_SCRIPT));
 }
@@ -904,7 +907,7 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
 	 *    `payment_basepoint`, or `delayed_payment_basepoint` are not valid
 	 *     secp256k1 pubkeys in compressed format.
 	 */
-	if (feature_negotiated(state->features,
+	if (feature_negotiated(state->fset, state->features,
 			       OPT_UPFRONT_SHUTDOWN_SCRIPT)) {
 		if (!fromwire_open_channel_option_upfront_shutdown_script(state,
 			    open_channel_msg, &chain_hash,
@@ -1481,7 +1484,6 @@ int main(int argc, char *argv[])
 	struct state *state = tal(NULL, struct state);
 	struct secret *none;
 	struct channel_id *force_tmp_channel_id;
-	struct feature_set *feature_set;
 
 	subdaemon_setup(argc, argv);
 
@@ -1493,7 +1495,7 @@ int main(int argc, char *argv[])
 	msg = wire_sync_read(tmpctx, REQ_FD);
 	if (!fromwire_opening_init(state, msg,
 				   &chainparams,
-				   &feature_set,
+				   &state->fset,
 				   &state->localconf,
 				   &state->max_to_self_delay,
 				   &state->min_effective_htlc_capacity,
@@ -1509,8 +1511,6 @@ int main(int argc, char *argv[])
 				   &dev_fast_gossip))
 		master_badmsg(WIRE_OPENING_INIT, msg);
 
-	features_init(take(feature_set));
-
 #if DEVELOPER
 	dev_force_tmp_channel_id = force_tmp_channel_id;
 #endif
diff --git a/plugins/pay.c b/plugins/pay.c
index f02ca195a74b..cc55f703e945 100644
--- a/plugins/pay.c
+++ b/plugins/pay.c
@@ -1283,7 +1283,8 @@ static struct command_result *json_pay(struct command *cmd,
 		   NULL))
 		return command_param_failed();
 
-	b11 = bolt11_decode(cmd, b11str, NULL, &fail);
+	/* FIXME: We need to know our features! */
+	b11 = bolt11_decode(cmd, b11str, NULL, NULL, &fail);
 	if (!b11) {
 		return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
 				    "Invalid bolt11: %s", fail);