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 }