Browse Source

features: add 'feature_bit_sub', which will subtract/unset bits

Given a two sets of featurebits, unset the featurebits in the first set
that are set in the second set
travis-experimental
niftynei 4 years ago
committed by neil saitug
parent
commit
ddc9500a64
  1. 29
      common/features.c
  2. 4
      common/features.h
  3. 33
      common/test/run-features.c

29
common/features.c

@ -205,6 +205,35 @@ bool feature_set_or(struct feature_set *a,
return true;
}
bool feature_set_sub(struct feature_set *a,
const struct feature_set *b TAKES)
{
/* Check first, before we change anything! */
for (size_t i = 0; i < ARRAY_SIZE(b->bits); i++) {
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(a->bits); i++) {
for (size_t j = 0; j < tal_bytelen(b->bits[i])*8; j++) {
if (feature_is_set(b->bits[i], j))
clear_feature_bit(a->bits[i], j);
}
trim_features(&a->bits[i]);
}
if (taken(b))
tal_free(b);
return true;
}
/* BOLT #1:
*
* All data fields are unsigned big-endian unless otherwise specified.

4
common/features.h

@ -32,6 +32,10 @@ void towire_feature_set(u8 **pptr, const struct feature_set *fset);
bool feature_set_or(struct feature_set *a,
const struct feature_set *b TAKES);
/* a - b, or returns false if features not already in a */
bool feature_set_sub(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 struct feature_set *our_features,

33
common/test/run-features.c

@ -179,6 +179,38 @@ static void test_feature_set_or(void)
}
}
static void test_feature_set_sub(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);
/* sub with nothing is a nop */
set_feature_bit(&f1->bits[i], 0);
set_feature_bit(&control->bits[i], 0);
assert(feature_set_eq(f1, control));
assert(feature_set_sub(f1, f2));
/* can't sub feature bit that's not set */
set_feature_bit(&f2->bits[i], 2);
assert(!feature_set_sub(f1, f2));
assert(feature_set_eq(f1, control));
assert(!feature_set_sub(f2, f1));
/* sub does the right thing */
set_feature_bit(&f1->bits[i], 2);
assert(feature_set_sub(f1, f2));
assert(feature_set_eq(f1, control));
assert(!feature_set_sub(f1, f2));
}
}
static void test_feature_trim(void)
{
struct feature_set *f;
@ -299,6 +331,7 @@ int main(void)
test_featurebits_or();
test_feature_set_or();
test_feature_trim();
test_feature_set_sub();
wally_cleanup(0);
tal_free(tmpctx);

Loading…
Cancel
Save