github.com/decred/dcrlnd@v0.7.6/lnwire/lnwire_test.go (about) 1 package lnwire 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "encoding/hex" 7 "image/color" 8 "math" 9 "math/rand" 10 "net" 11 "reflect" 12 "testing" 13 "testing/quick" 14 "time" 15 16 "github.com/decred/dcrd/chaincfg/chainhash" 17 "github.com/decred/dcrd/dcrec/secp256k1/v4" 18 "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa" 19 "github.com/decred/dcrd/dcrutil/v4" 20 "github.com/decred/dcrd/wire" 21 "github.com/decred/dcrlnd/tor" 22 "github.com/stretchr/testify/assert" 23 ) 24 25 func modNScalar(b []byte) *secp256k1.ModNScalar { 26 var m secp256k1.ModNScalar 27 m.SetByteSlice(b) 28 return &m 29 } 30 31 var ( 32 shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") 33 shaHash1, _ = chainhash.NewHash(shaHash1Bytes) 34 outpoint1 = wire.NewOutPoint(shaHash1, 0, wire.TxTreeRegular) 35 rBytes, _ = hex.DecodeString("63724406601629180062774974542967536251589935445068131219452686511677818569431") 36 sBytes, _ = hex.DecodeString("18801056069249825825291287104931333862866033135609736119018462340006816851118") 37 testSig = ecdsa.NewSignature(modNScalar(rBytes), modNScalar(sBytes)) 38 ) 39 40 const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" 41 42 func randAlias(r *rand.Rand) NodeAlias { 43 var a NodeAlias 44 for i := range a { 45 a[i] = letterBytes[r.Intn(len(letterBytes))] 46 } 47 48 return a 49 } 50 51 func randPubKey() (*secp256k1.PublicKey, error) { 52 priv, err := secp256k1.GeneratePrivateKey() 53 if err != nil { 54 return nil, err 55 } 56 57 return priv.PubKey(), nil 58 } 59 60 func randRawKey() ([33]byte, error) { 61 var n [33]byte 62 63 priv, err := secp256k1.GeneratePrivateKey() 64 if err != nil { 65 return n, err 66 } 67 68 copy(n[:], priv.PubKey().SerializeCompressed()) 69 70 return n, nil 71 } 72 73 func randDeliveryAddress(r *rand.Rand) (DeliveryAddress, error) { 74 // Generate size minimum one. Empty scripts should be tested specifically. 75 size := r.Intn(deliveryAddressMaxSize) + 1 76 da := DeliveryAddress(make([]byte, size)) 77 78 _, err := r.Read(da) 79 return da, err 80 } 81 82 func randRawFeatureVector(r *rand.Rand) *RawFeatureVector { 83 featureVec := NewRawFeatureVector() 84 for i := 0; i < 10000; i++ { 85 if r.Int31n(2) == 0 { 86 featureVec.Set(FeatureBit(i)) 87 } 88 } 89 return featureVec 90 } 91 92 func randTCP4Addr(r *rand.Rand) (*net.TCPAddr, error) { 93 var ip [4]byte 94 if _, err := r.Read(ip[:]); err != nil { 95 return nil, err 96 } 97 98 var port [2]byte 99 if _, err := r.Read(port[:]); err != nil { 100 return nil, err 101 } 102 103 addrIP := net.IP(ip[:]) 104 addrPort := int(binary.BigEndian.Uint16(port[:])) 105 106 return &net.TCPAddr{IP: addrIP, Port: addrPort}, nil 107 } 108 109 func randTCP6Addr(r *rand.Rand) (*net.TCPAddr, error) { 110 var ip [16]byte 111 if _, err := r.Read(ip[:]); err != nil { 112 return nil, err 113 } 114 115 var port [2]byte 116 if _, err := r.Read(port[:]); err != nil { 117 return nil, err 118 } 119 120 addrIP := net.IP(ip[:]) 121 addrPort := int(binary.BigEndian.Uint16(port[:])) 122 123 return &net.TCPAddr{IP: addrIP, Port: addrPort}, nil 124 } 125 126 func randV2OnionAddr(r *rand.Rand) (*tor.OnionAddr, error) { 127 var serviceID [tor.V2DecodedLen]byte 128 if _, err := r.Read(serviceID[:]); err != nil { 129 return nil, err 130 } 131 132 var port [2]byte 133 if _, err := r.Read(port[:]); err != nil { 134 return nil, err 135 } 136 137 onionService := tor.Base32Encoding.EncodeToString(serviceID[:]) 138 onionService += tor.OnionSuffix 139 addrPort := int(binary.BigEndian.Uint16(port[:])) 140 141 return &tor.OnionAddr{OnionService: onionService, Port: addrPort}, nil 142 } 143 144 func randV3OnionAddr(r *rand.Rand) (*tor.OnionAddr, error) { 145 var serviceID [tor.V3DecodedLen]byte 146 if _, err := r.Read(serviceID[:]); err != nil { 147 return nil, err 148 } 149 150 var port [2]byte 151 if _, err := r.Read(port[:]); err != nil { 152 return nil, err 153 } 154 155 onionService := tor.Base32Encoding.EncodeToString(serviceID[:]) 156 onionService += tor.OnionSuffix 157 addrPort := int(binary.BigEndian.Uint16(port[:])) 158 159 return &tor.OnionAddr{OnionService: onionService, Port: addrPort}, nil 160 } 161 162 func randAddrs(r *rand.Rand) ([]net.Addr, error) { 163 tcp4Addr, err := randTCP4Addr(r) 164 if err != nil { 165 return nil, err 166 } 167 168 tcp6Addr, err := randTCP6Addr(r) 169 if err != nil { 170 return nil, err 171 } 172 173 v2OnionAddr, err := randV2OnionAddr(r) 174 if err != nil { 175 return nil, err 176 } 177 178 v3OnionAddr, err := randV3OnionAddr(r) 179 if err != nil { 180 return nil, err 181 } 182 183 return []net.Addr{tcp4Addr, tcp6Addr, v2OnionAddr, v3OnionAddr}, nil 184 } 185 186 // TestChanUpdateChanFlags ensures that converting the ChanUpdateChanFlags and 187 // ChanUpdateMsgFlags bitfields to a string behaves as expected. 188 func TestChanUpdateChanFlags(t *testing.T) { 189 t.Parallel() 190 191 testCases := []struct { 192 flags uint8 193 expected string 194 }{ 195 { 196 flags: 0, 197 expected: "00000000", 198 }, 199 { 200 flags: 1, 201 expected: "00000001", 202 }, 203 { 204 flags: 3, 205 expected: "00000011", 206 }, 207 { 208 flags: 255, 209 expected: "11111111", 210 }, 211 } 212 213 for _, test := range testCases { 214 chanFlag := ChanUpdateChanFlags(test.flags) 215 toStr := chanFlag.String() 216 if toStr != test.expected { 217 t.Fatalf("expected %v, got %v", 218 test.expected, toStr) 219 } 220 221 msgFlag := ChanUpdateMsgFlags(test.flags) 222 toStr = msgFlag.String() 223 if toStr != test.expected { 224 t.Fatalf("expected %v, got %v", 225 test.expected, toStr) 226 } 227 } 228 } 229 230 func TestMaxOutPointIndex(t *testing.T) { 231 t.Parallel() 232 233 op := wire.OutPoint{ 234 Index: math.MaxUint32, 235 } 236 237 var b bytes.Buffer 238 if err := WriteOutPoint(&b, op); err == nil { 239 t.Fatalf("write of outPoint should fail, index exceeds 16-bits") 240 } 241 } 242 243 func TestEmptyMessageUnknownType(t *testing.T) { 244 t.Parallel() 245 246 fakeType := CustomTypeStart - 1 247 if _, err := makeEmptyMessage(fakeType); err == nil { 248 t.Fatalf("should not be able to make an empty message of an " + 249 "unknown type") 250 } 251 } 252 253 // TestLightningWireProtocol uses the testing/quick package to create a series 254 // of fuzz tests to attempt to break a primary scenario which is implemented as 255 // property based testing scenario. 256 func TestLightningWireProtocol(t *testing.T) { 257 t.Parallel() 258 259 // mainScenario is the primary test that will programmatically be 260 // executed for all registered wire messages. The quick-checker within 261 // testing/quick will attempt to find an input to this function, s.t 262 // the function returns false, if so then we've found an input that 263 // violates our model of the system. 264 mainScenario := func(msg Message) bool { 265 // Give a new message, we'll serialize the message into a new 266 // bytes buffer. 267 var b bytes.Buffer 268 if _, err := WriteMessage(&b, msg, 0); err != nil { 269 t.Fatalf("unable to write msg: %v", err) 270 return false 271 } 272 273 // Next, we'll ensure that the serialized payload (subtracting 274 // the 2 bytes for the message type) is _below_ the specified 275 // max payload size for this message. 276 payloadLen := uint32(b.Len()) - 2 277 if payloadLen > MaxMsgBody { 278 t.Fatalf("msg payload constraint violated: %v > %v", 279 payloadLen, MaxMsgBody) 280 return false 281 } 282 283 // Finally, we'll deserialize the message from the written 284 // buffer, and finally assert that the messages are equal. 285 newMsg, err := ReadMessage(&b, 0) 286 if err != nil { 287 t.Fatalf("unable to read msg: %v", err) 288 return false 289 } 290 if !assert.Equalf(t, msg, newMsg, "message mismatch") { 291 return false 292 } 293 294 return true 295 } 296 297 // customTypeGen is a map of functions that are able to randomly 298 // generate a given type. These functions are needed for types which 299 // are too complex for the testing/quick package to automatically 300 // generate. 301 customTypeGen := map[MessageType]func([]reflect.Value, *rand.Rand){ 302 MsgInit: func(v []reflect.Value, r *rand.Rand) { 303 req := NewInitMessage( 304 randRawFeatureVector(r), 305 randRawFeatureVector(r), 306 ) 307 308 v[0] = reflect.ValueOf(*req) 309 }, 310 MsgOpenChannel: func(v []reflect.Value, r *rand.Rand) { 311 req := OpenChannel{ 312 FundingAmount: dcrutil.Amount(r.Int63()), 313 PushAmount: MilliAtom(r.Int63()), 314 DustLimit: dcrutil.Amount(r.Int63()), 315 MaxValueInFlight: MilliAtom(r.Int63()), 316 ChannelReserve: dcrutil.Amount(r.Int63()), 317 HtlcMinimum: MilliAtom(r.Int31()), 318 FeePerKiloByte: uint32(r.Int63()), 319 CsvDelay: uint16(r.Int31()), 320 MaxAcceptedHTLCs: uint16(r.Int31()), 321 ChannelFlags: FundingFlag(uint8(r.Int31())), 322 } 323 324 if _, err := r.Read(req.ChainHash[:]); err != nil { 325 t.Fatalf("unable to generate chain hash: %v", err) 326 return 327 } 328 329 if _, err := r.Read(req.PendingChannelID[:]); err != nil { 330 t.Fatalf("unable to generate pending chan id: %v", err) 331 return 332 } 333 334 var err error 335 req.FundingKey, err = randPubKey() 336 if err != nil { 337 t.Fatalf("unable to generate key: %v", err) 338 return 339 } 340 req.RevocationPoint, err = randPubKey() 341 if err != nil { 342 t.Fatalf("unable to generate key: %v", err) 343 return 344 } 345 req.PaymentPoint, err = randPubKey() 346 if err != nil { 347 t.Fatalf("unable to generate key: %v", err) 348 return 349 } 350 req.DelayedPaymentPoint, err = randPubKey() 351 if err != nil { 352 t.Fatalf("unable to generate key: %v", err) 353 return 354 } 355 req.HtlcPoint, err = randPubKey() 356 if err != nil { 357 t.Fatalf("unable to generate key: %v", err) 358 return 359 } 360 req.FirstCommitmentPoint, err = randPubKey() 361 if err != nil { 362 t.Fatalf("unable to generate key: %v", err) 363 return 364 } 365 366 // 1/2 chance empty TLV records. 367 if r.Intn(2) == 0 { 368 req.UpfrontShutdownScript, err = randDeliveryAddress(r) 369 if err != nil { 370 t.Fatalf("unable to generate delivery address: %v", err) 371 return 372 } 373 374 req.ChannelType = new(ChannelType) 375 *req.ChannelType = ChannelType(*randRawFeatureVector(r)) 376 377 req.LeaseExpiry = new(LeaseExpiry) 378 *req.LeaseExpiry = LeaseExpiry(1337) 379 } else { 380 req.UpfrontShutdownScript = []byte{} 381 } 382 383 // 1/2 chance additional TLV data. 384 if r.Intn(2) == 0 { 385 req.ExtraData = []byte{0xfd, 0x00, 0xff, 0x00} 386 } 387 388 v[0] = reflect.ValueOf(req) 389 }, 390 MsgAcceptChannel: func(v []reflect.Value, r *rand.Rand) { 391 req := AcceptChannel{ 392 DustLimit: dcrutil.Amount(r.Int63()), 393 MaxValueInFlight: MilliAtom(r.Int63()), 394 ChannelReserve: dcrutil.Amount(r.Int63()), 395 MinAcceptDepth: uint32(r.Int31()), 396 HtlcMinimum: MilliAtom(r.Int31()), 397 CsvDelay: uint16(r.Int31()), 398 MaxAcceptedHTLCs: uint16(r.Int31()), 399 } 400 401 if _, err := r.Read(req.PendingChannelID[:]); err != nil { 402 t.Fatalf("unable to generate pending chan id: %v", err) 403 return 404 } 405 406 var err error 407 req.FundingKey, err = randPubKey() 408 if err != nil { 409 t.Fatalf("unable to generate key: %v", err) 410 return 411 } 412 req.RevocationPoint, err = randPubKey() 413 if err != nil { 414 t.Fatalf("unable to generate key: %v", err) 415 return 416 } 417 req.PaymentPoint, err = randPubKey() 418 if err != nil { 419 t.Fatalf("unable to generate key: %v", err) 420 return 421 } 422 req.DelayedPaymentPoint, err = randPubKey() 423 if err != nil { 424 t.Fatalf("unable to generate key: %v", err) 425 return 426 } 427 req.HtlcPoint, err = randPubKey() 428 if err != nil { 429 t.Fatalf("unable to generate key: %v", err) 430 return 431 } 432 req.FirstCommitmentPoint, err = randPubKey() 433 if err != nil { 434 t.Fatalf("unable to generate key: %v", err) 435 return 436 } 437 438 // 1/2 chance empty TLV records. 439 if r.Intn(2) == 0 { 440 req.UpfrontShutdownScript, err = randDeliveryAddress(r) 441 if err != nil { 442 t.Fatalf("unable to generate delivery address: %v", err) 443 return 444 } 445 446 req.ChannelType = new(ChannelType) 447 *req.ChannelType = ChannelType(*randRawFeatureVector(r)) 448 449 req.LeaseExpiry = new(LeaseExpiry) 450 *req.LeaseExpiry = LeaseExpiry(1337) 451 } else { 452 req.UpfrontShutdownScript = []byte{} 453 } 454 455 // 1/2 chance additional TLV data. 456 if r.Intn(2) == 0 { 457 req.ExtraData = []byte{0xfd, 0x00, 0xff, 0x00} 458 } 459 460 v[0] = reflect.ValueOf(req) 461 }, 462 MsgFundingCreated: func(v []reflect.Value, r *rand.Rand) { 463 req := FundingCreated{ 464 ExtraData: make([]byte, 0), 465 } 466 467 if _, err := r.Read(req.PendingChannelID[:]); err != nil { 468 t.Fatalf("unable to generate pending chan id: %v", err) 469 return 470 } 471 472 if _, err := r.Read(req.FundingPoint.Hash[:]); err != nil { 473 t.Fatalf("unable to generate hash: %v", err) 474 return 475 } 476 req.FundingPoint.Index = uint32(r.Int31()) % math.MaxUint16 477 478 var err error 479 req.CommitSig, err = NewSigFromSignature(testSig) 480 if err != nil { 481 t.Fatalf("unable to parse sig: %v", err) 482 return 483 } 484 485 v[0] = reflect.ValueOf(req) 486 }, 487 MsgFundingSigned: func(v []reflect.Value, r *rand.Rand) { 488 var c [32]byte 489 _, err := r.Read(c[:]) 490 if err != nil { 491 t.Fatalf("unable to generate chan id: %v", err) 492 return 493 } 494 495 req := FundingSigned{ 496 ChanID: ChannelID(c), 497 ExtraData: make([]byte, 0), 498 } 499 req.CommitSig, err = NewSigFromSignature(testSig) 500 if err != nil { 501 t.Fatalf("unable to parse sig: %v", err) 502 return 503 } 504 505 v[0] = reflect.ValueOf(req) 506 }, 507 MsgFundingLocked: func(v []reflect.Value, r *rand.Rand) { 508 509 var c [32]byte 510 if _, err := r.Read(c[:]); err != nil { 511 t.Fatalf("unable to generate chan id: %v", err) 512 return 513 } 514 515 pubKey, err := randPubKey() 516 if err != nil { 517 t.Fatalf("unable to generate key: %v", err) 518 return 519 } 520 521 req := NewFundingLocked(ChannelID(c), pubKey) 522 523 v[0] = reflect.ValueOf(*req) 524 }, 525 MsgClosingSigned: func(v []reflect.Value, r *rand.Rand) { 526 req := ClosingSigned{ 527 FeeAtoms: dcrutil.Amount(r.Int63()), 528 ExtraData: make([]byte, 0), 529 } 530 var err error 531 req.Signature, err = NewSigFromSignature(testSig) 532 if err != nil { 533 t.Fatalf("unable to parse sig: %v", err) 534 return 535 } 536 537 if _, err := r.Read(req.ChannelID[:]); err != nil { 538 t.Fatalf("unable to generate chan id: %v", err) 539 return 540 } 541 542 v[0] = reflect.ValueOf(req) 543 }, 544 MsgCommitSig: func(v []reflect.Value, r *rand.Rand) { 545 req := NewCommitSig() 546 if _, err := r.Read(req.ChanID[:]); err != nil { 547 t.Fatalf("unable to generate chan id: %v", err) 548 return 549 } 550 551 var err error 552 req.CommitSig, err = NewSigFromSignature(testSig) 553 if err != nil { 554 t.Fatalf("unable to parse sig: %v", err) 555 return 556 } 557 558 // Only create the slice if there will be any signatures 559 // in it to prevent false positive test failures due to 560 // an empty slice versus a nil slice. 561 numSigs := uint16(r.Int31n(1020)) 562 if numSigs > 0 { 563 req.HtlcSigs = make([]Sig, numSigs) 564 } 565 for i := 0; i < int(numSigs); i++ { 566 req.HtlcSigs[i], err = NewSigFromSignature(testSig) 567 if err != nil { 568 t.Fatalf("unable to parse sig: %v", err) 569 return 570 } 571 } 572 573 v[0] = reflect.ValueOf(*req) 574 }, 575 MsgRevokeAndAck: func(v []reflect.Value, r *rand.Rand) { 576 req := NewRevokeAndAck() 577 if _, err := r.Read(req.ChanID[:]); err != nil { 578 t.Fatalf("unable to generate chan id: %v", err) 579 return 580 } 581 if _, err := r.Read(req.Revocation[:]); err != nil { 582 t.Fatalf("unable to generate bytes: %v", err) 583 return 584 } 585 var err error 586 req.NextRevocationKey, err = randPubKey() 587 if err != nil { 588 t.Fatalf("unable to generate key: %v", err) 589 return 590 } 591 592 v[0] = reflect.ValueOf(*req) 593 }, 594 MsgChannelAnnouncement: func(v []reflect.Value, r *rand.Rand) { 595 var err error 596 req := ChannelAnnouncement{ 597 ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), 598 Features: randRawFeatureVector(r), 599 ExtraOpaqueData: make([]byte, 0), 600 } 601 req.NodeSig1, err = NewSigFromSignature(testSig) 602 if err != nil { 603 t.Fatalf("unable to parse sig: %v", err) 604 return 605 } 606 req.NodeSig2, err = NewSigFromSignature(testSig) 607 if err != nil { 608 t.Fatalf("unable to parse sig: %v", err) 609 return 610 } 611 req.DecredSig1, err = NewSigFromSignature(testSig) 612 if err != nil { 613 t.Fatalf("unable to parse sig: %v", err) 614 return 615 } 616 req.DecredSig2, err = NewSigFromSignature(testSig) 617 if err != nil { 618 t.Fatalf("unable to parse sig: %v", err) 619 return 620 } 621 622 req.NodeID1, err = randRawKey() 623 if err != nil { 624 t.Fatalf("unable to generate key: %v", err) 625 return 626 } 627 req.NodeID2, err = randRawKey() 628 if err != nil { 629 t.Fatalf("unable to generate key: %v", err) 630 return 631 } 632 req.DecredKey1, err = randRawKey() 633 if err != nil { 634 t.Fatalf("unable to generate key: %v", err) 635 return 636 } 637 req.DecredKey2, err = randRawKey() 638 if err != nil { 639 t.Fatalf("unable to generate key: %v", err) 640 return 641 } 642 if _, err := r.Read(req.ChainHash[:]); err != nil { 643 t.Fatalf("unable to generate chain hash: %v", err) 644 return 645 } 646 647 numExtraBytes := r.Int31n(1000) 648 if numExtraBytes > 0 { 649 req.ExtraOpaqueData = make([]byte, numExtraBytes) 650 _, err := r.Read(req.ExtraOpaqueData) 651 if err != nil { 652 t.Fatalf("unable to generate opaque "+ 653 "bytes: %v", err) 654 return 655 } 656 } 657 658 v[0] = reflect.ValueOf(req) 659 }, 660 MsgNodeAnnouncement: func(v []reflect.Value, r *rand.Rand) { 661 var err error 662 req := NodeAnnouncement{ 663 Features: randRawFeatureVector(r), 664 Timestamp: uint32(r.Int31()), 665 Alias: randAlias(r), 666 RGBColor: color.RGBA{ 667 R: uint8(r.Int31()), 668 G: uint8(r.Int31()), 669 B: uint8(r.Int31()), 670 }, 671 ExtraOpaqueData: make([]byte, 0), 672 } 673 req.Signature, err = NewSigFromSignature(testSig) 674 if err != nil { 675 t.Fatalf("unable to parse sig: %v", err) 676 return 677 } 678 679 req.NodeID, err = randRawKey() 680 if err != nil { 681 t.Fatalf("unable to generate key: %v", err) 682 return 683 } 684 685 req.Addresses, err = randAddrs(r) 686 if err != nil { 687 t.Fatalf("unable to generate addresses: %v", err) 688 } 689 690 numExtraBytes := r.Int31n(1000) 691 if numExtraBytes > 0 { 692 req.ExtraOpaqueData = make([]byte, numExtraBytes) 693 _, err := r.Read(req.ExtraOpaqueData) 694 if err != nil { 695 t.Fatalf("unable to generate opaque "+ 696 "bytes: %v", err) 697 return 698 } 699 } 700 701 v[0] = reflect.ValueOf(req) 702 }, 703 MsgChannelUpdate: func(v []reflect.Value, r *rand.Rand) { 704 var err error 705 706 msgFlags := ChanUpdateMsgFlags(r.Int31()) 707 maxHtlc := MilliAtom(r.Int63()) 708 709 // We make the max_htlc field zero if it is not flagged 710 // as being part of the ChannelUpdate, to pass 711 // serialization tests, as it will be ignored if the bit 712 // is not set. 713 if msgFlags&ChanUpdateOptionMaxHtlc == 0 { 714 maxHtlc = 0 715 } 716 717 req := ChannelUpdate{ 718 ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), 719 Timestamp: uint32(r.Int31()), 720 MessageFlags: msgFlags, 721 ChannelFlags: ChanUpdateChanFlags(r.Int31()), 722 TimeLockDelta: uint16(r.Int31()), 723 HtlcMinimumMAtoms: MilliAtom(r.Int63()), 724 HtlcMaximumMAtoms: maxHtlc, 725 BaseFee: uint32(r.Int31()), 726 FeeRate: uint32(r.Int31()), 727 ExtraOpaqueData: make([]byte, 0), 728 } 729 req.Signature, err = NewSigFromSignature(testSig) 730 if err != nil { 731 t.Fatalf("unable to parse sig: %v", err) 732 return 733 } 734 735 if _, err := r.Read(req.ChainHash[:]); err != nil { 736 t.Fatalf("unable to generate chain hash: %v", err) 737 return 738 } 739 740 numExtraBytes := r.Int31n(1000) 741 if numExtraBytes > 0 { 742 req.ExtraOpaqueData = make([]byte, numExtraBytes) 743 _, err := r.Read(req.ExtraOpaqueData) 744 if err != nil { 745 t.Fatalf("unable to generate opaque "+ 746 "bytes: %v", err) 747 return 748 } 749 } 750 751 v[0] = reflect.ValueOf(req) 752 }, 753 MsgAnnounceSignatures: func(v []reflect.Value, r *rand.Rand) { 754 var err error 755 req := AnnounceSignatures{ 756 ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), 757 ExtraOpaqueData: make([]byte, 0), 758 } 759 760 req.NodeSignature, err = NewSigFromSignature(testSig) 761 if err != nil { 762 t.Fatalf("unable to parse sig: %v", err) 763 return 764 } 765 766 req.DecredSignature, err = NewSigFromSignature(testSig) 767 if err != nil { 768 t.Fatalf("unable to parse sig: %v", err) 769 return 770 } 771 772 if _, err := r.Read(req.ChannelID[:]); err != nil { 773 t.Fatalf("unable to generate chan id: %v", err) 774 return 775 } 776 777 numExtraBytes := r.Int31n(1000) 778 if numExtraBytes > 0 { 779 req.ExtraOpaqueData = make([]byte, numExtraBytes) 780 _, err := r.Read(req.ExtraOpaqueData) 781 if err != nil { 782 t.Fatalf("unable to generate opaque "+ 783 "bytes: %v", err) 784 return 785 } 786 } 787 788 v[0] = reflect.ValueOf(req) 789 }, 790 MsgChannelReestablish: func(v []reflect.Value, r *rand.Rand) { 791 req := ChannelReestablish{ 792 NextLocalCommitHeight: uint64(r.Int63()), 793 RemoteCommitTailHeight: uint64(r.Int63()), 794 ExtraData: make([]byte, 0), 795 } 796 797 // With a 50/50 probability, we'll include the 798 // additional fields so we can test our ability to 799 // properly parse, and write out the optional fields. 800 if r.Int()%2 == 0 { 801 _, err := r.Read(req.LastRemoteCommitSecret[:]) 802 if err != nil { 803 t.Fatalf("unable to read commit secret: %v", err) 804 return 805 } 806 807 req.LocalUnrevokedCommitPoint, err = randPubKey() 808 if err != nil { 809 t.Fatalf("unable to generate key: %v", err) 810 return 811 } 812 } 813 814 v[0] = reflect.ValueOf(req) 815 }, 816 MsgQueryShortChanIDs: func(v []reflect.Value, r *rand.Rand) { 817 req := QueryShortChanIDs{ 818 ExtraData: make([]byte, 0), 819 } 820 821 // With a 50/50 change, we'll either use zlib encoding, 822 // or regular encoding. 823 if r.Int31()%2 == 0 { 824 req.EncodingType = EncodingSortedZlib 825 } else { 826 req.EncodingType = EncodingSortedPlain 827 } 828 829 if _, err := rand.Read(req.ChainHash[:]); err != nil { 830 t.Fatalf("unable to read chain hash: %v", err) 831 return 832 } 833 834 numChanIDs := rand.Int31n(5000) 835 for i := int32(0); i < numChanIDs; i++ { 836 req.ShortChanIDs = append(req.ShortChanIDs, 837 NewShortChanIDFromInt(uint64(r.Int63()))) 838 } 839 840 v[0] = reflect.ValueOf(req) 841 }, 842 MsgReplyChannelRange: func(v []reflect.Value, r *rand.Rand) { 843 req := ReplyChannelRange{ 844 FirstBlockHeight: uint32(r.Int31()), 845 NumBlocks: uint32(r.Int31()), 846 ExtraData: make([]byte, 0), 847 } 848 849 if _, err := rand.Read(req.ChainHash[:]); err != nil { 850 t.Fatalf("unable to read chain hash: %v", err) 851 return 852 } 853 854 req.Complete = uint8(r.Int31n(2)) 855 856 // With a 50/50 change, we'll either use zlib encoding, 857 // or regular encoding. 858 if r.Int31()%2 == 0 { 859 req.EncodingType = EncodingSortedZlib 860 } else { 861 req.EncodingType = EncodingSortedPlain 862 } 863 864 numChanIDs := rand.Int31n(5000) 865 for i := int32(0); i < numChanIDs; i++ { 866 req.ShortChanIDs = append(req.ShortChanIDs, 867 NewShortChanIDFromInt(uint64(r.Int63()))) 868 } 869 870 v[0] = reflect.ValueOf(req) 871 }, 872 MsgPing: func(v []reflect.Value, r *rand.Rand) { 873 // We use a special message generator here to ensure we 874 // don't generate ping messages that are too large, 875 // which'll cause the test to fail. 876 // 877 // We'll allow the test to generate padding bytes up to 878 // the max message limit, factoring in the 2 bytes for 879 // the num pong bytes. 880 paddingBytes := make([]byte, r.Intn(MaxMsgBody-1)) 881 req := Ping{ 882 NumPongBytes: uint16(r.Intn(MaxPongBytes + 1)), 883 PaddingBytes: paddingBytes, 884 } 885 886 v[0] = reflect.ValueOf(req) 887 }, 888 } 889 890 // With the above types defined, we'll now generate a slice of 891 // scenarios to feed into quick.Check. The function scans in input 892 // space of the target function under test, so we'll need to create a 893 // series of wrapper functions to force it to iterate over the target 894 // types, but re-use the mainScenario defined above. 895 tests := []struct { 896 msgType MessageType 897 scenario interface{} 898 }{ 899 { 900 msgType: MsgInit, 901 scenario: func(m Init) bool { 902 return mainScenario(&m) 903 }, 904 }, 905 { 906 msgType: MsgError, 907 scenario: func(m Error) bool { 908 return mainScenario(&m) 909 }, 910 }, 911 { 912 msgType: MsgPing, 913 scenario: func(m Ping) bool { 914 return mainScenario(&m) 915 }, 916 }, 917 { 918 msgType: MsgPong, 919 scenario: func(m Pong) bool { 920 return mainScenario(&m) 921 }, 922 }, 923 { 924 msgType: MsgOpenChannel, 925 scenario: func(m OpenChannel) bool { 926 return mainScenario(&m) 927 }, 928 }, 929 { 930 msgType: MsgAcceptChannel, 931 scenario: func(m AcceptChannel) bool { 932 return mainScenario(&m) 933 }, 934 }, 935 { 936 msgType: MsgFundingCreated, 937 scenario: func(m FundingCreated) bool { 938 return mainScenario(&m) 939 }, 940 }, 941 { 942 msgType: MsgFundingSigned, 943 scenario: func(m FundingSigned) bool { 944 return mainScenario(&m) 945 }, 946 }, 947 { 948 msgType: MsgFundingLocked, 949 scenario: func(m FundingLocked) bool { 950 return mainScenario(&m) 951 }, 952 }, 953 { 954 msgType: MsgShutdown, 955 scenario: func(m Shutdown) bool { 956 return mainScenario(&m) 957 }, 958 }, 959 { 960 msgType: MsgClosingSigned, 961 scenario: func(m ClosingSigned) bool { 962 return mainScenario(&m) 963 }, 964 }, 965 { 966 msgType: MsgUpdateAddHTLC, 967 scenario: func(m UpdateAddHTLC) bool { 968 return mainScenario(&m) 969 }, 970 }, 971 { 972 msgType: MsgUpdateFulfillHTLC, 973 scenario: func(m UpdateFulfillHTLC) bool { 974 return mainScenario(&m) 975 }, 976 }, 977 { 978 msgType: MsgUpdateFailHTLC, 979 scenario: func(m UpdateFailHTLC) bool { 980 return mainScenario(&m) 981 }, 982 }, 983 { 984 msgType: MsgCommitSig, 985 scenario: func(m CommitSig) bool { 986 return mainScenario(&m) 987 }, 988 }, 989 { 990 msgType: MsgRevokeAndAck, 991 scenario: func(m RevokeAndAck) bool { 992 return mainScenario(&m) 993 }, 994 }, 995 { 996 msgType: MsgUpdateFee, 997 scenario: func(m UpdateFee) bool { 998 return mainScenario(&m) 999 }, 1000 }, 1001 { 1002 1003 msgType: MsgUpdateFailMalformedHTLC, 1004 scenario: func(m UpdateFailMalformedHTLC) bool { 1005 return mainScenario(&m) 1006 }, 1007 }, 1008 { 1009 msgType: MsgChannelReestablish, 1010 scenario: func(m ChannelReestablish) bool { 1011 return mainScenario(&m) 1012 }, 1013 }, 1014 { 1015 msgType: MsgChannelAnnouncement, 1016 scenario: func(m ChannelAnnouncement) bool { 1017 return mainScenario(&m) 1018 }, 1019 }, 1020 { 1021 msgType: MsgNodeAnnouncement, 1022 scenario: func(m NodeAnnouncement) bool { 1023 return mainScenario(&m) 1024 }, 1025 }, 1026 { 1027 msgType: MsgChannelUpdate, 1028 scenario: func(m ChannelUpdate) bool { 1029 return mainScenario(&m) 1030 }, 1031 }, 1032 { 1033 msgType: MsgAnnounceSignatures, 1034 scenario: func(m AnnounceSignatures) bool { 1035 return mainScenario(&m) 1036 }, 1037 }, 1038 { 1039 msgType: MsgGossipTimestampRange, 1040 scenario: func(m GossipTimestampRange) bool { 1041 return mainScenario(&m) 1042 }, 1043 }, 1044 { 1045 msgType: MsgQueryShortChanIDs, 1046 scenario: func(m QueryShortChanIDs) bool { 1047 return mainScenario(&m) 1048 }, 1049 }, 1050 { 1051 msgType: MsgReplyShortChanIDsEnd, 1052 scenario: func(m ReplyShortChanIDsEnd) bool { 1053 return mainScenario(&m) 1054 }, 1055 }, 1056 { 1057 msgType: MsgQueryChannelRange, 1058 scenario: func(m QueryChannelRange) bool { 1059 return mainScenario(&m) 1060 }, 1061 }, 1062 { 1063 msgType: MsgReplyChannelRange, 1064 scenario: func(m ReplyChannelRange) bool { 1065 return mainScenario(&m) 1066 }, 1067 }, 1068 } 1069 for _, test := range tests { 1070 var config *quick.Config 1071 1072 // If the type defined is within the custom type gen map above, 1073 // then we'll modify the default config to use this Value 1074 // function that knows how to generate the proper types. 1075 if valueGen, ok := customTypeGen[test.msgType]; ok { 1076 config = &quick.Config{ 1077 Values: valueGen, 1078 } 1079 } 1080 1081 t.Logf("Running fuzz tests for msgType=%v", test.msgType) 1082 if err := quick.Check(test.scenario, config); err != nil { 1083 t.Fatalf("fuzz checks for msg=%v failed: %v", 1084 test.msgType, err) 1085 } 1086 } 1087 1088 } 1089 1090 func init() { 1091 rand.Seed(time.Now().Unix()) 1092 }