github.com/decred/dcrlnd@v0.7.6/lnwire/features_test.go (about)

     1  package lnwire
     2  
     3  import (
     4  	"bytes"
     5  	"reflect"
     6  	"sort"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  var testFeatureNames = map[FeatureBit]string{
    13  	0: "feature1",
    14  	3: "feature2",
    15  	4: "feature3",
    16  	5: "feature3",
    17  }
    18  
    19  func TestFeatureVectorSetUnset(t *testing.T) {
    20  	t.Parallel()
    21  
    22  	tests := []struct {
    23  		bits             []FeatureBit
    24  		expectedFeatures []bool
    25  	}{
    26  		// No features are enabled if no bits are set.
    27  		{
    28  			bits:             nil,
    29  			expectedFeatures: []bool{false, false, false, false, false, false, false, false},
    30  		},
    31  		// Test setting an even bit for an even-only bit feature. The
    32  		// corresponding odd bit should not be seen as set.
    33  		{
    34  			bits:             []FeatureBit{0},
    35  			expectedFeatures: []bool{true, false, false, false, false, false, false, false},
    36  		},
    37  		// Test setting an odd bit for an even-only bit feature. The
    38  		// corresponding even bit should not be seen as set.
    39  		{
    40  			bits:             []FeatureBit{1},
    41  			expectedFeatures: []bool{false, true, false, false, false, false, false, false},
    42  		},
    43  		// Test setting an even bit for an odd-only bit feature. The bit should
    44  		// be seen as set and the odd bit should not.
    45  		{
    46  			bits:             []FeatureBit{2},
    47  			expectedFeatures: []bool{false, false, true, false, false, false, false, false},
    48  		},
    49  		// Test setting an odd bit for an odd-only bit feature. The bit should
    50  		// be seen as set and the even bit should not.
    51  		{
    52  			bits:             []FeatureBit{3},
    53  			expectedFeatures: []bool{false, false, false, true, false, false, false, false},
    54  		},
    55  		// Test setting an even bit for even-odd pair feature. Both bits in the
    56  		// pair should be seen as set.
    57  		{
    58  			bits:             []FeatureBit{4},
    59  			expectedFeatures: []bool{false, false, false, false, true, true, false, false},
    60  		},
    61  		// Test setting an odd bit for even-odd pair feature. Both bits in the
    62  		// pair should be seen as set.
    63  		{
    64  			bits:             []FeatureBit{5},
    65  			expectedFeatures: []bool{false, false, false, false, true, true, false, false},
    66  		},
    67  		// Test setting an even bit for an unknown feature. The bit should be
    68  		// seen as set and the odd bit should not.
    69  		{
    70  			bits:             []FeatureBit{6},
    71  			expectedFeatures: []bool{false, false, false, false, false, false, true, false},
    72  		},
    73  		// Test setting an odd bit for an unknown feature. The bit should be
    74  		// seen as set and the odd bit should not.
    75  		{
    76  			bits:             []FeatureBit{7},
    77  			expectedFeatures: []bool{false, false, false, false, false, false, false, true},
    78  		},
    79  	}
    80  
    81  	fv := NewFeatureVector(nil, testFeatureNames)
    82  	for i, test := range tests {
    83  		for _, bit := range test.bits {
    84  			fv.Set(bit)
    85  		}
    86  
    87  		for j, expectedSet := range test.expectedFeatures {
    88  			if fv.HasFeature(FeatureBit(j)) != expectedSet {
    89  				t.Errorf("Expectation failed in case %d, bit %d", i, j)
    90  				break
    91  			}
    92  
    93  		}
    94  
    95  		for _, bit := range test.bits {
    96  			fv.Unset(bit)
    97  		}
    98  	}
    99  }
   100  
   101  // TestFeatureVectorRequiresFeature tests that if a feature vector only
   102  // includes a required feature bit (it's even), then the RequiresFeature method
   103  // will return true for both that bit as well as it's optional counter party.
   104  func TestFeatureVectorRequiresFeature(t *testing.T) {
   105  	t.Parallel()
   106  
   107  	// Create a new feature vector with the features above, and set only
   108  	// the set of required bits. These will be all the even features
   109  	// referenced above.
   110  	fv := NewFeatureVector(nil, testFeatureNames)
   111  	fv.Set(0)
   112  	fv.Set(4)
   113  
   114  	// Next we'll query for those exact bits, these should show up as being
   115  	// required.
   116  	require.True(t, fv.RequiresFeature(0))
   117  	require.True(t, fv.RequiresFeature(4))
   118  
   119  	// If we query for the odd (optional) counter party to each of the
   120  	// features, the method should still return that the backing feature
   121  	// vector requires the feature to be set.
   122  	require.True(t, fv.RequiresFeature(1))
   123  	require.True(t, fv.RequiresFeature(5))
   124  }
   125  
   126  func TestFeatureVectorEncodeDecode(t *testing.T) {
   127  	t.Parallel()
   128  
   129  	tests := []struct {
   130  		bits            []FeatureBit
   131  		expectedEncoded []byte
   132  	}{
   133  		{
   134  			bits:            nil,
   135  			expectedEncoded: []byte{0x00, 0x00},
   136  		},
   137  		{
   138  			bits:            []FeatureBit{2, 3, 7},
   139  			expectedEncoded: []byte{0x00, 0x01, 0x8C},
   140  		},
   141  		{
   142  			bits:            []FeatureBit{2, 3, 8},
   143  			expectedEncoded: []byte{0x00, 0x02, 0x01, 0x0C},
   144  		},
   145  	}
   146  
   147  	for i, test := range tests {
   148  		fv := NewRawFeatureVector(test.bits...)
   149  
   150  		// Test that Encode produces the correct serialization.
   151  		buffer := new(bytes.Buffer)
   152  		err := fv.Encode(buffer)
   153  		if err != nil {
   154  			t.Errorf("Failed to encode feature vector in case %d: %v", i, err)
   155  			continue
   156  		}
   157  
   158  		encoded := buffer.Bytes()
   159  		if !bytes.Equal(encoded, test.expectedEncoded) {
   160  			t.Errorf("Wrong encoding in case %d: got %v, expected %v",
   161  				i, encoded, test.expectedEncoded)
   162  			continue
   163  		}
   164  
   165  		// Test that decoding then re-encoding produces the same result.
   166  		fv2 := NewRawFeatureVector()
   167  		err = fv2.Decode(bytes.NewReader(encoded))
   168  		if err != nil {
   169  			t.Errorf("Failed to decode feature vector in case %d: %v", i, err)
   170  			continue
   171  		}
   172  
   173  		buffer2 := new(bytes.Buffer)
   174  		err = fv2.Encode(buffer2)
   175  		if err != nil {
   176  			t.Errorf("Failed to re-encode feature vector in case %d: %v",
   177  				i, err)
   178  			continue
   179  		}
   180  
   181  		reencoded := buffer2.Bytes()
   182  		if !bytes.Equal(reencoded, test.expectedEncoded) {
   183  			t.Errorf("Wrong re-encoding in case %d: got %v, expected %v",
   184  				i, reencoded, test.expectedEncoded)
   185  		}
   186  	}
   187  }
   188  
   189  func TestFeatureVectorUnknownFeatures(t *testing.T) {
   190  	t.Parallel()
   191  
   192  	tests := []struct {
   193  		bits            []FeatureBit
   194  		expectedUnknown []FeatureBit
   195  	}{
   196  		{
   197  			bits:            nil,
   198  			expectedUnknown: nil,
   199  		},
   200  		// Since bits {0, 3, 4, 5} are known, and only even bits are considered
   201  		// required (according to the "it's OK to be odd rule"), that leaves
   202  		// {2, 6} as both unknown and required.
   203  		{
   204  			bits:            []FeatureBit{0, 1, 2, 3, 4, 5, 6, 7},
   205  			expectedUnknown: []FeatureBit{2, 6},
   206  		},
   207  	}
   208  
   209  	for i, test := range tests {
   210  		rawVector := NewRawFeatureVector(test.bits...)
   211  		fv := NewFeatureVector(rawVector, testFeatureNames)
   212  
   213  		unknown := fv.UnknownRequiredFeatures()
   214  
   215  		// Sort to make comparison independent of order
   216  		sort.Slice(unknown, func(i, j int) bool {
   217  			return unknown[i] < unknown[j]
   218  		})
   219  		if !reflect.DeepEqual(unknown, test.expectedUnknown) {
   220  			t.Errorf("Wrong unknown features in case %d: got %v, expected %v",
   221  				i, unknown, test.expectedUnknown)
   222  		}
   223  	}
   224  }
   225  
   226  func TestFeatureNames(t *testing.T) {
   227  	t.Parallel()
   228  
   229  	tests := []struct {
   230  		bit           FeatureBit
   231  		expectedName  string
   232  		expectedKnown bool
   233  	}{
   234  		{
   235  			bit:           0,
   236  			expectedName:  "feature1",
   237  			expectedKnown: true,
   238  		},
   239  		{
   240  			bit:           1,
   241  			expectedName:  "unknown",
   242  			expectedKnown: false,
   243  		},
   244  		{
   245  			bit:           2,
   246  			expectedName:  "unknown",
   247  			expectedKnown: false,
   248  		},
   249  		{
   250  			bit:           3,
   251  			expectedName:  "feature2",
   252  			expectedKnown: true,
   253  		},
   254  		{
   255  			bit:           4,
   256  			expectedName:  "feature3",
   257  			expectedKnown: true,
   258  		},
   259  		{
   260  			bit:           5,
   261  			expectedName:  "feature3",
   262  			expectedKnown: true,
   263  		},
   264  		{
   265  			bit:           6,
   266  			expectedName:  "unknown",
   267  			expectedKnown: false,
   268  		},
   269  		{
   270  			bit:           7,
   271  			expectedName:  "unknown",
   272  			expectedKnown: false,
   273  		},
   274  	}
   275  
   276  	fv := NewFeatureVector(nil, testFeatureNames)
   277  	for _, test := range tests {
   278  		name := fv.Name(test.bit)
   279  		if name != test.expectedName {
   280  			t.Errorf("Name for feature bit %d is incorrect: "+
   281  				"expected %s, got %s", test.bit, name, test.expectedName)
   282  		}
   283  
   284  		known := fv.IsKnown(test.bit)
   285  		if known != test.expectedKnown {
   286  			t.Errorf("IsKnown for feature bit %d is incorrect: "+
   287  				"expected %v, got %v", test.bit, known, test.expectedKnown)
   288  		}
   289  	}
   290  }
   291  
   292  // TestIsRequired asserts that feature bits properly return their IsRequired
   293  // status. We require that even features be required and odd features be
   294  // optional.
   295  func TestIsRequired(t *testing.T) {
   296  	optional := FeatureBit(1)
   297  	if optional.IsRequired() {
   298  		t.Fatalf("optional feature should not be required")
   299  	}
   300  
   301  	required := FeatureBit(0)
   302  	if !required.IsRequired() {
   303  		t.Fatalf("required feature should be required")
   304  	}
   305  }
   306  
   307  // TestFeatures asserts that the Features() method on a FeatureVector properly
   308  // returns the set of feature bits it stores internally.
   309  func TestFeatures(t *testing.T) {
   310  	tests := []struct {
   311  		name string
   312  		exp  map[FeatureBit]struct{}
   313  	}{
   314  		{
   315  			name: "empty",
   316  			exp:  map[FeatureBit]struct{}{},
   317  		},
   318  		{
   319  			name: "one",
   320  			exp: map[FeatureBit]struct{}{
   321  				5: {},
   322  			},
   323  		},
   324  		{
   325  			name: "several",
   326  			exp: map[FeatureBit]struct{}{
   327  				0:     {},
   328  				5:     {},
   329  				23948: {},
   330  			},
   331  		},
   332  	}
   333  
   334  	toRawFV := func(set map[FeatureBit]struct{}) *RawFeatureVector {
   335  		var bits []FeatureBit
   336  		for bit := range set {
   337  			bits = append(bits, bit)
   338  		}
   339  		return NewRawFeatureVector(bits...)
   340  	}
   341  
   342  	for _, test := range tests {
   343  		test := test
   344  		t.Run(test.name, func(t *testing.T) {
   345  			fv := NewFeatureVector(
   346  				toRawFV(test.exp), Features,
   347  			)
   348  
   349  			if !reflect.DeepEqual(fv.Features(), test.exp) {
   350  				t.Fatalf("feature mismatch, want: %v, got: %v",
   351  					test.exp, fv.Features())
   352  			}
   353  		})
   354  	}
   355  }
   356  
   357  func TestRawFeatureVectorOnlyContains(t *testing.T) {
   358  	t.Parallel()
   359  
   360  	features := []FeatureBit{
   361  		StaticRemoteKeyOptional,
   362  		AnchorsZeroFeeHtlcTxOptional,
   363  		ExplicitChannelTypeRequired,
   364  	}
   365  	fv := NewRawFeatureVector(features...)
   366  	require.True(t, fv.OnlyContains(features...))
   367  	require.False(t, fv.OnlyContains(features[:1]...))
   368  }
   369  
   370  func TestEqualRawFeatureVectors(t *testing.T) {
   371  	t.Parallel()
   372  
   373  	a := NewRawFeatureVector(
   374  		StaticRemoteKeyOptional,
   375  		AnchorsZeroFeeHtlcTxOptional,
   376  		ExplicitChannelTypeRequired,
   377  	)
   378  	b := a.Clone()
   379  	require.True(t, a.Equals(b))
   380  
   381  	b.Unset(ExplicitChannelTypeRequired)
   382  	require.False(t, a.Equals(b))
   383  
   384  	b.Set(ExplicitChannelTypeOptional)
   385  	require.False(t, a.Equals(b))
   386  }
   387  
   388  func TestIsEmptyFeatureVector(t *testing.T) {
   389  	t.Parallel()
   390  
   391  	fv := NewRawFeatureVector()
   392  	require.True(t, fv.IsEmpty())
   393  
   394  	fv.Set(StaticRemoteKeyOptional)
   395  	require.False(t, fv.IsEmpty())
   396  
   397  	fv.Unset(StaticRemoteKeyOptional)
   398  	require.True(t, fv.IsEmpty())
   399  }