Skip to content

Commit

Permalink
lnwire: add new RequiresFeature method
Browse files Browse the repository at this point in the history
In this commit, we add a new RequiresFeature method to the feature
vector struct. This method allows us to check if the set of features
we're examining *require* that the even portion of a bit pair be set.
This can be used to check if new behavior should be allowed (after we
flip new bits to be required) for existing contexts.
  • Loading branch information
Roasbeef committed Nov 26, 2020
1 parent 82ccab6 commit baeceb2
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
14 changes: 14 additions & 0 deletions lnwire/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,20 @@ func (fv *FeatureVector) HasFeature(feature FeatureBit) bool {
(fv.isFeatureBitPair(feature) && fv.IsSet(feature^1))
}

// RequiresFeature returns true if the referenced feature vector *requires*
// that the given required bit be set. This method can be used with both
// optional and required feature bits as a parameter.
func (fv *FeatureVector) RequiresFeature(feature FeatureBit) bool {
// If we weren't passed a required feature bit, then we'll flip the
// lowest bit to query for the required version of the feature. This
// lets callers pass in both the optional and required bits.
if !feature.IsRequired() {
feature ^= 1
}

return fv.IsSet(feature)
}

// UnknownRequiredFeatures returns a list of feature bits set in the vector
// that are unknown and in an even bit position. Feature bits with an even
// index must be known to a node receiving the feature vector in a message.
Expand Down
30 changes: 29 additions & 1 deletion lnwire/features_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"reflect"
"sort"
"testing"

"github.com/stretchr/testify/require"
)

var testFeatureNames = map[FeatureBit]string{
Expand Down Expand Up @@ -87,6 +89,7 @@ func TestFeatureVectorSetUnset(t *testing.T) {
t.Errorf("Expectation failed in case %d, bit %d", i, j)
break
}

}

for _, bit := range test.bits {
Expand All @@ -95,6 +98,31 @@ func TestFeatureVectorSetUnset(t *testing.T) {
}
}

// TestFeatureVectorRequiresFeature tests that if a feature vector only
// includes a required feature bit (it's even), then the RequiresFeature method
// will return true for both that bit as well as it's optional counter party.
func TestFeatureVectorRequiresFeature(t *testing.T) {
t.Parallel()

// Create a new feature vector with the features above, and set only
// the set of required bits. These will be all the even features
// referenced above.
fv := NewFeatureVector(nil, testFeatureNames)
fv.Set(0)
fv.Set(4)

// Next we'll query for those exact bits, these should show up as being
// required.
require.True(t, fv.RequiresFeature(0))
require.True(t, fv.RequiresFeature(4))

// If we query for the odd (optional) counter party to each of the
// features, the method should still return that the backing feature
// vector requires the feature to be set.
require.True(t, fv.RequiresFeature(1))
require.True(t, fv.RequiresFeature(5))
}

func TestFeatureVectorEncodeDecode(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -277,7 +305,7 @@ func TestIsRequired(t *testing.T) {
}

// TestFeatures asserts that the Features() method on a FeatureVector properly
// returns the set of feature bits it stores internallly.
// returns the set of feature bits it stores internally.
func TestFeatures(t *testing.T) {
tests := []struct {
name string
Expand Down

0 comments on commit baeceb2

Please sign in to comment.