mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
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:
@@ -458,6 +458,7 @@ static char *decode_9(struct bolt11 *b11,
|
|||||||
size_t data_length)
|
size_t data_length)
|
||||||
{
|
{
|
||||||
size_t flen = (data_length * 5 + 7) / 8;
|
size_t flen = (data_length * 5 + 7) / 8;
|
||||||
|
int badf;
|
||||||
|
|
||||||
b11->features = tal_arr(b11, u8, flen);
|
b11->features = tal_arr(b11, u8, flen);
|
||||||
pull_bits_certain(hu5, data, data_len, b11->features,
|
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,
|
* 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 _even_, and the next most significant bit is numbered 1,
|
||||||
* which is _odd_. */
|
* which is _odd_. */
|
||||||
for (size_t i = 0; i < data_length * 5; i += 2)
|
badf = features_unsupported(b11->features);
|
||||||
if (feature_is_set(b11->features, i))
|
if (badf != -1)
|
||||||
return tal_fmt(b11, "9: unknown feature bit %zu", i);
|
return tal_fmt(b11, "9: unknown feature bit %i", badf);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,8 +111,10 @@ bool feature_negotiated(const u8 *lfeatures, size_t f)
|
|||||||
* @bitmap: the features bitmap the peer is asking for
|
* @bitmap: the features bitmap the peer is asking for
|
||||||
* @supported: array of features we support
|
* @supported: array of features we support
|
||||||
* @num_supported: how many elements in supported
|
* @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,
|
const u32 *supported,
|
||||||
size_t num_supported)
|
size_t num_supported)
|
||||||
{
|
{
|
||||||
@@ -126,18 +128,18 @@ static bool all_supported_features(const u8 *bitmap,
|
|||||||
if (feature_supported(bitnum, supported, num_supported))
|
if (feature_supported(bitnum, supported, num_supported))
|
||||||
continue;
|
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
|
/* BIT 2 would logically be "compulsory initial_routing_sync", but
|
||||||
* that does not exist, so we special case it. */
|
* that does not exist, so we special case it. */
|
||||||
if (feature_is_set(features,
|
if (feature_is_set(features,
|
||||||
COMPULSORY_FEATURE(OPT_INITIAL_ROUTING_SYNC)))
|
COMPULSORY_FEATURE(OPT_INITIAL_ROUTING_SYNC)))
|
||||||
return false;
|
return COMPULSORY_FEATURE(OPT_INITIAL_ROUTING_SYNC);
|
||||||
|
|
||||||
return all_supported_features(features,
|
return all_supported_features(features,
|
||||||
our_features,
|
our_features,
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
#include <ccan/short_types/short_types.h>
|
#include <ccan/short_types/short_types.h>
|
||||||
#include <ccan/tal/tal.h>
|
#include <ccan/tal/tal.h>
|
||||||
|
|
||||||
/* Returns true if we're OK with all these offered features. */
|
/* Returns -1 if we're OK with all these offered features, otherwise first
|
||||||
bool features_supported(const u8 *features);
|
* unsupported (even) feature. */
|
||||||
|
int features_unsupported(const u8 *features);
|
||||||
|
|
||||||
/* For sending our features: tal_count() returns length. */
|
/* For sending our features: tal_count() returns length. */
|
||||||
u8 *get_offered_features(const tal_t *ctx);
|
u8 *get_offered_features(const tal_t *ctx);
|
||||||
|
|||||||
@@ -84,17 +84,17 @@ int main(void)
|
|||||||
|
|
||||||
/* We always support no features. */
|
/* We always support no features. */
|
||||||
memset(bits, 0, tal_count(bits));
|
memset(bits, 0, tal_count(bits));
|
||||||
assert(features_supported(bits));
|
assert(features_unsupported(bits) == -1);
|
||||||
|
|
||||||
/* We must support our own features. */
|
/* We must support our own features. */
|
||||||
lf = get_offered_features(tmpctx);
|
lf = get_offered_features(tmpctx);
|
||||||
assert(features_supported(lf));
|
assert(features_unsupported(lf) == -1);
|
||||||
|
|
||||||
/* We can add random odd features, no problem. */
|
/* We can add random odd features, no problem. */
|
||||||
for (size_t i = 1; i < 16; i += 2) {
|
for (size_t i = 1; i < 16; i += 2) {
|
||||||
bits = tal_dup_arr(tmpctx, u8, lf, tal_count(lf), 0);
|
bits = tal_dup_arr(tmpctx, u8, lf, tal_count(lf), 0);
|
||||||
set_feature_bit(&bits, i);
|
set_feature_bit(&bits, i);
|
||||||
assert(features_supported(bits));
|
assert(features_unsupported(bits) == -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We can't add random even features. */
|
/* We can't add random even features. */
|
||||||
@@ -104,9 +104,9 @@ int main(void)
|
|||||||
|
|
||||||
/* Special case for missing compulsory feature */
|
/* Special case for missing compulsory feature */
|
||||||
if (i == 2) {
|
if (i == 2) {
|
||||||
assert(!features_supported(bits));
|
assert(features_unsupported(bits) == i);
|
||||||
} else {
|
} else {
|
||||||
assert(features_supported(bits)
|
assert((features_unsupported(bits) == -1)
|
||||||
== feature_supported(i, our_features,
|
== feature_supported(i, our_features,
|
||||||
ARRAY_SIZE(our_features)));
|
ARRAY_SIZE(our_features)));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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:
|
* - upon receiving unknown _even_ feature bits that are non-zero:
|
||||||
* - MUST fail the connection.
|
* - MUST fail the connection.
|
||||||
*/
|
*/
|
||||||
if (!features_supported(features)) {
|
if (features_unsupported(features) != -1) {
|
||||||
const u8 *our_features = get_offered_features(msg);
|
const u8 *our_features = get_offered_features(msg);
|
||||||
msg = towire_errorfmt(NULL, NULL, "Unsupported features %s:"
|
msg = towire_errorfmt(NULL, NULL, "Unsupported features %s:"
|
||||||
" we only offer features %s",
|
" we only offer features %s",
|
||||||
|
|||||||
Reference in New Issue
Block a user