lnwire: replace all wire msg tests with a single property-based test
This commit does away with all the old manual message equality tests and replace it with a single property-based test that uses the testing/quick package. This test uses a single scenario which MUST hold for all the messages type and all possible messages generated for those types. As a result we are able to do away with all the prior manually generated test data as the fuzzer to scan the input space looking for a message that violates the scenario.
This commit is contained in:
parent
febc8c399a
commit
e3686cbc69
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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() != "<unknown>" {
|
||||
t.Fatalf("incorrect string, expected <unknown> got %v",
|
||||
fakeFlag.String())
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user