common: make BOLT11 use the normal feature array.

This was decided at a recent spec meeting: in particular, mpp and
var_onion_optin options will be used here.

We enhanced "features_supported" into "features_unsupported" so it
can return the first un-handlable bit number.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2019-11-23 10:49:23 +10:30
parent ebac3d2a85
commit 09cdbb70eb
5 changed files with 20 additions and 16 deletions

View File

@ -458,6 +458,7 @@ static char *decode_9(struct bolt11 *b11,
size_t data_length)
{
size_t flen = (data_length * 5 + 7) / 8;
int badf;
b11->features = tal_arr(b11, u8, flen);
pull_bits_certain(hu5, data, data_len, b11->features,
@ -478,9 +479,9 @@ static char *decode_9(struct bolt11 *b11,
* 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_. */
for (size_t i = 0; i < data_length * 5; i += 2)
if (feature_is_set(b11->features, i))
return tal_fmt(b11, "9: unknown feature bit %zu", i);
badf = features_unsupported(b11->features);
if (badf != -1)
return tal_fmt(b11, "9: unknown feature bit %i", badf);
return NULL;
}

View File

@ -111,8 +111,10 @@ bool feature_negotiated(const u8 *lfeatures, size_t f)
* @bitmap: the features bitmap the peer is asking for
* @supported: array of features we support
* @num_supported: how many elements in supported
*
* Returns -1 on success, or first unsupported feature.
*/
static bool all_supported_features(const u8 *bitmap,
static int all_supported_features(const u8 *bitmap,
const u32 *supported,
size_t num_supported)
{
@ -126,18 +128,18 @@ static bool all_supported_features(const u8 *bitmap,
if (feature_supported(bitnum, supported, num_supported))
continue;
return false;
return bitnum;
}
return true;
return -1;
}
bool features_supported(const u8 *features)
int features_unsupported(const u8 *features)
{
/* BIT 2 would logically be "compulsory initial_routing_sync", but
* that does not exist, so we special case it. */
if (feature_is_set(features,
COMPULSORY_FEATURE(OPT_INITIAL_ROUTING_SYNC)))
return false;
return COMPULSORY_FEATURE(OPT_INITIAL_ROUTING_SYNC);
return all_supported_features(features,
our_features,

View File

@ -4,8 +4,9 @@
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
/* Returns true if we're OK with all these offered features. */
bool features_supported(const u8 *features);
/* 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_features(const tal_t *ctx);

View File

@ -84,17 +84,17 @@ int main(void)
/* We always support no features. */
memset(bits, 0, tal_count(bits));
assert(features_supported(bits));
assert(features_unsupported(bits) == -1);
/* We must support our own features. */
lf = get_offered_features(tmpctx);
assert(features_supported(lf));
assert(features_unsupported(lf) == -1);
/* We can add random odd features, no problem. */
for (size_t i = 1; i < 16; i += 2) {
bits = tal_dup_arr(tmpctx, u8, lf, tal_count(lf), 0);
set_feature_bit(&bits, i);
assert(features_supported(bits));
assert(features_unsupported(bits) == -1);
}
/* We can't add random even features. */
@ -104,9 +104,9 @@ int main(void)
/* Special case for missing compulsory feature */
if (i == 2) {
assert(!features_supported(bits));
assert(features_unsupported(bits) == i);
} else {
assert(features_supported(bits)
assert((features_unsupported(bits) == -1)
== feature_supported(i, our_features,
ARRAY_SIZE(our_features)));
}

View File

@ -73,7 +73,7 @@ static struct io_plan *peer_init_received(struct io_conn *conn,
* - upon receiving unknown _even_ feature bits that are non-zero:
* - MUST fail the connection.
*/
if (!features_supported(features)) {
if (features_unsupported(features) != -1) {
const u8 *our_features = get_offered_features(msg);
msg = towire_errorfmt(NULL, NULL, "Unsupported features %s:"
" we only offer features %s",