mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 18:10:34 +01:00
868 lines
22 KiB
Go
868 lines
22 KiB
Go
package lnwire_test
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"image/color"
|
|
"io"
|
|
"math"
|
|
"math/big"
|
|
"math/rand"
|
|
"net"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/btcsuite/btcd/btcec"
|
|
"github.com/btcsuite/btcutil"
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
|
"github.com/lightningnetwork/lnd/tor"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
const deliveryAddressMaxSize = 34
|
|
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
|
|
var (
|
|
testSig = &btcec.Signature{
|
|
R: new(big.Int),
|
|
S: new(big.Int),
|
|
}
|
|
testNodeSig, _ = lnwire.NewSigFromSignature(testSig)
|
|
|
|
testNumExtraBytes = 1000
|
|
testNumSigs = 100
|
|
testNumChanIDs = 1000
|
|
buffer = make([]byte, 0, lnwire.MaxSliceLength)
|
|
|
|
bufPool = sync.Pool{
|
|
New: func() interface{} {
|
|
return bytes.NewBuffer(buffer)
|
|
},
|
|
}
|
|
)
|
|
|
|
// BenchmarkWriteMessage benchmarks the performance of lnwire.WriteMessage. It
|
|
// generates a test message for each of the lnwire.Message, calls the
|
|
// WriteMessage method and benchmark it.
|
|
func BenchmarkWriteMessage(b *testing.B) {
|
|
// Create testing messages. We will use a constant seed to make sure
|
|
// the benchmark uses the same data every time.
|
|
r := rand.New(rand.NewSource(42))
|
|
|
|
msgAll := makeAllMessages(b, r)
|
|
|
|
// Iterate all messages and write each once.
|
|
for _, msg := range msgAll {
|
|
m := msg
|
|
// Run each message as a sub benchmark test.
|
|
b.Run(msg.MsgType().String(), func(b *testing.B) {
|
|
|
|
b.ResetTimer()
|
|
for i := 0; i < b.N; i++ {
|
|
// Fetch a buffer from the pool and reset it.
|
|
buf := bufPool.Get().(*bytes.Buffer)
|
|
buf.Reset()
|
|
|
|
_, err := lnwire.WriteMessage(buf, m, 0)
|
|
require.NoError(b, err, "unable to write msg")
|
|
|
|
// Put the buffer back when done.
|
|
bufPool.Put(buf)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// BenchmarkReadMessage benchmarks the performance of lnwire.ReadMessage. It
|
|
// first creates a test message for each of the lnwire.Message, writes it to
|
|
// the buffer, then later reads it from the buffer.
|
|
func BenchmarkReadMessage(b *testing.B) {
|
|
// Create testing messages. We will use a constant seed to make sure
|
|
// the benchmark uses the same data every time.
|
|
r := rand.New(rand.NewSource(42))
|
|
msgAll := makeAllMessages(b, r)
|
|
|
|
// Write all the messages to the buffer.
|
|
for _, msg := range msgAll {
|
|
// Fetch a buffer from the pool and reset it.
|
|
buf := bufPool.Get().(*bytes.Buffer)
|
|
buf.Reset()
|
|
|
|
_, err := lnwire.WriteMessage(buf, msg, 0)
|
|
require.NoError(b, err, "unable to write msg")
|
|
|
|
// Run each message as a sub benchmark test.
|
|
m := msg
|
|
b.Run(m.MsgType().String(), func(b *testing.B) {
|
|
b.ResetTimer()
|
|
|
|
for i := 0; i < b.N; i++ {
|
|
r := bytes.NewBuffer(buf.Bytes())
|
|
|
|
// Read the message from the buffer.
|
|
_, err := lnwire.ReadMessage(r, 0)
|
|
require.NoError(b, err, "unable to read msg")
|
|
}
|
|
})
|
|
|
|
// Put the buffer back when done.
|
|
bufPool.Put(buf)
|
|
}
|
|
}
|
|
|
|
// makeAllMessages is used to create testing messages for each lnwire message
|
|
// type.
|
|
//
|
|
// TODO(yy): the following testing messages are created somewhat arbitrary. We
|
|
// should standardlize each of the testing messages so that a better baseline
|
|
// can be used.
|
|
func makeAllMessages(t testing.TB, r *rand.Rand) []lnwire.Message {
|
|
msgAll := []lnwire.Message{}
|
|
|
|
msgAll = append(msgAll, newMsgInit(t, r))
|
|
msgAll = append(msgAll, newMsgError(t, r))
|
|
msgAll = append(msgAll, newMsgPing(t, r))
|
|
msgAll = append(msgAll, newMsgPong(t, r))
|
|
msgAll = append(msgAll, newMsgOpenChannel(t, r))
|
|
msgAll = append(msgAll, newMsgAcceptChannel(t, r))
|
|
msgAll = append(msgAll, newMsgFundingCreated(t, r))
|
|
msgAll = append(msgAll, newMsgFundingSigned(t, r))
|
|
msgAll = append(msgAll, newMsgFundingLocked(t, r))
|
|
msgAll = append(msgAll, newMsgShutdown(t, r))
|
|
msgAll = append(msgAll, newMsgClosingSigned(t, r))
|
|
msgAll = append(msgAll, newMsgUpdateAddHTLC(t, r))
|
|
msgAll = append(msgAll, newMsgUpdateFulfillHTLC(t, r))
|
|
msgAll = append(msgAll, newMsgUpdateFailHTLC(t, r))
|
|
msgAll = append(msgAll, newMsgCommitSig(t, r))
|
|
msgAll = append(msgAll, newMsgRevokeAndAck(t, r))
|
|
msgAll = append(msgAll, newMsgUpdateFee(t, r))
|
|
msgAll = append(msgAll, newMsgUpdateFailMalformedHTLC(t, r))
|
|
msgAll = append(msgAll, newMsgChannelReestablish(t, r))
|
|
msgAll = append(msgAll, newMsgChannelAnnouncement(t, r))
|
|
msgAll = append(msgAll, newMsgNodeAnnouncement(t, r))
|
|
msgAll = append(msgAll, newMsgChannelUpdate(t, r))
|
|
msgAll = append(msgAll, newMsgAnnounceSignatures(t, r))
|
|
msgAll = append(msgAll, newMsgQueryShortChanIDs(t, r))
|
|
msgAll = append(msgAll, newMsgReplyShortChanIDsEnd(t, r))
|
|
msgAll = append(msgAll, newMsgQueryChannelRange(t, r))
|
|
msgAll = append(msgAll, newMsgReplyChannelRange(t, r))
|
|
msgAll = append(msgAll, newMsgGossipTimestampRange(t, r))
|
|
msgAll = append(msgAll, newMsgQueryShortChanIDsZlib(t, r))
|
|
msgAll = append(msgAll, newMsgReplyChannelRangeZlib(t, r))
|
|
|
|
return msgAll
|
|
}
|
|
|
|
func newMsgInit(t testing.TB, r io.Reader) *lnwire.Init {
|
|
t.Helper()
|
|
|
|
return &lnwire.Init{
|
|
GlobalFeatures: rawFeatureVector(),
|
|
Features: rawFeatureVector(),
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
}
|
|
|
|
// newMsgOpenChannel creates a testing OpenChannel message.
|
|
func newMsgOpenChannel(t testing.TB, r *rand.Rand) *lnwire.OpenChannel {
|
|
t.Helper()
|
|
|
|
msg := &lnwire.OpenChannel{
|
|
FundingAmount: btcutil.Amount(r.Int63()),
|
|
PushAmount: lnwire.MilliSatoshi(r.Int63()),
|
|
DustLimit: btcutil.Amount(r.Int63()),
|
|
MaxValueInFlight: lnwire.MilliSatoshi(r.Int63()),
|
|
ChannelReserve: btcutil.Amount(r.Int63()),
|
|
HtlcMinimum: lnwire.MilliSatoshi(r.Int63()),
|
|
FeePerKiloWeight: uint32(r.Int31()),
|
|
CsvDelay: uint16(r.Intn(1 << 16)),
|
|
MaxAcceptedHTLCs: uint16(r.Intn(1 << 16)),
|
|
ChannelFlags: lnwire.FundingFlag(uint8(r.Intn(1 << 8))),
|
|
FundingKey: randPubKey(t),
|
|
RevocationPoint: randPubKey(t),
|
|
PaymentPoint: randPubKey(t),
|
|
DelayedPaymentPoint: randPubKey(t),
|
|
HtlcPoint: randPubKey(t),
|
|
FirstCommitmentPoint: randPubKey(t),
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := r.Read(msg.ChainHash[:])
|
|
require.NoError(t, err, "unable to read bytes for ChainHash")
|
|
|
|
_, err = r.Read(msg.PendingChannelID[:])
|
|
require.NoError(t, err, "unable to read bytes for PendingChannelID")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgAcceptChannel(t testing.TB, r *rand.Rand) *lnwire.AcceptChannel {
|
|
t.Helper()
|
|
|
|
msg := &lnwire.AcceptChannel{
|
|
DustLimit: btcutil.Amount(r.Int63()),
|
|
MaxValueInFlight: lnwire.MilliSatoshi(r.Int63()),
|
|
ChannelReserve: btcutil.Amount(r.Int63()),
|
|
MinAcceptDepth: uint32(r.Int31()),
|
|
HtlcMinimum: lnwire.MilliSatoshi(r.Int63()),
|
|
CsvDelay: uint16(r.Intn(1 << 16)),
|
|
MaxAcceptedHTLCs: uint16(r.Intn(1 << 16)),
|
|
FundingKey: randPubKey(t),
|
|
RevocationPoint: randPubKey(t),
|
|
PaymentPoint: randPubKey(t),
|
|
DelayedPaymentPoint: randPubKey(t),
|
|
HtlcPoint: randPubKey(t),
|
|
FirstCommitmentPoint: randPubKey(t),
|
|
UpfrontShutdownScript: randDeliveryAddress(t, r),
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
_, err := r.Read(msg.PendingChannelID[:])
|
|
require.NoError(t, err, "unable to generate pending chan id")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgError(t testing.TB, r io.Reader) *lnwire.Error {
|
|
t.Helper()
|
|
|
|
msg := lnwire.NewError()
|
|
|
|
_, err := r.Read(msg.ChanID[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
msg.Data = createExtraData(t, r)
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgPing(t testing.TB, r *rand.Rand) *lnwire.Ping {
|
|
t.Helper()
|
|
|
|
return &lnwire.Ping{
|
|
NumPongBytes: uint16(r.Intn(1 << 16)),
|
|
PaddingBytes: createExtraData(t, r),
|
|
}
|
|
}
|
|
|
|
func newMsgPong(t testing.TB, r io.Reader) *lnwire.Pong {
|
|
t.Helper()
|
|
|
|
return &lnwire.Pong{
|
|
PongBytes: createExtraData(t, r),
|
|
}
|
|
}
|
|
|
|
func newMsgFundingCreated(t testing.TB, r *rand.Rand) *lnwire.FundingCreated {
|
|
t.Helper()
|
|
|
|
msg := &lnwire.FundingCreated{
|
|
CommitSig: testNodeSig,
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := r.Read(msg.PendingChannelID[:])
|
|
require.NoError(t, err, "unable to generate pending chan id")
|
|
|
|
_, err = r.Read(msg.FundingPoint.Hash[:])
|
|
require.NoError(t, err, "unable to generate hash")
|
|
|
|
msg.FundingPoint.Index = uint32(r.Int31()) % math.MaxUint16
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgFundingSigned(t testing.TB, r io.Reader) *lnwire.FundingSigned {
|
|
t.Helper()
|
|
|
|
var c [32]byte
|
|
|
|
_, err := r.Read(c[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
msg := &lnwire.FundingSigned{
|
|
ChanID: lnwire.ChannelID(c),
|
|
CommitSig: testNodeSig,
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgFundingLocked(t testing.TB, r io.Reader) *lnwire.FundingLocked {
|
|
t.Helper()
|
|
|
|
var c [32]byte
|
|
|
|
_, err := r.Read(c[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
pubKey := randPubKey(t)
|
|
|
|
msg := lnwire.NewFundingLocked(lnwire.ChannelID(c), pubKey)
|
|
msg.ExtraData = createExtraData(t, r)
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgShutdown(t testing.TB, r *rand.Rand) *lnwire.Shutdown {
|
|
t.Helper()
|
|
|
|
msg := &lnwire.Shutdown{
|
|
Address: randDeliveryAddress(t, r),
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := r.Read(msg.ChannelID[:])
|
|
require.NoError(t, err, "unable to generate channel id")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgClosingSigned(t testing.TB, r *rand.Rand) *lnwire.ClosingSigned {
|
|
t.Helper()
|
|
|
|
msg := &lnwire.ClosingSigned{
|
|
FeeSatoshis: btcutil.Amount(r.Int63()),
|
|
Signature: testNodeSig,
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := r.Read(msg.ChannelID[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgUpdateAddHTLC(t testing.TB, r *rand.Rand) *lnwire.UpdateAddHTLC {
|
|
t.Helper()
|
|
|
|
msg := &lnwire.UpdateAddHTLC{
|
|
ID: r.Uint64(),
|
|
Amount: lnwire.MilliSatoshi(r.Int63()),
|
|
Expiry: r.Uint32(),
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := r.Read(msg.ChanID[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
_, err = r.Read(msg.PaymentHash[:])
|
|
require.NoError(t, err, "unable to generate paymenthash")
|
|
|
|
_, err = r.Read(msg.OnionBlob[:])
|
|
require.NoError(t, err, "unable to generate onion blob")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgUpdateFulfillHTLC(t testing.TB,
|
|
r *rand.Rand) *lnwire.UpdateFulfillHTLC {
|
|
|
|
t.Helper()
|
|
|
|
msg := &lnwire.UpdateFulfillHTLC{
|
|
ID: r.Uint64(),
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := r.Read(msg.ChanID[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
_, err = r.Read(msg.PaymentPreimage[:])
|
|
require.NoError(t, err, "unable to generate payment preimage")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgUpdateFailHTLC(t testing.TB, r *rand.Rand) *lnwire.UpdateFailHTLC {
|
|
t.Helper()
|
|
|
|
msg := &lnwire.UpdateFailHTLC{
|
|
ID: r.Uint64(),
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := r.Read(msg.ChanID[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgCommitSig(t testing.TB, r io.Reader) *lnwire.CommitSig {
|
|
t.Helper()
|
|
|
|
msg := lnwire.NewCommitSig()
|
|
|
|
_, err := r.Read(msg.ChanID[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
msg.CommitSig = testNodeSig
|
|
msg.ExtraData = createExtraData(t, r)
|
|
|
|
msg.HtlcSigs = make([]lnwire.Sig, testNumSigs)
|
|
for i := 0; i < testNumSigs; i++ {
|
|
msg.HtlcSigs[i] = testNodeSig
|
|
}
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgRevokeAndAck(t testing.TB, r io.Reader) *lnwire.RevokeAndAck {
|
|
t.Helper()
|
|
|
|
msg := lnwire.NewRevokeAndAck()
|
|
|
|
_, err := r.Read(msg.ChanID[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
_, err = r.Read(msg.Revocation[:])
|
|
require.NoError(t, err, "unable to generate bytes")
|
|
|
|
msg.NextRevocationKey = randPubKey(t)
|
|
require.NoError(t, err, "unable to generate key")
|
|
|
|
msg.ExtraData = createExtraData(t, r)
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgUpdateFee(t testing.TB, r *rand.Rand) *lnwire.UpdateFee {
|
|
t.Helper()
|
|
|
|
msg := &lnwire.UpdateFee{
|
|
FeePerKw: uint32(r.Int31()),
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := r.Read(msg.ChanID[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgUpdateFailMalformedHTLC(t testing.TB,
|
|
r *rand.Rand) *lnwire.UpdateFailMalformedHTLC {
|
|
|
|
t.Helper()
|
|
|
|
msg := &lnwire.UpdateFailMalformedHTLC{
|
|
ID: r.Uint64(),
|
|
FailureCode: lnwire.FailCode(r.Intn(1 << 16)),
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := r.Read(msg.ChanID[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
_, err = r.Read(msg.ShaOnionBlob[:])
|
|
require.NoError(t, err, "unable to generate sha256 onion blob")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgChannelReestablish(t testing.TB,
|
|
r *rand.Rand) *lnwire.ChannelReestablish {
|
|
|
|
t.Helper()
|
|
|
|
msg := &lnwire.ChannelReestablish{
|
|
NextLocalCommitHeight: uint64(r.Int63()),
|
|
RemoteCommitTailHeight: uint64(r.Int63()),
|
|
LocalUnrevokedCommitPoint: randPubKey(t),
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := r.Read(msg.LastRemoteCommitSecret[:])
|
|
require.NoError(t, err, "unable to read commit secret")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgChannelAnnouncement(t testing.TB,
|
|
r *rand.Rand) *lnwire.ChannelAnnouncement {
|
|
|
|
t.Helper()
|
|
|
|
msg := &lnwire.ChannelAnnouncement{
|
|
ShortChannelID: lnwire.NewShortChanIDFromInt(uint64(r.Int63())),
|
|
Features: rawFeatureVector(),
|
|
NodeID1: randRawKey(t),
|
|
NodeID2: randRawKey(t),
|
|
BitcoinKey1: randRawKey(t),
|
|
BitcoinKey2: randRawKey(t),
|
|
ExtraOpaqueData: createExtraData(t, r),
|
|
NodeSig1: testNodeSig,
|
|
NodeSig2: testNodeSig,
|
|
BitcoinSig1: testNodeSig,
|
|
BitcoinSig2: testNodeSig,
|
|
}
|
|
|
|
_, err := r.Read(msg.ChainHash[:])
|
|
require.NoError(t, err, "unable to generate chain hash")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgNodeAnnouncement(t testing.TB,
|
|
r *rand.Rand) *lnwire.NodeAnnouncement {
|
|
|
|
t.Helper()
|
|
|
|
msg := &lnwire.NodeAnnouncement{
|
|
Features: rawFeatureVector(),
|
|
Timestamp: uint32(r.Int31()),
|
|
Alias: randAlias(r),
|
|
RGBColor: color.RGBA{
|
|
R: uint8(r.Intn(1 << 8)),
|
|
G: uint8(r.Intn(1 << 8)),
|
|
B: uint8(r.Intn(1 << 8)),
|
|
},
|
|
NodeID: randRawKey(t),
|
|
Addresses: randAddrs(t, r),
|
|
ExtraOpaqueData: createExtraData(t, r),
|
|
Signature: testNodeSig,
|
|
}
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgChannelUpdate(t testing.TB, r *rand.Rand) *lnwire.ChannelUpdate {
|
|
t.Helper()
|
|
|
|
msgFlags := lnwire.ChanUpdateMsgFlags(r.Int31())
|
|
maxHtlc := lnwire.MilliSatoshi(r.Int63())
|
|
|
|
// We make the max_htlc field zero if it is not flagged
|
|
// as being part of the ChannelUpdate, to pass
|
|
// serialization tests, as it will be ignored if the bit
|
|
// is not set.
|
|
if msgFlags&lnwire.ChanUpdateOptionMaxHtlc == 0 {
|
|
maxHtlc = 0
|
|
}
|
|
|
|
msg := &lnwire.ChannelUpdate{
|
|
ShortChannelID: lnwire.NewShortChanIDFromInt(r.Uint64()),
|
|
Timestamp: uint32(r.Int31()),
|
|
MessageFlags: msgFlags,
|
|
ChannelFlags: lnwire.ChanUpdateChanFlags(r.Int31()),
|
|
TimeLockDelta: uint16(r.Int31()),
|
|
HtlcMinimumMsat: lnwire.MilliSatoshi(r.Int63()),
|
|
HtlcMaximumMsat: maxHtlc,
|
|
BaseFee: uint32(r.Int31()),
|
|
FeeRate: uint32(r.Int31()),
|
|
ExtraOpaqueData: createExtraData(t, r),
|
|
Signature: testNodeSig,
|
|
}
|
|
|
|
_, err := r.Read(msg.ChainHash[:])
|
|
require.NoError(t, err, "unable to generate chain hash")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgAnnounceSignatures(t testing.TB,
|
|
r *rand.Rand) *lnwire.AnnounceSignatures {
|
|
|
|
t.Helper()
|
|
|
|
msg := &lnwire.AnnounceSignatures{
|
|
ShortChannelID: lnwire.NewShortChanIDFromInt(
|
|
uint64(r.Int63()),
|
|
),
|
|
ExtraOpaqueData: createExtraData(t, r),
|
|
NodeSignature: testNodeSig,
|
|
BitcoinSignature: testNodeSig,
|
|
}
|
|
|
|
_, err := r.Read(msg.ChannelID[:])
|
|
require.NoError(t, err, "unable to generate chan id")
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgQueryShortChanIDs(t testing.TB,
|
|
r *rand.Rand) *lnwire.QueryShortChanIDs {
|
|
|
|
t.Helper()
|
|
|
|
msg := &lnwire.QueryShortChanIDs{
|
|
EncodingType: lnwire.EncodingSortedPlain,
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := rand.Read(msg.ChainHash[:])
|
|
require.NoError(t, err, "unable to read chain hash")
|
|
|
|
for i := 0; i < testNumChanIDs; i++ {
|
|
msg.ShortChanIDs = append(msg.ShortChanIDs,
|
|
lnwire.NewShortChanIDFromInt(uint64(r.Int63())))
|
|
}
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgQueryShortChanIDsZlib(t testing.TB,
|
|
r *rand.Rand) *lnwire.QueryShortChanIDs {
|
|
|
|
t.Helper()
|
|
|
|
msg := &lnwire.QueryShortChanIDs{
|
|
EncodingType: lnwire.EncodingSortedZlib,
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := rand.Read(msg.ChainHash[:])
|
|
require.NoError(t, err, "unable to read chain hash")
|
|
|
|
for i := 0; i < testNumChanIDs; i++ {
|
|
msg.ShortChanIDs = append(msg.ShortChanIDs,
|
|
lnwire.NewShortChanIDFromInt(uint64(r.Int63())))
|
|
}
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgReplyShortChanIDsEnd(t testing.TB,
|
|
r *rand.Rand) *lnwire.ReplyShortChanIDsEnd {
|
|
|
|
t.Helper()
|
|
|
|
msg := lnwire.NewReplyShortChanIDsEnd()
|
|
|
|
_, err := rand.Read(msg.ChainHash[:])
|
|
require.NoError(t, err, "unable to read chain hash")
|
|
|
|
msg.Complete = uint8(r.Int31n(2))
|
|
msg.ExtraData = createExtraData(t, r)
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgQueryChannelRange(t testing.TB,
|
|
r *rand.Rand) *lnwire.QueryChannelRange {
|
|
|
|
t.Helper()
|
|
|
|
msg := lnwire.NewQueryChannelRange()
|
|
|
|
_, err := rand.Read(msg.ChainHash[:])
|
|
require.NoError(t, err, "unable to read chain hash")
|
|
|
|
msg.FirstBlockHeight = r.Uint32()
|
|
msg.NumBlocks = r.Uint32()
|
|
msg.ExtraData = createExtraData(t, r)
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgReplyChannelRange(t testing.TB,
|
|
r *rand.Rand) *lnwire.ReplyChannelRange {
|
|
|
|
t.Helper()
|
|
|
|
msg := &lnwire.ReplyChannelRange{
|
|
EncodingType: lnwire.EncodingSortedPlain,
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := rand.Read(msg.ChainHash[:])
|
|
require.NoError(t, err, "unable to read chain hash")
|
|
|
|
msg.Complete = uint8(r.Int31n(2))
|
|
|
|
for i := 0; i < testNumChanIDs; i++ {
|
|
msg.ShortChanIDs = append(msg.ShortChanIDs,
|
|
lnwire.NewShortChanIDFromInt(uint64(r.Int63())))
|
|
}
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgReplyChannelRangeZlib(t testing.TB,
|
|
r *rand.Rand) *lnwire.ReplyChannelRange {
|
|
|
|
t.Helper()
|
|
|
|
msg := &lnwire.ReplyChannelRange{
|
|
EncodingType: lnwire.EncodingSortedZlib,
|
|
ExtraData: createExtraData(t, r),
|
|
}
|
|
|
|
_, err := rand.Read(msg.ChainHash[:])
|
|
require.NoError(t, err, "unable to read chain hash")
|
|
|
|
msg.Complete = uint8(r.Int31n(2))
|
|
|
|
for i := 0; i < testNumChanIDs; i++ {
|
|
msg.ShortChanIDs = append(msg.ShortChanIDs,
|
|
lnwire.NewShortChanIDFromInt(uint64(r.Int63())))
|
|
}
|
|
|
|
return msg
|
|
}
|
|
|
|
func newMsgGossipTimestampRange(t testing.TB,
|
|
r *rand.Rand) *lnwire.GossipTimestampRange {
|
|
|
|
t.Helper()
|
|
|
|
msg := lnwire.NewGossipTimestampRange()
|
|
msg.FirstTimestamp = r.Uint32()
|
|
msg.TimestampRange = r.Uint32()
|
|
msg.ExtraData = createExtraData(t, r)
|
|
|
|
_, err := r.Read(msg.ChainHash[:])
|
|
require.NoError(t, err, "unable to read chain hash")
|
|
|
|
return msg
|
|
}
|
|
|
|
func randRawKey(t testing.TB) [33]byte {
|
|
t.Helper()
|
|
|
|
var n [33]byte
|
|
|
|
priv, err := btcec.NewPrivateKey(btcec.S256())
|
|
require.NoError(t, err, "failed to create privKey")
|
|
|
|
copy(n[:], priv.PubKey().SerializeCompressed())
|
|
|
|
return n
|
|
}
|
|
|
|
func randPubKey(t testing.TB) *btcec.PublicKey {
|
|
t.Helper()
|
|
|
|
priv, err := btcec.NewPrivateKey(btcec.S256())
|
|
require.NoError(t, err, "failed to create pubkey")
|
|
|
|
return priv.PubKey()
|
|
}
|
|
|
|
func rawFeatureVector() *lnwire.RawFeatureVector {
|
|
// Get a slice of known feature bits.
|
|
featureBits := make([]lnwire.FeatureBit, 0, len(lnwire.Features))
|
|
for fb := range lnwire.Features {
|
|
featureBits = append(featureBits, fb)
|
|
}
|
|
|
|
featureVec := lnwire.NewRawFeatureVector(featureBits...)
|
|
|
|
return featureVec
|
|
}
|
|
|
|
func randDeliveryAddress(t testing.TB, r *rand.Rand) lnwire.DeliveryAddress {
|
|
t.Helper()
|
|
|
|
// Generate a max sized address.
|
|
size := r.Intn(deliveryAddressMaxSize) + 1
|
|
da := lnwire.DeliveryAddress(make([]byte, size))
|
|
|
|
_, err := r.Read(da)
|
|
require.NoError(t, err, "unable to read address")
|
|
return da
|
|
}
|
|
|
|
func randTCP4Addr(t testing.TB, r *rand.Rand) *net.TCPAddr {
|
|
t.Helper()
|
|
|
|
var ip [4]byte
|
|
_, err := r.Read(ip[:])
|
|
require.NoError(t, err, "unable to read ip")
|
|
|
|
var port [2]byte
|
|
_, err = r.Read(port[:])
|
|
require.NoError(t, err, "unable to read port")
|
|
|
|
addrIP := net.IP(ip[:])
|
|
addrPort := int(binary.BigEndian.Uint16(port[:]))
|
|
|
|
return &net.TCPAddr{IP: addrIP, Port: addrPort}
|
|
}
|
|
|
|
func randTCP6Addr(t testing.TB, r *rand.Rand) *net.TCPAddr {
|
|
t.Helper()
|
|
|
|
var ip [16]byte
|
|
|
|
_, err := r.Read(ip[:])
|
|
require.NoError(t, err, "unable to read ip")
|
|
|
|
var port [2]byte
|
|
_, err = r.Read(port[:])
|
|
require.NoError(t, err, "unable to read port")
|
|
|
|
addrIP := net.IP(ip[:])
|
|
addrPort := int(binary.BigEndian.Uint16(port[:]))
|
|
|
|
return &net.TCPAddr{IP: addrIP, Port: addrPort}
|
|
}
|
|
|
|
func randV2OnionAddr(t testing.TB, r *rand.Rand) *tor.OnionAddr {
|
|
t.Helper()
|
|
|
|
var serviceID [tor.V2DecodedLen]byte
|
|
_, err := r.Read(serviceID[:])
|
|
require.NoError(t, err, "unable to read serviceID")
|
|
|
|
var port [2]byte
|
|
_, err = r.Read(port[:])
|
|
require.NoError(t, err, "unable to read port")
|
|
|
|
onionService := tor.Base32Encoding.EncodeToString(serviceID[:])
|
|
onionService += tor.OnionSuffix
|
|
addrPort := int(binary.BigEndian.Uint16(port[:]))
|
|
|
|
return &tor.OnionAddr{OnionService: onionService, Port: addrPort}
|
|
}
|
|
|
|
func randV3OnionAddr(t testing.TB, r *rand.Rand) *tor.OnionAddr {
|
|
t.Helper()
|
|
|
|
var serviceID [tor.V3DecodedLen]byte
|
|
_, err := r.Read(serviceID[:])
|
|
require.NoError(t, err, "unable to read serviceID")
|
|
|
|
var port [2]byte
|
|
_, err = r.Read(port[:])
|
|
require.NoError(t, err, "unable to read port")
|
|
|
|
onionService := tor.Base32Encoding.EncodeToString(serviceID[:])
|
|
onionService += tor.OnionSuffix
|
|
addrPort := int(binary.BigEndian.Uint16(port[:]))
|
|
|
|
return &tor.OnionAddr{OnionService: onionService, Port: addrPort}
|
|
}
|
|
|
|
func randAddrs(t testing.TB, r *rand.Rand) []net.Addr {
|
|
tcp4Addr := randTCP4Addr(t, r)
|
|
tcp6Addr := randTCP6Addr(t, r)
|
|
v2OnionAddr := randV2OnionAddr(t, r)
|
|
v3OnionAddr := randV3OnionAddr(t, r)
|
|
|
|
return []net.Addr{tcp4Addr, tcp6Addr, v2OnionAddr, v3OnionAddr}
|
|
}
|
|
|
|
func randAlias(r *rand.Rand) lnwire.NodeAlias {
|
|
var a lnwire.NodeAlias
|
|
for i := range a {
|
|
a[i] = letterBytes[r.Intn(len(letterBytes))]
|
|
}
|
|
|
|
return a
|
|
}
|
|
|
|
func createExtraData(t testing.TB, r io.Reader) []byte {
|
|
t.Helper()
|
|
|
|
// Read random bytes.
|
|
extraData := make([]byte, testNumExtraBytes)
|
|
_, err := r.Read(extraData)
|
|
require.NoError(t, err, "unable to generate extra data")
|
|
|
|
// Encode the data length.
|
|
binary.BigEndian.PutUint16(extraData[:2], uint16(len(extraData[2:])))
|
|
|
|
return extraData
|
|
}
|