diff --git a/lnwire/announcement_signatures_test.go b/lnwire/announcement_signatures_test.go deleted file mode 100644 index 3b1ac4da..00000000 --- a/lnwire/announcement_signatures_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestAnnounceSignatureEncodeDecode(t *testing.T) { - ac := &AnnounceSignatures{ - ChannelID: ChannelID(revHash), - ShortChannelID: NewShortChanIDFromInt(1), - NodeSignature: someSig, - BitcoinSignature: someSig, - } - - // Next encode the message into an empty bytes buffer. - var b bytes.Buffer - if err := ac.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode AnnounceSignatures: %v", err) - } - - // Deserialize the encoded message into a new empty struct. - ac2 := &AnnounceSignatures{} - if err := ac2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode AnnounceSignatures: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(ac, ac2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - ac, ac2) - } -} diff --git a/lnwire/channel_announcement_test.go b/lnwire/channel_announcement_test.go deleted file mode 100644 index 9244f8f0..00000000 --- a/lnwire/channel_announcement_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" - - "github.com/roasbeef/btcd/btcec" - "github.com/roasbeef/btcd/chaincfg/chainhash" -) - -func TestChannelAnnoucementEncodeDecode(t *testing.T) { - ca := &ChannelAnnouncement{ - NodeSig1: someSig, - NodeSig2: someSig, - ShortChannelID: someShortChannelID, - BitcoinSig1: someSig, - BitcoinSig2: someSig, - NodeID1: pubKey, - NodeID2: pubKey, - BitcoinKey1: pubKey, - BitcoinKey2: pubKey, - } - - // Next encode the CA message into an empty bytes buffer. - var b bytes.Buffer - if err := ca.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode ChannelAnnouncement: %v", err) - } - - // Ensure the max payload estimate is correct. - serializedLength := uint32(b.Len()) - if serializedLength != ca.MaxPayloadLength(0) { - t.Fatalf("payload length estimate is incorrect: expected %v "+ - "got %v", serializedLength, ca.MaxPayloadLength(0)) - } - - // Deserialize the encoded CA message into a new empty struct. - ca2 := &ChannelAnnouncement{} - if err := ca2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode ChannelAnnouncement: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(ca, ca2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - ca, ca2) - } -} - -func TestChannelAnnoucementValidation(t *testing.T) { - getKeys := func(s string) (*btcec.PrivateKey, *btcec.PublicKey) { - return btcec.PrivKeyFromBytes(btcec.S256(), []byte(s)) - } - - firstNodePrivKey, firstNodePubKey := getKeys("node-id-1") - secondNodePrivKey, secondNodePubKey := getKeys("node-id-2") - firstBitcoinPrivKey, firstBitcoinPubKey := getKeys("bitcoin-key-1") - secondBitcoinPrivKey, secondBitcoinPubKey := getKeys("bitcoin-key-2") - - hash := chainhash.DoubleHashB(firstNodePubKey.SerializeCompressed()) - firstBitcoinSig, _ := firstBitcoinPrivKey.Sign(hash) - - hash = chainhash.DoubleHashB(secondNodePubKey.SerializeCompressed()) - secondBitcoinSig, _ := secondBitcoinPrivKey.Sign(hash) - - ca := &ChannelAnnouncement{ - ShortChannelID: someShortChannelID, - BitcoinSig1: firstBitcoinSig, - BitcoinSig2: secondBitcoinSig, - NodeID1: firstNodePubKey, - NodeID2: secondNodePubKey, - BitcoinKey1: firstBitcoinPubKey, - BitcoinKey2: secondBitcoinPubKey, - } - - dataToSign, _ := ca.DataToSign() - hash = chainhash.DoubleHashB(dataToSign) - - firstNodeSign, _ := firstNodePrivKey.Sign(hash) - ca.NodeSig1 = firstNodeSign - - secondNodeSign, _ := secondNodePrivKey.Sign(hash) - ca.NodeSig2 = secondNodeSign - - if err := ca.Validate(); err != nil { - t.Fatal(err) - } -} diff --git a/lnwire/channel_update_test.go b/lnwire/channel_update_test.go deleted file mode 100644 index 51b16c0b..00000000 --- a/lnwire/channel_update_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestChannelUpdateEncodeDecode(t *testing.T) { - cua := &ChannelUpdate{ - Signature: someSig, - ShortChannelID: someShortChannelID, - Timestamp: maxUint32, - Flags: maxUint16, - TimeLockDelta: maxUint16, - HtlcMinimumMsat: maxUint32, - FeeBaseMsat: maxUint32, - FeeProportionalMillionths: maxUint32, - } - - // Next encode the CUA message into an empty bytes buffer. - var b bytes.Buffer - if err := cua.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode ChannelUpdate: %v", err) - } - - // Ensure the max payload estimate is correct. - serializedLength := uint32(b.Len()) - if serializedLength != cua.MaxPayloadLength(0) { - t.Fatalf("payload length estimate is incorrect: expected %v "+ - "got %v", serializedLength, cua.MaxPayloadLength(0)) - } - - // Deserialize the encoded CUA message into a new empty struct. - cua2 := &ChannelUpdate{} - if err := cua2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode ChannelUpdateAnnouncement: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(cua, cua2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - cua, cua2) - } -} diff --git a/lnwire/close_complete.go b/lnwire/close_complete.go index 653180ae..2841767c 100644 --- a/lnwire/close_complete.go +++ b/lnwire/close_complete.go @@ -26,12 +26,6 @@ type CloseComplete struct { ResponderCloseSig *btcec.Signature } -// NewCloseComplete creates a new empty CloseComplete message. -// TODO(roasbeef): add params to all constructors... -func NewCloseComplete() *CloseComplete { - return &CloseComplete{} -} - // A compile time check to ensure CloseComplete implements the lnwire.Message // interface. var _ Message = (*CloseComplete)(nil) diff --git a/lnwire/close_complete_test.go b/lnwire/close_complete_test.go deleted file mode 100644 index 1ab67d3b..00000000 --- a/lnwire/close_complete_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestCloseCompleteEncodeDecode(t *testing.T) { - cc := &CloseComplete{ - ChannelPoint: *outpoint1, - ResponderCloseSig: commitSig, - } - - // Next encode the CC message into an empty bytes buffer. - var b bytes.Buffer - if err := cc.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode CloseComplete: %v", err) - } - - // Deserialize the encoded CC message into a new empty struct. - cc2 := &CloseComplete{} - if err := cc2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode CloseComplete: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(cc, cc2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - cc, cc2) - } -} diff --git a/lnwire/close_request_test.go b/lnwire/close_request_test.go deleted file mode 100644 index a7184afc..00000000 --- a/lnwire/close_request_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" - - "github.com/roasbeef/btcutil" -) - -func TestCloseRequestEncodeDecode(t *testing.T) { - cr := &CloseRequest{ - ChanID: ChannelID(revHash), - RequesterCloseSig: commitSig, - Fee: btcutil.Amount(10000), - } - - // Next encode the CR message into an empty bytes buffer. - var b bytes.Buffer - if err := cr.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode CloseRequest: %v", err) - } - - // Deserialize the encoded CR message into a new empty struct. - cr2 := &CloseRequest{} - if err := cr2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode CloseRequest: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(cr, cr2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - cr, cr2) - } -} diff --git a/lnwire/commit_sig_test.go b/lnwire/commit_sig_test.go deleted file mode 100644 index c59a0f4b..00000000 --- a/lnwire/commit_sig_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestCommitSigEncodeDecode(t *testing.T) { - commitSignature := &CommitSig{ - ChanID: ChannelID(revHash), - CommitSig: commitSig, - } - - // Next encode the CS message into an empty bytes buffer. - var b bytes.Buffer - if err := commitSignature.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode CommitSig: %v", err) - } - - // Deserialize the encoded EG message into a new empty struct. - commitSignature2 := &CommitSig{} - if err := commitSignature2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode CommitSig: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(commitSignature, commitSignature2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - commitSignature, commitSignature2) - } -} diff --git a/lnwire/error_test.go b/lnwire/error_test.go deleted file mode 100644 index 57251268..00000000 --- a/lnwire/error_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestErrorEncodeDecode(t *testing.T) { - eg := &Error{ - ChanID: ChannelID(revHash), - Code: 99, - Data: []byte{'k', 'e', 'k'}, - } - - // Next encode the error message into an empty bytes buffer. - var b bytes.Buffer - if err := eg.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode ErrorGeneric: %v", err) - } - - // Deserialize the encoded error message into a new empty struct. - eg2 := &Error{} - if err := eg2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode ErrorGeneric: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(eg, eg2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - eg, eg2) - } -} diff --git a/lnwire/features_test.go b/lnwire/features_test.go index 4aec59d1..0fba1890 100644 --- a/lnwire/features_test.go +++ b/lnwire/features_test.go @@ -72,6 +72,11 @@ func TestOptionalFeature(t *testing.T) { t.Fatal("locally feature was set but remote peer notified us" + " that it don't have it") } + + // A feature with a non-existent name shouldn't be active. + if shared.IsActive("nothere") { + t.Fatal("non-existent feature shouldn't be active") + } } // TestSetRequireAfterInit checks that we can change the feature flag after @@ -117,3 +122,21 @@ func TestDecodeEncodeFeaturesVector(t *testing.T) { "%v", spew.Sdump(f), spew.Sdump(nf)) } } + +func TestFeatureFlagString(t *testing.T) { + if OptionalFlag.String() != "optional" { + t.Fatalf("incorrect string, expected optional got %v", + OptionalFlag.String()) + } + + if RequiredFlag.String() != "required" { + t.Fatalf("incorrect string, expected required got %v", + OptionalFlag.String()) + } + + fakeFlag := featureFlag(9) + if fakeFlag.String() != "" { + t.Fatalf("incorrect string, expected got %v", + fakeFlag.String()) + } +} diff --git a/lnwire/funding_locked_test.go b/lnwire/funding_locked_test.go deleted file mode 100644 index 45d69d01..00000000 --- a/lnwire/funding_locked_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestFundingLockedWire(t *testing.T) { - // First create a new FundingLocked message. - fl := NewFundingLocked(ChannelID(revHash), pubKey) - - // Next encode the FundingLocked message into an empty bytes buffer. - var b bytes.Buffer - if err := fl.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode FundingLocked: %v", err) - } - - // Check to ensure that the FundingLocked message is the correct size. - if uint32(b.Len()) > fl.MaxPayloadLength(0) { - t.Fatalf("length of FundingLocked message is too long: %v should be less than %v", - b.Len(), fl.MaxPayloadLength(0)) - } - - // Deserialize the encoded FundingLocked message into an empty struct. - fl2 := &FundingLocked{} - if err := fl2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode FundingLocked: %v", err) - } - - // Assert equality of the two instances - if !reflect.DeepEqual(fl, fl2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", fl, fl2) - } -} diff --git a/lnwire/init_test.go b/lnwire/init_test.go deleted file mode 100644 index 23b3fbc6..00000000 --- a/lnwire/init_test.go +++ /dev/null @@ -1,47 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestInitEncodeDecode(t *testing.T) { - const somefeature = "somefeature" - - gf := NewFeatureVector([]Feature{ - {somefeature, OptionalFlag}, - }) - lf := NewFeatureVector([]Feature{ - {somefeature, OptionalFlag}, - }) - - init1 := &Init{ - GlobalFeatures: gf, - LocalFeatures: lf, - } - - // Next encode the init message into an empty bytes buffer. - var b bytes.Buffer - if err := init1.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode init: %v", err) - } - - // Deserialize the encoded init message into a new empty struct. - init2 := &Init{} - if err := init2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode init: %v", err) - } - - // We not encode the feature map in feature vector, for that reason the - // init messages will differ. Set feature map with nil in - // order to use deep equal function. - init1.GlobalFeatures.featuresMap = nil - init1.LocalFeatures.featuresMap = nil - - // Assert equality of the two instances. - if !reflect.DeepEqual(init1, init2) { - t.Fatalf("encode/decode init messages don't match %#v vs %#v", - init1, init2) - } -} diff --git a/lnwire/lnwire_test.go b/lnwire/lnwire_test.go index 0f2fbedd..b9e2415a 100644 --- a/lnwire/lnwire_test.go +++ b/lnwire/lnwire_test.go @@ -1,16 +1,22 @@ package lnwire import ( + "bytes" "encoding/hex" + "math" + "math/big" + "math/rand" "net" + "reflect" + "testing" + "testing/quick" "github.com/roasbeef/btcd/btcec" "github.com/roasbeef/btcd/chaincfg/chainhash" - "github.com/roasbeef/btcd/txscript" "github.com/roasbeef/btcd/wire" + "github.com/roasbeef/btcutil" ) -// Common variables and functions for the message tests var ( revHash = [32]byte{ 0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab, @@ -22,62 +28,551 @@ var ( shaHash1Bytes, _ = hex.DecodeString("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") shaHash1, _ = chainhash.NewHash(shaHash1Bytes) outpoint1 = wire.NewOutPoint(shaHash1, 0) - - privKeyBytes, _ = hex.DecodeString("9fa1d55217f57019a3c37f49465896b15836f54cb8ef6963870a52926420a2dd") - privKey, pubKey = btcec.PrivKeyFromBytes(btcec.S256(), privKeyBytes) - address = pubKey - - // Commitment Signature - tx = wire.NewMsgTx(1) - emptybytes = new([]byte) - sigStr, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, privKey) - commitSig, _ = btcec.ParseSignature(sigStr, btcec.S256()) - - sig1privKeyBytes, _ = hex.DecodeString("927f5827d75dd2addeb532c0fa5ac9277565f981dd6d0d037b422be5f60bdbef") - sig1privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig1privKeyBytes) - sigStr1, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig1privKey) - commitSig1, _ = btcec.ParseSignature(sigStr1, btcec.S256()) - - // Funding TX Sig 2 - sig2privKeyBytes, _ = hex.DecodeString("8a4ad188f6f4000495b765cfb6ffa591133a73019c45428ddd28f53bab551847") - sig2privKey, _ = btcec.PrivKeyFromBytes(btcec.S256(), sig2privKeyBytes) - sigStr2, _ = txscript.RawTxInSignature(tx, 0, *emptybytes, txscript.SigHashAll, sig2privKey) - commitSig2, _ = btcec.ParseSignature(sigStr2, btcec.S256()) - // Slice of Funding TX Sigs - ptrFundingTXSigs = append(*new([]*btcec.Signature), commitSig1, commitSig2) - - // TxID - txid = new(chainhash.Hash) - // Reversed when displayed - txidBytes, _ = hex.DecodeString("fd95c6e5c9d5bcf9cfc7231b6a438e46c518c724d0b04b75cc8fddf84a254e3a") - _ = copy(txid[:], txidBytes) - - someAlias, _ = NewAlias("012345678901234567890") - someSig, _ = btcec.ParseSignature(sigStr, btcec.S256()) - someSigBytes = someSig.Serialize() - - someAddress = &net.TCPAddr{IP: (net.IP)([]byte{0x7f, 0x0, 0x0, 0x1}), Port: 8333} - someOtherAddress, _ = net.ResolveTCPAddr("tcp", "[2001:db8:85a3:0:0:8a2e:370:7334]:80") - someAddresses = []net.Addr{someAddress, someOtherAddress} - - maxUint32 uint32 = (1 << 32) - 1 - maxUint24 uint32 = (1 << 24) - 1 - maxUint16 uint16 = (1 << 16) - 1 - - someShortChannelID = ShortChannelID{ - BlockHeight: maxUint24, - TxIndex: maxUint24, - TxPosition: maxUint16, + testSig = &btcec.Signature{ + R: new(big.Int), + S: new(big.Int), } + _, _ = testSig.R.SetString("63724406601629180062774974542967536251589935445068131219452686511677818569431", 10) + _, _ = testSig.S.SetString("18801056069249825825291287104931333862866033135609736119018462340006816851118", 10) - someRGB = RGB{ - red: 255, - green: 255, - blue: 255, - } - - someFeature = featureName("somefeature") - someFeatures = NewFeatureVector([]Feature{ - {someFeature, OptionalFlag}, - }) + // TODO(roasbeef): randomly generate from three types of addrs + a1 = &net.TCPAddr{IP: (net.IP)([]byte{0x7f, 0x0, 0x0, 0x1}), Port: 8333} + a2, _ = net.ResolveTCPAddr("tcp", "[2001:db8:85a3:0:0:8a2e:370:7334]:80") + testAddrs = []net.Addr{a1, a2} ) + +func randPubKey() (*btcec.PublicKey, error) { + priv, err := btcec.NewPrivateKey(btcec.S256()) + if err != nil { + return nil, err + } + + return priv.PubKey(), nil +} + +func randFeatureVector(r *rand.Rand) *FeatureVector { + numFeatures := r.Int31n(131123) + features := make([]Feature, numFeatures) + for i := int32(0); i < numFeatures; i++ { + features[i] = Feature{ + Flag: featureFlag(rand.Int31n(2) + 1), + } + } + + return NewFeatureVector(features) +} + +func TestMaxOutPointIndex(t *testing.T) { + op := wire.OutPoint{ + Index: math.MaxUint32, + } + + var b bytes.Buffer + if err := writeElement(&b, op); err == nil { + t.Fatalf("write of outPoint should fail, index exceeds 16-bits") + } +} + +func TestEmptyMessageUnknownType(t *testing.T) { + fakeType := MessageType(math.MaxUint16) + if _, err := makeEmptyMessage(fakeType); err == nil { + t.Fatalf("should not be able to make an empty message of an " + + "unknown type") + } +} + +// TestLightningWireProtocol uses the testing/quick package to create a series +// of fuzz tests to attempt to break a primary scenario which is implemented as +// property based testing scenario. +func TestLightningWireProtocol(t *testing.T) { + // mainScenario is the primary test that will programmatically be + // executed for all registered wire messages. The quick-checker within + // testing/quick will attempt to find an input to this function, s.t + // the function returns false, if so then we've found an input that + // violates our model of the system. + mainScenario := func(msg Message) bool { + // Give a new message, we'll serialize the message into a new + // bytes buffer. + var b bytes.Buffer + if _, err := WriteMessage(&b, msg, 0); err != nil { + t.Fatalf("unable to write msg: %v", err) + return false + } + + // Next, we'll ensure that the serialized payload (subtracting + // the 2 bytes for the message type) is _below_ the specified + // max payload size for this message. + payloadLen := uint32(b.Len()) - 2 + if payloadLen > msg.MaxPayloadLength(0) { + t.Fatalf("msg payload constraint violated: %v > %v", + payloadLen, msg.MaxPayloadLength(0)) + return false + } + + // Finally, we'll deserialize the message from the written + // buffer, and finally assert that the messages are equal. + _, newMsg, err := ReadMessage(&b, 0) + if err != nil { + t.Fatalf("unable to read msg: %v", err) + return false + } + if !reflect.DeepEqual(msg, newMsg) { + t.Fatalf("messages don't match after re-encoding: %v "+ + "vs %v", msg, newMsg) + return false + } + + return true + } + + // customTypeGen is a map of functions that are able to randomly + // generate a given type. These functions are needed for types which + // are too complex for the testing/quick package to automatically + // generate. + customTypeGen := map[MessageType]func([]reflect.Value, *rand.Rand){ + MsgInit: func(v []reflect.Value, r *rand.Rand) { + req := NewInitMessage( + randFeatureVector(r), + randFeatureVector(r), + ) + req.GlobalFeatures.featuresMap = nil + req.LocalFeatures.featuresMap = nil + + v[0] = reflect.ValueOf(*req) + }, + MsgSingleFundingRequest: func(v []reflect.Value, r *rand.Rand) { + req := SingleFundingRequest{ + ChannelType: uint8(r.Int63()), + CoinType: uint64(r.Int63()), + FeePerKb: btcutil.Amount(r.Int63()), + FundingAmount: btcutil.Amount(r.Int63()), + PushSatoshis: btcutil.Amount(r.Int63()), + CsvDelay: uint32(r.Int31()), + DustLimit: btcutil.Amount(r.Int63()), + ConfirmationDepth: uint32(r.Int31()), + } + + if _, err := r.Read(req.PendingChannelID[:]); err != nil { + t.Fatalf("unable to generate pending chan id: %v", err) + return + } + var script [34]byte + if _, err := r.Read(script[:]); err != nil { + t.Fatalf("unable to generate pending chan id: %v", err) + return + } + req.DeliveryPkScript = script[:] + + var err error + req.ChannelDerivationPoint, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + req.CommitmentKey, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + + v[0] = reflect.ValueOf(req) + }, + MsgSingleFundingResponse: func(v []reflect.Value, r *rand.Rand) { + req := SingleFundingResponse{ + CsvDelay: uint32(r.Int31()), + DustLimit: btcutil.Amount(r.Int63()), + ConfirmationDepth: uint32(r.Int31()), + } + + if _, err := r.Read(req.PendingChannelID[:]); err != nil { + t.Fatalf("unable to generate pending chan id: %v", err) + return + } + var script [34]byte + if _, err := r.Read(script[:]); err != nil { + t.Fatalf("unable to generate pending chan id: %v", err) + return + } + req.DeliveryPkScript = script[:] + + var err error + req.ChannelDerivationPoint, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + req.CommitmentKey, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + req.RevocationKey, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + + v[0] = reflect.ValueOf(req) + }, + MsgSingleFundingComplete: func(v []reflect.Value, r *rand.Rand) { + req := SingleFundingComplete{} + + if _, err := r.Read(req.PendingChannelID[:]); err != nil { + t.Fatalf("unable to generate pending chan id: %v", err) + return + } + + if _, err := r.Read(req.FundingOutPoint.Hash[:]); err != nil { + t.Fatalf("unable to generate hash: %v", err) + return + } + req.FundingOutPoint.Index = uint32(r.Int31()) % math.MaxUint16 + + if _, err := r.Read(req.StateHintObsfucator[:]); err != nil { + t.Fatalf("unable to read state hint: %v", err) + return + } + + req.CommitSignature = testSig + + var err error + req.RevocationKey, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + + v[0] = reflect.ValueOf(req) + }, + MsgSingleFundingSignComplete: func(v []reflect.Value, r *rand.Rand) { + var c [32]byte + if _, err := r.Read(c[:]); err != nil { + t.Fatalf("unable to generate chan id: %v", err) + return + } + + req := NewSingleFundingSignComplete(ChannelID(c), testSig) + + v[0] = reflect.ValueOf(*req) + }, + MsgFundingLocked: func(v []reflect.Value, r *rand.Rand) { + + var c [32]byte + if _, err := r.Read(c[:]); err != nil { + t.Fatalf("unable to generate chan id: %v", err) + return + } + + pubKey, err := randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + + req := NewFundingLocked(ChannelID(c), pubKey) + + v[0] = reflect.ValueOf(*req) + }, + MsgCloseRequest: func(v []reflect.Value, r *rand.Rand) { + var chanID [32]byte + if _, err := r.Read(chanID[:]); err != nil { + t.Fatalf("unable to generate chan id: %v", err) + return + } + + req := NewCloseRequest(ChannelID(chanID), testSig) + req.Fee = btcutil.Amount(rand.Int63()) + + req.RequesterCloseSig = testSig + + v[0] = reflect.ValueOf(*req) + }, + MsgCloseComplete: func(v []reflect.Value, r *rand.Rand) { + req := CloseComplete{} + + if _, err := r.Read(req.ChannelPoint.Hash[:]); err != nil { + t.Fatalf("unable to generate hash: %v", err) + return + } + req.ChannelPoint.Index = uint32(r.Int31()) % math.MaxUint16 + + req.ResponderCloseSig = testSig + + v[0] = reflect.ValueOf(req) + }, + MsgCommitSig: func(v []reflect.Value, r *rand.Rand) { + req := NewCommitSig() + if _, err := r.Read(req.ChanID[:]); err != nil { + t.Fatalf("unable to generate chan id: %v", err) + return + } + req.CommitSig = testSig + + v[0] = reflect.ValueOf(*req) + }, + MsgRevokeAndAck: func(v []reflect.Value, r *rand.Rand) { + req := NewRevokeAndAck() + if _, err := r.Read(req.ChanID[:]); err != nil { + t.Fatalf("unable to generate chan id: %v", err) + return + } + if _, err := r.Read(req.Revocation[:]); err != nil { + t.Fatalf("unable to generate bytes: %v", err) + return + } + if _, err := r.Read(req.NextRevocationHash[:]); err != nil { + t.Fatalf("unable to generate bytes: %v", err) + return + } + + var err error + req.NextRevocationKey, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + + v[0] = reflect.ValueOf(*req) + }, + MsgChannelAnnouncement: func(v []reflect.Value, r *rand.Rand) { + req := ChannelAnnouncement{ + ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), + } + req.NodeSig1 = testSig + req.NodeSig2 = testSig + req.BitcoinSig1 = testSig + req.BitcoinSig2 = testSig + + var err error + req.NodeID1, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + req.NodeID2, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + req.BitcoinKey1, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + req.BitcoinKey2, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + + v[0] = reflect.ValueOf(req) + }, + MsgNodeAnnouncement: func(v []reflect.Value, r *rand.Rand) { + var a [32]byte + if _, err := r.Read(a[:]); err != nil { + t.Fatalf("unable to generate alias: %v", err) + return + } + + req := NodeAnnouncement{ + Signature: testSig, + Timestamp: uint32(r.Int31()), + Alias: newAlias(a[:]), + RGBColor: RGB{ + red: uint8(r.Int31()), + green: uint8(r.Int31()), + blue: uint8(r.Int31()), + }, + Features: randFeatureVector(r), + Addresses: testAddrs, + } + req.Features.featuresMap = nil + + var err error + req.NodeID, err = randPubKey() + if err != nil { + t.Fatalf("unable to generate key: %v", err) + return + } + + v[0] = reflect.ValueOf(req) + }, + MsgChannelUpdate: func(v []reflect.Value, r *rand.Rand) { + req := ChannelUpdate{ + Signature: testSig, + ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), + Timestamp: uint32(r.Int31()), + Flags: uint16(r.Int31()), + TimeLockDelta: uint16(r.Int31()), + HtlcMinimumMsat: uint32(r.Int31()), + FeeBaseMsat: uint32(r.Int31()), + FeeProportionalMillionths: uint32(r.Int31()), + } + + v[0] = reflect.ValueOf(req) + }, + MsgAnnounceSignatures: func(v []reflect.Value, r *rand.Rand) { + req := AnnounceSignatures{ + ShortChannelID: NewShortChanIDFromInt(uint64(r.Int63())), + NodeSignature: testSig, + BitcoinSignature: testSig, + } + if _, err := r.Read(req.ChannelID[:]); err != nil { + t.Fatalf("unable to generate chan id: %v", err) + return + } + + v[0] = reflect.ValueOf(req) + }, + } + + // With the above types defined, we'll now generate a slice of + // scenarios to feed into quick.Check. The function scans in input + // space of the target function under test, so we'll need to create a + // series of wrapper functions to force it to iterate over the target + // types, but re-use the mainScenario defined above. + tests := []struct { + msgType MessageType + scenario interface{} + }{ + { + msgType: MsgInit, + scenario: func(m Init) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgError, + scenario: func(m Error) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgPing, + scenario: func(m Ping) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgPong, + scenario: func(m Pong) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgSingleFundingRequest, + scenario: func(m SingleFundingRequest) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgSingleFundingResponse, + scenario: func(m SingleFundingResponse) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgSingleFundingComplete, + scenario: func(m SingleFundingComplete) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgSingleFundingSignComplete, + scenario: func(m SingleFundingSignComplete) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgFundingLocked, + scenario: func(m FundingLocked) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgCloseRequest, + scenario: func(m CloseRequest) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgCloseComplete, + scenario: func(m CloseComplete) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgUpdateAddHTLC, + scenario: func(m UpdateAddHTLC) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgUpdateFufillHTLC, + scenario: func(m UpdateFufillHTLC) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgUpdateFailHTLC, + scenario: func(m UpdateFailHTLC) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgCommitSig, + scenario: func(m CommitSig) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgRevokeAndAck, + scenario: func(m RevokeAndAck) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgChannelAnnouncement, + scenario: func(m ChannelAnnouncement) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgNodeAnnouncement, + scenario: func(m NodeAnnouncement) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgChannelUpdate, + scenario: func(m ChannelUpdate) bool { + return mainScenario(&m) + }, + }, + { + msgType: MsgAnnounceSignatures, + scenario: func(m AnnounceSignatures) bool { + return mainScenario(&m) + }, + }, + } + for _, test := range tests { + var config *quick.Config + + // If the type defined is within the custom type gen map above, + // then we'll modify the default config to use this Value + // function that knows how to generate the proper types. + if valueGen, ok := customTypeGen[test.msgType]; ok { + config = &quick.Config{ + Values: valueGen, + } + } + + t.Logf("Running fuzz tests for msgType=%v", test.msgType) + if err := quick.Check(test.scenario, config); err != nil { + t.Fatalf("fuzz checks for msg=%v failed: %v", + test.msgType, err) + } + } + +} diff --git a/lnwire/node_announcement_test.go b/lnwire/node_announcement_test.go index f6d8edfe..de59d2a2 100644 --- a/lnwire/node_announcement_test.go +++ b/lnwire/node_announcement_test.go @@ -1,76 +1,14 @@ package lnwire -import ( - "bytes" - "reflect" - "testing" -) - -func TestNodeAnnouncementEncodeDecode(t *testing.T) { - na := &NodeAnnouncement{ - Signature: someSig, - Timestamp: maxUint32, - NodeID: pubKey, - RGBColor: someRGB, - Alias: someAlias, - Addresses: someAddresses, - Features: someFeatures, - } - - // Next encode the NA message into an empty bytes buffer. - var b bytes.Buffer - if err := na.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode NodeAnnouncement: %v", err) - } - - // Deserialize the encoded NA message into a new empty struct. - na2 := &NodeAnnouncement{} - if err := na2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode NodeAnnouncement: %v", err) - } - - // We do not encode the feature map in feature vector, for that reason - // the node announcement messages will differ. Set feature map with nil - // in order to use deep equal function. - na.Features.featuresMap = nil - - // Assert equality of the two instances. - if !reflect.DeepEqual(na, na2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - na, na2) - } -} - -func TestNodeAnnoucementPayloadLength(t *testing.T) { - na := &NodeAnnouncement{ - Signature: someSig, - Timestamp: maxUint32, - NodeID: pubKey, - RGBColor: someRGB, - Alias: someAlias, - Addresses: someAddresses, - Features: someFeatures, - } - - var b bytes.Buffer - if err := na.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode node: %v", err) - } - - serializedLength := uint32(b.Len()) - if serializedLength != 167 { - t.Fatalf("payload length estimate is incorrect: expected %v "+ - "got %v", 167, serializedLength) - } - - if na.MaxPayloadLength(0) != 8192 { - t.Fatalf("max payload length doesn't match: expected 8192, got %v", - na.MaxPayloadLength(0)) - } -} +import "testing" func TestValidateAlias(t *testing.T) { - if err := someAlias.Validate(); err != nil { + aliasStr := "012345678901234567890" + alias := NewAlias(aliasStr) + if err := alias.Validate(); err != nil { t.Fatalf("alias was invalid: %v", err) } + if aliasStr != alias.String() { + t.Fatalf("aliases don't match") + } } diff --git a/lnwire/ping_test.go b/lnwire/ping_test.go deleted file mode 100644 index 547a9b94..00000000 --- a/lnwire/ping_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestPingEncodeDecode(t *testing.T) { - ping := &Ping{ - NumPongBytes: 10, - PaddingBytes: bytes.Repeat([]byte("A"), 100), - } - - // Next encode the ping message into an empty bytes buffer. - var b bytes.Buffer - if err := ping.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode ping: %v", err) - } - - // Deserialize the encoded ping message into a new empty struct. - ping2 := &Ping{} - if err := ping2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode ping: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(ping, ping2) { - t.Fatalf("encode/decode ping messages don't match %#v vs %#v", - ping, ping2) - } -} diff --git a/lnwire/pong_test.go b/lnwire/pong_test.go deleted file mode 100644 index 8a415fcd..00000000 --- a/lnwire/pong_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestPongEncodeDecode(t *testing.T) { - pong := &Pong{ - PongBytes: bytes.Repeat([]byte("A"), 100), - } - - // Next encode the pong message into an empty bytes buffer. - var b bytes.Buffer - if err := pong.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode pong: %v", err) - } - - // Deserialize the encoded pong message into a new empty struct. - pong2 := &Pong{} - if err := pong2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode ping: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(pong, pong2) { - t.Fatalf("encode/decode pong messages don't match %#v vs %#v", - pong, pong2) - } -} diff --git a/lnwire/revoke_and_ack_test.go b/lnwire/revoke_and_ack_test.go deleted file mode 100644 index 673e2ce1..00000000 --- a/lnwire/revoke_and_ack_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestRevokeAndAckEncodeDecode(t *testing.T) { - cr := &RevokeAndAck{ - ChanID: ChannelID(revHash), - Revocation: revHash, - NextRevocationKey: pubKey, - NextRevocationHash: revHash, - } - - // Next encode the CR message into an empty bytes buffer. - var b bytes.Buffer - if err := cr.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode RevokeAndAck: %v", err) - } - - // Deserialize the encoded EG message into a new empty struct. - cr2 := &RevokeAndAck{} - if err := cr2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode RevokeAndAck: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(cr, cr2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - cr, cr2) - } -} diff --git a/lnwire/single_funding_complete_test.go b/lnwire/single_funding_complete_test.go deleted file mode 100644 index f9354c21..00000000 --- a/lnwire/single_funding_complete_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestSingleFundingCompleteWire(t *testing.T) { - var obsfucator [6]byte - copy(obsfucator[:], bytes.Repeat([]byte("k"), 6)) - - // First create a new SFC message. - sfc := NewSingleFundingComplete(revHash, *outpoint1, commitSig1, pubKey, - obsfucator) - - // Next encode the SFC message into an empty bytes buffer. - var b bytes.Buffer - if err := sfc.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode SingleFundingComplete: %v", err) - } - - // Deserialize the encoded SFC message into a new empty struct. - sfc2 := &SingleFundingComplete{} - if err := sfc2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode SingleFundingComplete: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(sfc, sfc2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - sfc, sfc2) - } -} diff --git a/lnwire/single_funding_request_test.go b/lnwire/single_funding_request_test.go deleted file mode 100644 index 67689d84..00000000 --- a/lnwire/single_funding_request_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestSingleFundingRequestWire(t *testing.T) { - // First create a new SFR message. - cdp := pubKey - delivery := PkScript(bytes.Repeat([]byte{0x02}, 25)) - sfr := NewSingleFundingRequest(revHash, 21, 22, 23, 5, 5, cdp, cdp, - delivery, 540, 10000, 6) - - // Next encode the SFR message into an empty bytes buffer. - var b bytes.Buffer - if err := sfr.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode SingleFundingRequest: %v", err) - } - - // Deserialize the encoded SFR message into a new empty struct. - sfr2 := &SingleFundingRequest{} - if err := sfr2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode SingleFundingRequest: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(sfr, sfr2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - sfr, sfr2) - } -} diff --git a/lnwire/single_funding_response_test.go b/lnwire/single_funding_response_test.go deleted file mode 100644 index 61ed2ab1..00000000 --- a/lnwire/single_funding_response_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestSingleFundingResponseWire(t *testing.T) { - // First create a new SFR message. - delivery := PkScript(bytes.Repeat([]byte{0x02}, 25)) - sfr := NewSingleFundingResponse(revHash, pubKey, pubKey, pubKey, 5, - delivery, 540, 4) - - // Next encode the SFR message into an empty bytes buffer. - var b bytes.Buffer - if err := sfr.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode SingleFundingResponse: %v", err) - } - - // Deserialize the encoded SFR message into a new empty struct. - sfr2 := &SingleFundingResponse{} - if err := sfr2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode SingleFundingResponse: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(sfr, sfr2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - sfr, sfr2) - } -} diff --git a/lnwire/single_funding_signcomplete_test.go b/lnwire/single_funding_signcomplete_test.go deleted file mode 100644 index 6b4889c6..00000000 --- a/lnwire/single_funding_signcomplete_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package lnwire - -import ( - "bytes" - "math/big" - "reflect" - "testing" - - "github.com/roasbeef/btcd/btcec" -) - -func TestSingleFundingSignCompleteWire(t *testing.T) { - // First create a new SFSC message. - sfsc := NewSingleFundingSignComplete( - revHash, - &btcec.Signature{ - R: new(big.Int).SetInt64(9), - S: new(big.Int).SetInt64(11), - }, - ) - - // Next encode the SFSC message into an empty bytes buffer. - var b bytes.Buffer - if err := sfsc.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode SingleFundingSignComplete: %v", err) - } - - // Deserialize the encoded SFSC message into a new empty struct. - sfsc2 := &SingleFundingSignComplete{} - if err := sfsc2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode SingleFundingSignComplete: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(sfsc, sfsc2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - sfsc, sfsc2) - } -} diff --git a/lnwire/update_add_htlc_test.go b/lnwire/update_add_htlc_test.go deleted file mode 100644 index 37d9f73e..00000000 --- a/lnwire/update_add_htlc_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" - - "github.com/roasbeef/btcutil" -) - -func TestUpdateAddHTLCEncodeDecode(t *testing.T) { - // First create a new UPAH message. - addReq := &UpdateAddHTLC{ - ChanID: ChannelID(revHash), - ID: 99, - Expiry: uint32(144), - Amount: btcutil.Amount(123456000), - PaymentHash: revHash, - } - copy(addReq.OnionBlob[:], bytes.Repeat([]byte{23}, OnionPacketSize)) - - // Next encode the HTLCAR message into an empty bytes buffer. - var b bytes.Buffer - if err := addReq.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode HTLCAddRequest: %v", err) - } - - // Deserialize the encoded UPAH message into a new empty struct. - addReq2 := &UpdateAddHTLC{} - if err := addReq2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode HTLCAddRequest: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(addReq, addReq2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - addReq, addReq2) - } -} diff --git a/lnwire/update_fail_htlc_test.go b/lnwire/update_fail_htlc_test.go deleted file mode 100644 index 46111c56..00000000 --- a/lnwire/update_fail_htlc_test.go +++ /dev/null @@ -1,34 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestUpdateFailHTLC(t *testing.T) { - // First create a new UFH message. - cancelMsg := &UpdateFailHTLC{ - ChanID: ChannelID(revHash), - ID: 22, - } - cancelMsg.Reason = []byte{byte(UnknownDestination)} - - // Next encode the UFH message into an empty bytes buffer. - var b bytes.Buffer - if err := cancelMsg.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode CancelHTLC: %v", err) - } - - // Deserialize the encoded UFH message into a new empty struct. - cancelMsg2 := &UpdateFailHTLC{} - if err := cancelMsg2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode CancelHTLC: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(cancelMsg, cancelMsg2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - cancelMsg, cancelMsg2) - } -} diff --git a/lnwire/update_fulfill_htlc_test.go b/lnwire/update_fulfill_htlc_test.go deleted file mode 100644 index 62a680fc..00000000 --- a/lnwire/update_fulfill_htlc_test.go +++ /dev/null @@ -1,30 +0,0 @@ -package lnwire - -import ( - "bytes" - "reflect" - "testing" -) - -func TestUpdateFufillHTLCEncodeDecode(t *testing.T) { - // First create a new HTLCSR message. - settleReq := NewUpdateFufillHTLC(ChannelID(revHash), 23, revHash) - - // Next encode the HTLCSR message into an empty bytes buffer. - var b bytes.Buffer - if err := settleReq.Encode(&b, 0); err != nil { - t.Fatalf("unable to encode UpdateFufillHTLC: %v", err) - } - - // Deserialize the encoded SFOP message into a new empty struct. - settleReq2 := &UpdateFufillHTLC{} - if err := settleReq2.Decode(&b, 0); err != nil { - t.Fatalf("unable to decode UpdateFufillHTLC: %v", err) - } - - // Assert equality of the two instances. - if !reflect.DeepEqual(settleReq, settleReq2) { - t.Fatalf("encode/decode error messages don't match %#v vs %#v", - settleReq, settleReq2) - } -}