common/features: add explicit bolt12 feature sets.

The spec only specifies the mpp bit for invoices, but in
general they are separate spaces.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2022-11-09 13:02:00 +10:30 committed by Christian Decker
parent 6e755d6fe8
commit 9a0d2040d3
5 changed files with 14 additions and 7 deletions

View file

@ -53,6 +53,7 @@ static char *check_features_and_chain(const tal_t *ctx,
const struct feature_set *our_features,
const struct chainparams *must_be_chain,
const u8 *features,
enum feature_place fplace,
const struct bitcoin_blkid *chains,
size_t num_chains)
{
@ -62,8 +63,7 @@ static char *check_features_and_chain(const tal_t *ctx,
}
if (our_features) {
int badf = features_unsupported(our_features, features,
BOLT11_FEATURE);
int badf = features_unsupported(our_features, features, fplace);
if (badf != -1)
return tal_fmt(ctx, "unknown feature bit %i", badf);
}
@ -182,6 +182,7 @@ struct tlv_offer *offer_decode(const tal_t *ctx,
*fail = check_features_and_chain(ctx,
our_features, must_be_chain,
offer->features,
BOLT12_OFFER_FEATURE,
offer->chains,
tal_count(offer->chains));
if (*fail)
@ -236,6 +237,7 @@ struct tlv_invoice_request *invrequest_decode(const tal_t *ctx,
*fail = check_features_and_chain(ctx,
our_features, must_be_chain,
invrequest->features,
BOLT12_INVREQ_FEATURE,
invrequest->chain, 1);
if (*fail)
return tal_free(invrequest);
@ -276,6 +278,7 @@ struct tlv_invoice *invoice_decode_nosig(const tal_t *ctx,
*fail = check_features_and_chain(ctx,
our_features, must_be_chain,
invoice->features,
BOLT12_INVOICE_FEATURE,
invoice->chain, 1);
if (*fail)
return tal_free(invoice);

View file

@ -59,7 +59,8 @@ static const struct feature_style feature_styles[] = {
{ OPT_BASIC_MPP,
.copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT,
[NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT,
[BOLT11_FEATURE] = FEATURE_REPRESENT } },
[BOLT11_FEATURE] = FEATURE_REPRESENT,
[BOLT12_INVOICE_FEATURE] = FEATURE_REPRESENT } },
/* BOLT #9:
* | 18/19 | `option_support_large_channel` |... IN ...
*/

View file

@ -10,8 +10,11 @@ enum feature_place {
NODE_ANNOUNCE_FEATURE,
CHANNEL_FEATURE,
BOLT11_FEATURE,
BOLT12_OFFER_FEATURE,
BOLT12_INVREQ_FEATURE,
BOLT12_INVOICE_FEATURE,
};
#define NUM_FEATURE_PLACE (BOLT11_FEATURE+1)
#define NUM_FEATURE_PLACE (BOLT12_INVOICE_FEATURE+1)
extern const char *feature_place_names[NUM_FEATURE_PLACE];

View file

@ -635,8 +635,8 @@ static char *opt_force_featureset(const char *optarg,
char **parts = tal_strsplit(tmpctx, optarg, "/", STR_EMPTY_OK);
if (tal_count(parts) != NUM_FEATURE_PLACE + 1) {
if (!strstarts(optarg, "-") && !strstarts(optarg, "+"))
return "Expected 5 feature sets (init/globalinit/"
" node_announce/channel/bolt11) each terminated by /"
return "Expected 8 feature sets (init/globalinit/"
" node_announce/channel/bolt11/b12offer/b12invreq/b12inv) each terminated by /"
" OR +/-<single_bit_num>";
char *endp;

View file

@ -3510,7 +3510,7 @@ def test_nonstatic_channel(node_factory, bitcoind):
opts=[{},
# needs at least 15 to connect
# (and 9 is a dependent)
{'dev-force-features': '9,15/////'}])
{'dev-force-features': '9,15////////'}])
chan = only_one(only_one(l1.rpc.listpeers()['peers'])['channels'])
assert 'option_static_remotekey' not in chan['features']
assert 'option_anchor_outputs' not in chan['features']