package lnwire import ( "bytes" "fmt" "image/color" "math" "github.com/btcsuite/btcd/btcec/v2" "github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/lightningnetwork/lnd/fn/v2" "github.com/lightningnetwork/lnd/lnwallet/chainfee" "github.com/lightningnetwork/lnd/tlv" "github.com/stretchr/testify/require" "pgregory.net/rapid" ) // TestMessage is an interface that extends the base Message interface with a // method to populate the message with random testing data. type TestMessage interface { Message // RandTestMessage populates the message with random data suitable for // testing. It uses the rapid testing framework to generate random // values. RandTestMessage(t *rapid.T) Message } // A compile time check to ensure AcceptChannel implements the TestMessage // interface. var _ TestMessage = (*AcceptChannel)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (a *AcceptChannel) RandTestMessage(t *rapid.T) Message { var pendingChanID [32]byte pendingChanIDBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw( t, "pendingChanID", ) copy(pendingChanID[:], pendingChanIDBytes) var channelType *ChannelType includeChannelType := rapid.Bool().Draw(t, "includeChannelType") includeLeaseExpiry := rapid.Bool().Draw(t, "includeLeaseExpiry") includeLocalNonce := rapid.Bool().Draw(t, "includeLocalNonce") if includeChannelType { channelType = RandChannelType(t) } var leaseExpiry *LeaseExpiry if includeLeaseExpiry { leaseExpiry = RandLeaseExpiry(t) } var localNonce OptMusig2NonceTLV if includeLocalNonce { nonce := RandMusig2Nonce(t) localNonce = tlv.SomeRecordT( tlv.NewRecordT[NonceRecordTypeT, Musig2Nonce](nonce), ) } return &AcceptChannel{ PendingChannelID: pendingChanID, DustLimit: btcutil.Amount( rapid.IntRange(100, 1000).Draw(t, "dustLimit"), ), MaxValueInFlight: MilliSatoshi( rapid.IntRange(10000, 1000000).Draw( t, "maxValueInFlight", ), ), ChannelReserve: btcutil.Amount( rapid.IntRange(1000, 10000).Draw(t, "channelReserve"), ), HtlcMinimum: MilliSatoshi( rapid.IntRange(1, 1000).Draw(t, "htlcMinimum"), ), MinAcceptDepth: uint32( rapid.IntRange(1, 10).Draw(t, "minAcceptDepth"), ), CsvDelay: uint16( rapid.IntRange(144, 1000).Draw(t, "csvDelay"), ), MaxAcceptedHTLCs: uint16( rapid.IntRange(10, 500).Draw(t, "maxAcceptedHTLCs"), ), FundingKey: RandPubKey(t), RevocationPoint: RandPubKey(t), PaymentPoint: RandPubKey(t), DelayedPaymentPoint: RandPubKey(t), HtlcPoint: RandPubKey(t), FirstCommitmentPoint: RandPubKey(t), UpfrontShutdownScript: RandDeliveryAddress(t), ChannelType: channelType, LeaseExpiry: leaseExpiry, LocalNonce: localNonce, ExtraData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure AnnounceSignatures1 implements the // lnwire.TestMessage interface. var _ TestMessage = (*AnnounceSignatures1)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (a *AnnounceSignatures1) RandTestMessage(t *rapid.T) Message { return &AnnounceSignatures1{ ChannelID: RandChannelID(t), ShortChannelID: RandShortChannelID(t), NodeSignature: RandSignature(t), BitcoinSignature: RandSignature(t), ExtraOpaqueData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure AnnounceSignatures2 implements the // lnwire.TestMessage interface. var _ TestMessage = (*AnnounceSignatures2)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (a *AnnounceSignatures2) RandTestMessage(t *rapid.T) Message { return &AnnounceSignatures2{ ChannelID: RandChannelID(t), ShortChannelID: RandShortChannelID(t), PartialSignature: *RandPartialSig(t), ExtraOpaqueData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure ChannelAnnouncement1 implements the // TestMessage interface. var _ TestMessage = (*ChannelAnnouncement1)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (a *ChannelAnnouncement1) RandTestMessage(t *rapid.T) Message { // Generate Node IDs and Bitcoin keys (compressed public keys) node1PubKey := RandPubKey(t) node2PubKey := RandPubKey(t) bitcoin1PubKey := RandPubKey(t) bitcoin2PubKey := RandPubKey(t) // Convert to byte arrays var nodeID1, nodeID2, bitcoinKey1, bitcoinKey2 [33]byte copy(nodeID1[:], node1PubKey.SerializeCompressed()) copy(nodeID2[:], node2PubKey.SerializeCompressed()) copy(bitcoinKey1[:], bitcoin1PubKey.SerializeCompressed()) copy(bitcoinKey2[:], bitcoin2PubKey.SerializeCompressed()) // Ensure nodeID1 is numerically less than nodeID2 // This is a requirement stated in the field description if bytes.Compare(nodeID1[:], nodeID2[:]) > 0 { nodeID1, nodeID2 = nodeID2, nodeID1 } // Generate chain hash chainHash := RandChainHash(t) var hash chainhash.Hash copy(hash[:], chainHash[:]) return &ChannelAnnouncement1{ NodeSig1: RandSignature(t), NodeSig2: RandSignature(t), BitcoinSig1: RandSignature(t), BitcoinSig2: RandSignature(t), Features: RandFeatureVector(t), ChainHash: hash, ShortChannelID: RandShortChannelID(t), NodeID1: nodeID1, NodeID2: nodeID2, BitcoinKey1: bitcoinKey1, BitcoinKey2: bitcoinKey2, ExtraOpaqueData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure ChannelAnnouncement2 implements the // lnwire.TestMessage interface. var _ TestMessage = (*ChannelAnnouncement2)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *ChannelAnnouncement2) RandTestMessage(t *rapid.T) Message { features := RandFeatureVector(t) shortChanID := RandShortChannelID(t) capacity := uint64(rapid.IntRange(1, 16777215).Draw(t, "capacity")) var nodeID1, nodeID2 [33]byte copy(nodeID1[:], RandPubKey(t).SerializeCompressed()) copy(nodeID2[:], RandPubKey(t).SerializeCompressed()) // Make sure nodeID1 is numerically less than nodeID2 (as per spec). if bytes.Compare(nodeID1[:], nodeID2[:]) > 0 { nodeID1, nodeID2 = nodeID2, nodeID1 } chainHash := RandChainHash(t) var chainHashObj chainhash.Hash copy(chainHashObj[:], chainHash[:]) msg := &ChannelAnnouncement2{ Signature: RandSignature(t), ChainHash: tlv.NewPrimitiveRecord[tlv.TlvType0, chainhash.Hash]( chainHashObj, ), Features: tlv.NewRecordT[tlv.TlvType2, RawFeatureVector]( *features, ), ShortChannelID: tlv.NewRecordT[tlv.TlvType4, ShortChannelID]( shortChanID, ), Capacity: tlv.NewPrimitiveRecord[tlv.TlvType6, uint64]( capacity, ), NodeID1: tlv.NewPrimitiveRecord[tlv.TlvType8, [33]byte]( nodeID1, ), NodeID2: tlv.NewPrimitiveRecord[tlv.TlvType10, [33]byte]( nodeID2, ), ExtraOpaqueData: RandExtraOpaqueData(t, nil), } msg.Signature.ForceSchnorr() // Randomly include optional fields if rapid.Bool().Draw(t, "includeBitcoinKey1") { var bitcoinKey1 [33]byte copy(bitcoinKey1[:], RandPubKey(t).SerializeCompressed()) msg.BitcoinKey1 = tlv.SomeRecordT( tlv.NewPrimitiveRecord[tlv.TlvType12, [33]byte]( bitcoinKey1, ), ) } if rapid.Bool().Draw(t, "includeBitcoinKey2") { var bitcoinKey2 [33]byte copy(bitcoinKey2[:], RandPubKey(t).SerializeCompressed()) msg.BitcoinKey2 = tlv.SomeRecordT( tlv.NewPrimitiveRecord[tlv.TlvType14, [33]byte]( bitcoinKey2, ), ) } if rapid.Bool().Draw(t, "includeMerkleRootHash") { hash := RandSHA256Hash(t) var merkleRootHash [32]byte copy(merkleRootHash[:], hash[:]) msg.MerkleRootHash = tlv.SomeRecordT( tlv.NewPrimitiveRecord[tlv.TlvType16, [32]byte]( merkleRootHash, ), ) } return msg } // A compile time check to ensure ChannelReady implements the lnwire.TestMessage // interface. var _ TestMessage = (*ChannelReady)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *ChannelReady) RandTestMessage(t *rapid.T) Message { msg := &ChannelReady{ ChanID: RandChannelID(t), NextPerCommitmentPoint: RandPubKey(t), ExtraData: RandExtraOpaqueData(t, nil), } includeAliasScid := rapid.Bool().Draw(t, "includeAliasScid") includeNextLocalNonce := rapid.Bool().Draw(t, "includeNextLocalNonce") includeAnnouncementNodeNonce := rapid.Bool().Draw( t, "includeAnnouncementNodeNonce", ) includeAnnouncementBitcoinNonce := rapid.Bool().Draw( t, "includeAnnouncementBitcoinNonce", ) if includeAliasScid { scid := RandShortChannelID(t) msg.AliasScid = &scid } if includeNextLocalNonce { nonce := RandMusig2Nonce(t) msg.NextLocalNonce = SomeMusig2Nonce(nonce) } if includeAnnouncementNodeNonce { nonce := RandMusig2Nonce(t) msg.AnnouncementNodeNonce = tlv.SomeRecordT( tlv.NewRecordT[tlv.TlvType0, Musig2Nonce](nonce), ) } if includeAnnouncementBitcoinNonce { nonce := RandMusig2Nonce(t) msg.AnnouncementBitcoinNonce = tlv.SomeRecordT( tlv.NewRecordT[tlv.TlvType2, Musig2Nonce](nonce), ) } return msg } // A compile time check to ensure ChannelReestablish implements the // lnwire.TestMessage interface. var _ TestMessage = (*ChannelReestablish)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (a *ChannelReestablish) RandTestMessage(t *rapid.T) Message { msg := &ChannelReestablish{ ChanID: RandChannelID(t), NextLocalCommitHeight: rapid.Uint64().Draw( t, "nextLocalCommitHeight", ), RemoteCommitTailHeight: rapid.Uint64().Draw( t, "remoteCommitTailHeight", ), LastRemoteCommitSecret: RandPaymentPreimage(t), LocalUnrevokedCommitPoint: RandPubKey(t), ExtraData: RandExtraOpaqueData(t, nil), } // Randomly decide whether to include optional fields includeLocalNonce := rapid.Bool().Draw(t, "includeLocalNonce") includeDynHeight := rapid.Bool().Draw(t, "includeDynHeight") if includeLocalNonce { nonce := RandMusig2Nonce(t) msg.LocalNonce = SomeMusig2Nonce(nonce) } if includeDynHeight { height := DynHeight(rapid.Uint64().Draw(t, "dynHeight")) msg.DynHeight = fn.Some(height) } return msg } // A compile time check to ensure ChannelUpdate1 implements the TestMessage // interface. var _ TestMessage = (*ChannelUpdate1)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (a *ChannelUpdate1) RandTestMessage(t *rapid.T) Message { // Generate random message flags // Randomly decide whether to include max HTLC field includeMaxHtlc := rapid.Bool().Draw(t, "includeMaxHtlc") var msgFlags ChanUpdateMsgFlags if includeMaxHtlc { msgFlags |= ChanUpdateRequiredMaxHtlc } // Generate random channel flags // Randomly decide direction (node1 or node2) isNode2 := rapid.Bool().Draw(t, "isNode2") var chanFlags ChanUpdateChanFlags if isNode2 { chanFlags |= ChanUpdateDirection } // Randomly decide if channel is disabled isDisabled := rapid.Bool().Draw(t, "isDisabled") if isDisabled { chanFlags |= ChanUpdateDisabled } // Generate chain hash chainHash := RandChainHash(t) var hash chainhash.Hash copy(hash[:], chainHash[:]) // Generate other random fields maxHtlc := MilliSatoshi(rapid.Uint64().Draw(t, "maxHtlc")) // If max HTLC flag is not set, we need to zero the value if !includeMaxHtlc { maxHtlc = 0 } // Randomly decide if an inbound fee should be included. // By default, our extra opaque data will just be random TLV but if we // include an inbound fee, then we will also set the record in the // extra opaque data. var ( customRecords, _ = RandCustomRecords(t, nil, false) inboundFee tlv.OptionalRecordT[tlv.TlvType55555, Fee] ) includeInboundFee := rapid.Bool().Draw(t, "includeInboundFee") if includeInboundFee { if customRecords == nil { customRecords = make(CustomRecords) } inFeeBase := int32( rapid.IntRange(-1000, 1000).Draw(t, "inFeeBase"), ) inFeeProp := int32( rapid.IntRange(-1000, 1000).Draw(t, "inFeeProp"), ) fee := Fee{ BaseFee: inFeeBase, FeeRate: inFeeProp, } inboundFee = tlv.SomeRecordT( tlv.NewRecordT[tlv.TlvType55555, Fee](fee), ) var b bytes.Buffer feeRecord := fee.Record() err := feeRecord.Encode(&b) require.NoError(t, err) customRecords[uint64(FeeRecordType)] = b.Bytes() } extraBytes, err := customRecords.Serialize() require.NoError(t, err) return &ChannelUpdate1{ Signature: RandSignature(t), ChainHash: hash, ShortChannelID: RandShortChannelID(t), Timestamp: uint32(rapid.IntRange(0, 0x7FFFFFFF).Draw( t, "timestamp"), ), MessageFlags: msgFlags, ChannelFlags: chanFlags, TimeLockDelta: uint16(rapid.IntRange(0, 65535).Draw( t, "timelockDelta"), ), HtlcMinimumMsat: MilliSatoshi(rapid.Uint64().Draw( t, "htlcMinimum"), ), BaseFee: uint32(rapid.IntRange(0, 0x7FFFFFFF).Draw( t, "baseFee"), ), FeeRate: uint32(rapid.IntRange(0, 0x7FFFFFFF).Draw( t, "feeRate"), ), HtlcMaximumMsat: maxHtlc, InboundFee: inboundFee, ExtraOpaqueData: extraBytes, } } // A compile time check to ensure ChannelUpdate2 implements the // lnwire.TestMessage interface. var _ TestMessage = (*ChannelUpdate2)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *ChannelUpdate2) RandTestMessage(t *rapid.T) Message { shortChanID := RandShortChannelID(t) blockHeight := uint32(rapid.IntRange(0, 1000000).Draw(t, "blockHeight")) var disabledFlags ChanUpdateDisableFlags if rapid.Bool().Draw(t, "disableIncoming") { disabledFlags |= ChanUpdateDisableIncoming } if rapid.Bool().Draw(t, "disableOutgoing") { disabledFlags |= ChanUpdateDisableOutgoing } cltvExpiryDelta := uint16(rapid.IntRange(10, 200).Draw( t, "cltvExpiryDelta"), ) htlcMinMsat := MilliSatoshi(rapid.IntRange(1, 10000).Draw( t, "htlcMinMsat"), ) htlcMaxMsat := MilliSatoshi(rapid.IntRange(10000, 100000000).Draw( t, "htlcMaxMsat"), ) feeBaseMsat := uint32(rapid.IntRange(0, 10000).Draw(t, "feeBaseMsat")) feeProportionalMillionths := uint32(rapid.IntRange(0, 10000).Draw( t, "feeProportionalMillionths"), ) chainHash := RandChainHash(t) var chainHashObj chainhash.Hash copy(chainHashObj[:], chainHash[:]) //nolint:ll msg := &ChannelUpdate2{ Signature: RandSignature(t), ChainHash: tlv.NewPrimitiveRecord[tlv.TlvType0, chainhash.Hash]( chainHashObj, ), ShortChannelID: tlv.NewRecordT[tlv.TlvType2, ShortChannelID]( shortChanID, ), BlockHeight: tlv.NewPrimitiveRecord[tlv.TlvType4, uint32]( blockHeight, ), DisabledFlags: tlv.NewPrimitiveRecord[tlv.TlvType6, ChanUpdateDisableFlags]( //nolint:ll disabledFlags, ), CLTVExpiryDelta: tlv.NewPrimitiveRecord[tlv.TlvType10, uint16]( cltvExpiryDelta, ), HTLCMinimumMsat: tlv.NewPrimitiveRecord[tlv.TlvType12, MilliSatoshi]( htlcMinMsat, ), HTLCMaximumMsat: tlv.NewPrimitiveRecord[tlv.TlvType14, MilliSatoshi]( htlcMaxMsat, ), FeeBaseMsat: tlv.NewPrimitiveRecord[tlv.TlvType16, uint32]( feeBaseMsat, ), FeeProportionalMillionths: tlv.NewPrimitiveRecord[tlv.TlvType18, uint32]( feeProportionalMillionths, ), ExtraOpaqueData: RandExtraOpaqueData(t, nil), } msg.Signature.ForceSchnorr() if rapid.Bool().Draw(t, "isSecondPeer") { msg.SecondPeer = tlv.SomeRecordT( tlv.RecordT[tlv.TlvType8, TrueBoolean]{}, ) } return msg } // A compile time check to ensure ClosingComplete implements the // lnwire.TestMessage interface. var _ TestMessage = (*ClosingComplete)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *ClosingComplete) RandTestMessage(t *rapid.T) Message { msg := &ClosingComplete{ ChannelID: RandChannelID(t), FeeSatoshis: btcutil.Amount(rapid.Int64Range(0, 1000000).Draw( t, "feeSatoshis"), ), LockTime: rapid.Uint32Range(0, 0xffffffff).Draw( t, "lockTime", ), CloseeScript: RandDeliveryAddress(t), CloserScript: RandDeliveryAddress(t), ExtraData: RandExtraOpaqueData(t, nil), } includeCloserNoClosee := rapid.Bool().Draw(t, "includeCloserNoClosee") includeNoCloserClosee := rapid.Bool().Draw(t, "includeNoCloserClosee") includeCloserAndClosee := rapid.Bool().Draw(t, "includeCloserAndClosee") // Ensure at least one signature is present. if !includeCloserNoClosee && !includeNoCloserClosee && !includeCloserAndClosee { // If all are false, enable at least one randomly. choice := rapid.IntRange(0, 2).Draw(t, "sigChoice") switch choice { case 0: includeCloserNoClosee = true case 1: includeNoCloserClosee = true case 2: includeCloserAndClosee = true } } if includeCloserNoClosee { sig := RandSignature(t) msg.CloserNoClosee = tlv.SomeRecordT( tlv.NewRecordT[tlv.TlvType1, Sig](sig), ) } if includeNoCloserClosee { sig := RandSignature(t) msg.NoCloserClosee = tlv.SomeRecordT( tlv.NewRecordT[tlv.TlvType2, Sig](sig), ) } if includeCloserAndClosee { sig := RandSignature(t) msg.CloserAndClosee = tlv.SomeRecordT( tlv.NewRecordT[tlv.TlvType3, Sig](sig), ) } return msg } // A compile time check to ensure ClosingSig implements the lnwire.TestMessage // interface. var _ TestMessage = (*ClosingSig)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *ClosingSig) RandTestMessage(t *rapid.T) Message { msg := &ClosingSig{ ChannelID: RandChannelID(t), CloseeScript: RandDeliveryAddress(t), CloserScript: RandDeliveryAddress(t), ExtraData: RandExtraOpaqueData(t, nil), } includeCloserNoClosee := rapid.Bool().Draw(t, "includeCloserNoClosee") includeNoCloserClosee := rapid.Bool().Draw(t, "includeNoCloserClosee") includeCloserAndClosee := rapid.Bool().Draw(t, "includeCloserAndClosee") // Ensure at least one signature is present. if !includeCloserNoClosee && !includeNoCloserClosee && !includeCloserAndClosee { // If all are false, enable at least one randomly. choice := rapid.IntRange(0, 2).Draw(t, "sigChoice") switch choice { case 0: includeCloserNoClosee = true case 1: includeNoCloserClosee = true case 2: includeCloserAndClosee = true } } if includeCloserNoClosee { sig := RandSignature(t) msg.CloserNoClosee = tlv.SomeRecordT( tlv.NewRecordT[tlv.TlvType1, Sig](sig), ) } if includeNoCloserClosee { sig := RandSignature(t) msg.NoCloserClosee = tlv.SomeRecordT( tlv.NewRecordT[tlv.TlvType2, Sig](sig), ) } if includeCloserAndClosee { sig := RandSignature(t) msg.CloserAndClosee = tlv.SomeRecordT( tlv.NewRecordT[tlv.TlvType3, Sig](sig), ) } return msg } // A compile time check to ensure ClosingSigned implements the // lnwire.TestMessage interface. var _ TestMessage = (*ClosingSigned)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *ClosingSigned) RandTestMessage(t *rapid.T) Message { // Generate a random boolean to decide whether to include CommitSig or // PartialSig Since they're mutually exclusive, when one is populated, // the other must be blank. usePartialSig := rapid.Bool().Draw(t, "usePartialSig") msg := &ClosingSigned{ ChannelID: RandChannelID(t), FeeSatoshis: btcutil.Amount( rapid.Int64Range(0, 1000000).Draw(t, "feeSatoshis"), ), ExtraData: RandExtraOpaqueData(t, nil), } if usePartialSig { sigBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw( t, "sigScalar", ) var s btcec.ModNScalar _ = s.SetByteSlice(sigBytes) msg.PartialSig = SomePartialSig(NewPartialSig(s)) msg.Signature = Sig{} } else { msg.Signature = RandSignature(t) } return msg } // A compile time check to ensure CommitSig implements the lnwire.TestMessage // interface. var _ TestMessage = (*CommitSig)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *CommitSig) RandTestMessage(t *rapid.T) Message { cr, _ := RandCustomRecords(t, nil, true) sig := &CommitSig{ ChanID: RandChannelID(t), CommitSig: RandSignature(t), CustomRecords: cr, } numHtlcSigs := rapid.IntRange(0, 20).Draw(t, "numHtlcSigs") htlcSigs := make([]Sig, numHtlcSigs) for i := 0; i < numHtlcSigs; i++ { htlcSigs[i] = RandSignature(t) } if len(htlcSigs) > 0 { sig.HtlcSigs = htlcSigs } includePartialSig := rapid.Bool().Draw(t, "includePartialSig") if includePartialSig { sigWithNonce := RandPartialSigWithNonce(t) sig.PartialSig = MaybePartialSigWithNonce(sigWithNonce) } return sig } // A compile time check to ensure Custom implements the lnwire.TestMessage // interface. var _ TestMessage = (*Custom)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *Custom) RandTestMessage(t *rapid.T) Message { msgType := MessageType( rapid.IntRange(int(CustomTypeStart), 65535).Draw( t, "customMsgType", ), ) dataLen := rapid.IntRange(0, 1000).Draw(t, "customDataLength") data := rapid.SliceOfN(rapid.Byte(), dataLen, dataLen).Draw( t, "customData", ) msg, err := NewCustom(msgType, data) if err != nil { panic(fmt.Sprintf("Error creating custom message: %v", err)) } return msg } // A compile time check to ensure DynAck implements the lnwire.TestMessage // interface. var _ TestMessage = (*DynAck)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (da *DynAck) RandTestMessage(t *rapid.T) Message { msg := &DynAck{ ChanID: RandChannelID(t), ExtraData: RandExtraOpaqueData(t, nil), } includeLocalNonce := rapid.Bool().Draw(t, "includeLocalNonce") if includeLocalNonce { msg.LocalNonce = fn.Some(RandMusig2Nonce(t)) } return msg } // A compile time check to ensure DynPropose implements the lnwire.TestMessage // interface. var _ TestMessage = (*DynPropose)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (dp *DynPropose) RandTestMessage(t *rapid.T) Message { msg := &DynPropose{ ChanID: RandChannelID(t), Initiator: rapid.Bool().Draw(t, "initiator"), ExtraData: RandExtraOpaqueData(t, nil), } // Randomly decide which optional fields to include includeDustLimit := rapid.Bool().Draw(t, "includeDustLimit") includeMaxValueInFlight := rapid.Bool().Draw( t, "includeMaxValueInFlight", ) includeChannelReserve := rapid.Bool().Draw(t, "includeChannelReserve") includeCsvDelay := rapid.Bool().Draw(t, "includeCsvDelay") includeMaxAcceptedHTLCs := rapid.Bool().Draw( t, "includeMaxAcceptedHTLCs", ) includeFundingKey := rapid.Bool().Draw(t, "includeFundingKey") includeChannelType := rapid.Bool().Draw(t, "includeChannelType") includeKickoffFeerate := rapid.Bool().Draw(t, "includeKickoffFeerate") // Generate random values for each included field if includeDustLimit { dl := btcutil.Amount(rapid.Uint32().Draw(t, "dustLimit")) msg.DustLimit = fn.Some(dl) } if includeMaxValueInFlight { mvif := MilliSatoshi(rapid.Uint64().Draw(t, "maxValueInFlight")) msg.MaxValueInFlight = fn.Some(mvif) } if includeChannelReserve { cr := btcutil.Amount(rapid.Uint32().Draw(t, "channelReserve")) msg.ChannelReserve = fn.Some(cr) } if includeCsvDelay { cd := rapid.Uint16().Draw(t, "csvDelay") msg.CsvDelay = fn.Some(cd) } if includeMaxAcceptedHTLCs { mah := rapid.Uint16().Draw(t, "maxAcceptedHTLCs") msg.MaxAcceptedHTLCs = fn.Some(mah) } if includeFundingKey { msg.FundingKey = fn.Some(*RandPubKey(t)) } if includeChannelType { msg.ChannelType = fn.Some(*RandChannelType(t)) } if includeKickoffFeerate { kf := chainfee.SatPerKWeight(rapid.Uint32().Draw( t, "kickoffFeerate"), ) msg.KickoffFeerate = fn.Some(kf) } return msg } // A compile time check to ensure DynReject implements the lnwire.TestMessage // interface. var _ TestMessage = (*DynReject)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (dr *DynReject) RandTestMessage(t *rapid.T) Message { featureVec := NewRawFeatureVector() numFeatures := rapid.IntRange(0, 8).Draw(t, "numRejections") for i := 0; i < numFeatures; i++ { bit := FeatureBit( rapid.IntRange(0, 31).Draw( t, fmt.Sprintf("rejectionBit-%d", i), ), ) featureVec.Set(bit) } var extraData ExtraOpaqueData randData := RandExtraOpaqueData(t, nil) if len(randData) > 0 { extraData = randData } return &DynReject{ ChanID: RandChannelID(t), UpdateRejections: *featureVec, ExtraData: extraData, } } // A compile time check to ensure FundingCreated implements the TestMessage // interface. var _ TestMessage = (*FundingCreated)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (f *FundingCreated) RandTestMessage(t *rapid.T) Message { var pendingChanID [32]byte pendingChanIDBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw( t, "pendingChanID", ) copy(pendingChanID[:], pendingChanIDBytes) includePartialSig := rapid.Bool().Draw(t, "includePartialSig") var partialSig OptPartialSigWithNonceTLV var commitSig Sig if includePartialSig { sigWithNonce := RandPartialSigWithNonce(t) partialSig = MaybePartialSigWithNonce(sigWithNonce) // When using partial sig, CommitSig should be empty/blank. commitSig = Sig{} } else { commitSig = RandSignature(t) } return &FundingCreated{ PendingChannelID: pendingChanID, FundingPoint: RandOutPoint(t), CommitSig: commitSig, PartialSig: partialSig, ExtraData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure FundingSigned implements the // lnwire.TestMessage interface. var _ TestMessage = (*FundingSigned)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (f *FundingSigned) RandTestMessage(t *rapid.T) Message { usePartialSig := rapid.Bool().Draw(t, "usePartialSig") msg := &FundingSigned{ ChanID: RandChannelID(t), ExtraData: RandExtraOpaqueData(t, nil), } if usePartialSig { sigWithNonce := RandPartialSigWithNonce(t) msg.PartialSig = MaybePartialSigWithNonce(sigWithNonce) msg.CommitSig = Sig{} } else { msg.CommitSig = RandSignature(t) } return msg } // A compile time check to ensure GossipTimestampRange implements the // lnwire.TestMessage interface. var _ TestMessage = (*GossipTimestampRange)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (g *GossipTimestampRange) RandTestMessage(t *rapid.T) Message { var chainHash chainhash.Hash hashBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "chainHash") copy(chainHash[:], hashBytes) msg := &GossipTimestampRange{ ChainHash: chainHash, FirstTimestamp: rapid.Uint32().Draw(t, "firstTimestamp"), TimestampRange: rapid.Uint32().Draw(t, "timestampRange"), ExtraData: RandExtraOpaqueData(t, nil), } includeFirstBlockHeight := rapid.Bool().Draw( t, "includeFirstBlockHeight", ) includeBlockRange := rapid.Bool().Draw(t, "includeBlockRange") if includeFirstBlockHeight { height := rapid.Uint32().Draw(t, "firstBlockHeight") msg.FirstBlockHeight = tlv.SomeRecordT( tlv.RecordT[tlv.TlvType2, uint32]{Val: height}, ) } if includeBlockRange { blockRange := rapid.Uint32().Draw(t, "blockRange") msg.BlockRange = tlv.SomeRecordT( tlv.RecordT[tlv.TlvType4, uint32]{Val: blockRange}, ) } return msg } // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (msg *Init) RandTestMessage(t *rapid.T) Message { global := NewRawFeatureVector() local := NewRawFeatureVector() numGlobalFeatures := rapid.IntRange(0, 20).Draw(t, "numGlobalFeatures") for i := 0; i < numGlobalFeatures; i++ { bit := FeatureBit( rapid.IntRange(0, 100).Draw( t, fmt.Sprintf("globalFeatureBit%d", i), ), ) global.Set(bit) } numLocalFeatures := rapid.IntRange(0, 20).Draw(t, "numLocalFeatures") for i := 0; i < numLocalFeatures; i++ { bit := FeatureBit( rapid.IntRange(0, 100).Draw( t, fmt.Sprintf("localFeatureBit%d", i), ), ) local.Set(bit) } return NewInitMessage(global, local) } // A compile time check to ensure KickoffSig implements the lnwire.TestMessage // interface. var _ TestMessage = (*KickoffSig)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (ks *KickoffSig) RandTestMessage(t *rapid.T) Message { return &KickoffSig{ ChanID: RandChannelID(t), Signature: RandSignature(t), ExtraData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure NodeAnnouncement implements the // lnwire.TestMessage interface. var _ TestMessage = (*NodeAnnouncement)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (a *NodeAnnouncement) RandTestMessage(t *rapid.T) Message { // Generate random compressed public key for node ID pubKey := RandPubKey(t) var nodeID [33]byte copy(nodeID[:], pubKey.SerializeCompressed()) // Generate random RGB color rgbColor := color.RGBA{ R: uint8(rapid.IntRange(0, 255).Draw(t, "rgbR")), G: uint8(rapid.IntRange(0, 255).Draw(t, "rgbG")), B: uint8(rapid.IntRange(0, 255).Draw(t, "rgbB")), } return &NodeAnnouncement{ Signature: RandSignature(t), Features: RandFeatureVector(t), Timestamp: uint32(rapid.IntRange(0, 0x7FFFFFFF).Draw( t, "timestamp"), ), NodeID: nodeID, RGBColor: rgbColor, Alias: RandNodeAlias(t), Addresses: RandNetAddrs(t), ExtraOpaqueData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure OpenChannel implements the TestMessage // interface. var _ TestMessage = (*OpenChannel)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (o *OpenChannel) RandTestMessage(t *rapid.T) Message { chainHash := RandChainHash(t) var hash chainhash.Hash copy(hash[:], chainHash[:]) var pendingChanID [32]byte pendingChanIDBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw( t, "pendingChanID", ) copy(pendingChanID[:], pendingChanIDBytes) includeChannelType := rapid.Bool().Draw(t, "includeChannelType") includeLeaseExpiry := rapid.Bool().Draw(t, "includeLeaseExpiry") includeLocalNonce := rapid.Bool().Draw(t, "includeLocalNonce") var channelFlags FundingFlag if rapid.Bool().Draw(t, "announceChannel") { channelFlags |= FFAnnounceChannel } var localNonce OptMusig2NonceTLV if includeLocalNonce { nonce := RandMusig2Nonce(t) localNonce = tlv.SomeRecordT( tlv.NewRecordT[NonceRecordTypeT, Musig2Nonce](nonce), ) } var channelType *ChannelType if includeChannelType { channelType = RandChannelType(t) } var leaseExpiry *LeaseExpiry if includeLeaseExpiry { leaseExpiry = RandLeaseExpiry(t) } return &OpenChannel{ ChainHash: hash, PendingChannelID: pendingChanID, FundingAmount: btcutil.Amount( rapid.IntRange(5000, 10000000).Draw(t, "fundingAmount"), ), PushAmount: MilliSatoshi( rapid.IntRange(0, 1000000).Draw(t, "pushAmount"), ), DustLimit: btcutil.Amount( rapid.IntRange(100, 1000).Draw(t, "dustLimit"), ), MaxValueInFlight: MilliSatoshi( rapid.IntRange(10000, 1000000).Draw( t, "maxValueInFlight", ), ), ChannelReserve: btcutil.Amount( rapid.IntRange(1000, 10000).Draw(t, "channelReserve"), ), HtlcMinimum: MilliSatoshi( rapid.IntRange(1, 1000).Draw(t, "htlcMinimum"), ), FeePerKiloWeight: uint32( rapid.IntRange(250, 10000).Draw(t, "feePerKw"), ), CsvDelay: uint16( rapid.IntRange(144, 1000).Draw(t, "csvDelay"), ), MaxAcceptedHTLCs: uint16( rapid.IntRange(10, 500).Draw(t, "maxAcceptedHTLCs"), ), FundingKey: RandPubKey(t), RevocationPoint: RandPubKey(t), PaymentPoint: RandPubKey(t), DelayedPaymentPoint: RandPubKey(t), HtlcPoint: RandPubKey(t), FirstCommitmentPoint: RandPubKey(t), ChannelFlags: channelFlags, UpfrontShutdownScript: RandDeliveryAddress(t), ChannelType: channelType, LeaseExpiry: leaseExpiry, LocalNonce: localNonce, ExtraData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure Ping implements the lnwire.TestMessage // interface. var _ TestMessage = (*Ping)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (p *Ping) RandTestMessage(t *rapid.T) Message { numPongBytes := uint16(rapid.IntRange(0, int(MaxPongBytes)).Draw( t, "numPongBytes"), ) // Generate padding bytes (but keeping within allowed message size) // MaxMsgBody - 2 (for NumPongBytes) - 2 (for padding length) maxPaddingLen := MaxMsgBody - 4 paddingLen := rapid.IntRange(0, maxPaddingLen).Draw( t, "paddingLen", ) padding := make(PingPayload, paddingLen) // Fill padding with random bytes for i := 0; i < paddingLen; i++ { padding[i] = byte(rapid.IntRange(0, 255).Draw( t, fmt.Sprintf("paddingByte%d", i)), ) } return &Ping{ NumPongBytes: numPongBytes, PaddingBytes: padding, } } // A compile time check to ensure Pong implements the lnwire.TestMessage // interface. var _ TestMessage = (*Pong)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (p *Pong) RandTestMessage(t *rapid.T) Message { payloadLen := rapid.IntRange(0, 1000).Draw(t, "pongPayloadLength") payload := rapid.SliceOfN(rapid.Byte(), payloadLen, payloadLen).Draw( t, "pongPayload", ) return &Pong{ PongBytes: payload, } } // A compile time check to ensure QueryChannelRange implements the // lnwire.TestMessage interface. var _ TestMessage = (*QueryChannelRange)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (q *QueryChannelRange) RandTestMessage(t *rapid.T) Message { msg := &QueryChannelRange{ FirstBlockHeight: uint32(rapid.IntRange(0, 1000000).Draw( t, "firstBlockHeight"), ), NumBlocks: uint32(rapid.IntRange(1, 10000).Draw( t, "numBlocks"), ), ExtraData: RandExtraOpaqueData(t, nil), } // Generate chain hash chainHash := RandChainHash(t) var chainHashObj chainhash.Hash copy(chainHashObj[:], chainHash[:]) msg.ChainHash = chainHashObj // Randomly include QueryOptions if rapid.Bool().Draw(t, "includeQueryOptions") { queryOptions := &QueryOptions{} *queryOptions = QueryOptions(*RandFeatureVector(t)) msg.QueryOptions = queryOptions } return msg } // A compile time check to ensure QueryShortChanIDs implements the // lnwire.TestMessage interface. var _ TestMessage = (*QueryShortChanIDs)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (q *QueryShortChanIDs) RandTestMessage(t *rapid.T) Message { var chainHash chainhash.Hash hashBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "chainHash") copy(chainHash[:], hashBytes) encodingType := EncodingSortedPlain if rapid.Bool().Draw(t, "useZlibEncoding") { encodingType = EncodingSortedZlib } msg := &QueryShortChanIDs{ ChainHash: chainHash, EncodingType: encodingType, ExtraData: RandExtraOpaqueData(t, nil), noSort: false, } numIDs := rapid.IntRange(2, 20).Draw(t, "numShortChanIDs") // Generate sorted short channel IDs. shortChanIDs := make([]ShortChannelID, numIDs) for i := 0; i < numIDs; i++ { shortChanIDs[i] = RandShortChannelID(t) // Ensure they're properly sorted. if i > 0 && shortChanIDs[i].ToUint64() <= shortChanIDs[i-1].ToUint64() { // Ensure this ID is larger than the previous one. shortChanIDs[i] = NewShortChanIDFromInt( shortChanIDs[i-1].ToUint64() + 1, ) } } msg.ShortChanIDs = shortChanIDs return msg } // A compile time check to ensure ReplyChannelRange implements the // lnwire.TestMessage interface. var _ TestMessage = (*ReplyChannelRange)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *ReplyChannelRange) RandTestMessage(t *rapid.T) Message { msg := &ReplyChannelRange{ FirstBlockHeight: uint32(rapid.IntRange(0, 1000000).Draw( t, "firstBlockHeight"), ), NumBlocks: uint32(rapid.IntRange(1, 10000).Draw( t, "numBlocks"), ), Complete: uint8(rapid.IntRange(0, 1).Draw(t, "complete")), EncodingType: QueryEncoding( rapid.IntRange(0, 1).Draw(t, "encodingType"), ), ExtraData: RandExtraOpaqueData(t, nil), } msg.ChainHash = RandChainHash(t) numShortChanIDs := rapid.IntRange(0, 20).Draw(t, "numShortChanIDs") if numShortChanIDs == 0 { return msg } scidSet := fn.NewSet[ShortChannelID]() scids := make([]ShortChannelID, numShortChanIDs) for i := 0; i < numShortChanIDs; i++ { scid := RandShortChannelID(t) for scidSet.Contains(scid) { scid = RandShortChannelID(t) } scids[i] = scid scidSet.Add(scid) } // Make sure there're no duplicates. msg.ShortChanIDs = scids if rapid.Bool().Draw(t, "includeTimestamps") && numShortChanIDs > 0 { msg.Timestamps = make(Timestamps, numShortChanIDs) for i := 0; i < numShortChanIDs; i++ { msg.Timestamps[i] = ChanUpdateTimestamps{ Timestamp1: uint32(rapid.IntRange(0, math.MaxInt32).Draw(t, fmt.Sprintf("timestamp-1-%d", i))), //nolint:ll Timestamp2: uint32(rapid.IntRange(0, math.MaxInt32).Draw(t, fmt.Sprintf("timestamp-2-%d", i))), //nolint:ll } } } return msg } // A compile time check to ensure ReplyShortChanIDsEnd implements the // lnwire.TestMessage interface. var _ TestMessage = (*ReplyShortChanIDsEnd)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *ReplyShortChanIDsEnd) RandTestMessage(t *rapid.T) Message { var chainHash chainhash.Hash hashBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "chainHash") copy(chainHash[:], hashBytes) complete := uint8(rapid.IntRange(0, 1).Draw(t, "complete")) return &ReplyShortChanIDsEnd{ ChainHash: chainHash, Complete: complete, ExtraData: RandExtraOpaqueData(t, nil), } } // RandTestMessage returns a RevokeAndAck message populated with random data. // // This is part of the TestMessage interface. func (c *RevokeAndAck) RandTestMessage(t *rapid.T) Message { msg := NewRevokeAndAck() var chanID ChannelID bytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "channelID") copy(chanID[:], bytes) msg.ChanID = chanID revBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "revocation") copy(msg.Revocation[:], revBytes) msg.NextRevocationKey = RandPubKey(t) if rapid.Bool().Draw(t, "includeLocalNonce") { var nonce Musig2Nonce nonceBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw( t, "nonce", ) copy(nonce[:], nonceBytes) msg.LocalNonce = tlv.SomeRecordT( tlv.NewRecordT[NonceRecordTypeT, Musig2Nonce](nonce), ) } return msg } // A compile-time check to ensure Shutdown implements the lnwire.TestMessage // interface. var _ TestMessage = (*Shutdown)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (s *Shutdown) RandTestMessage(t *rapid.T) Message { // Generate random delivery address // First decide the address type (P2PKH, P2SH, P2WPKH, P2WSH, P2TR) addrType := rapid.IntRange(0, 4).Draw(t, "addrType") // Generate random address length based on type var addrLen int switch addrType { // P2PKH case 0: addrLen = 25 // P2SH case 1: addrLen = 23 // P2WPKH case 2: addrLen = 22 // P2WSH case 3: addrLen = 34 // P2TR case 4: addrLen = 34 } addr := rapid.SliceOfN(rapid.Byte(), addrLen, addrLen).Draw( t, "address", ) // Randomly decide whether to include a shutdown nonce includeNonce := rapid.Bool().Draw(t, "includeNonce") var shutdownNonce ShutdownNonceTLV if includeNonce { shutdownNonce = SomeShutdownNonce(RandMusig2Nonce(t)) } cr, _ := RandCustomRecords(t, nil, true) return &Shutdown{ ChannelID: RandChannelID(t), Address: addr, ShutdownNonce: shutdownNonce, CustomRecords: cr, } } // A compile time check to ensure Stfu implements the lnwire.TestMessage // interface. var _ TestMessage = (*Stfu)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (s *Stfu) RandTestMessage(t *rapid.T) Message { m := &Stfu{ ChanID: RandChannelID(t), Initiator: rapid.Bool().Draw(t, "initiator"), } extraData := RandExtraOpaqueData(t, nil) if len(extraData) > 0 { m.ExtraData = extraData } return m } // A compile time check to ensure UpdateAddHTLC implements the // lnwire.TestMessage interface. var _ TestMessage = (*UpdateAddHTLC)(nil) // RandTestMessage returns an UpdateAddHTLC message populated with random data. // // This is part of the TestMessage interface. func (c *UpdateAddHTLC) RandTestMessage(t *rapid.T) Message { msg := &UpdateAddHTLC{ ChanID: RandChannelID(t), ID: rapid.Uint64().Draw(t, "id"), Amount: MilliSatoshi(rapid.Uint64().Draw(t, "amount")), Expiry: rapid.Uint32().Draw(t, "expiry"), } hashBytes := rapid.SliceOfN(rapid.Byte(), 32, 32).Draw(t, "paymentHash") copy(msg.PaymentHash[:], hashBytes) onionBytes := rapid.SliceOfN( rapid.Byte(), OnionPacketSize, OnionPacketSize, ).Draw(t, "onionBlob") copy(msg.OnionBlob[:], onionBytes) numRecords := rapid.IntRange(0, 5).Draw(t, "numRecords") if numRecords > 0 { msg.CustomRecords, _ = RandCustomRecords(t, nil, true) } // 50/50 chance to add a blinding point if rapid.Bool().Draw(t, "includeBlindingPoint") { pubKey := RandPubKey(t) msg.BlindingPoint = tlv.SomeRecordT( tlv.NewPrimitiveRecord[BlindingPointTlvType](pubKey), ) } return msg } // A compile time check to ensure UpdateFailHTLC implements the TestMessage // interface. var _ TestMessage = (*UpdateFailHTLC)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *UpdateFailHTLC) RandTestMessage(t *rapid.T) Message { return &UpdateFailHTLC{ ChanID: RandChannelID(t), ID: rapid.Uint64().Draw(t, "id"), Reason: RandOpaqueReason(t), ExtraData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure UpdateFailMalformedHTLC implements the // TestMessage interface. var _ TestMessage = (*UpdateFailMalformedHTLC)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *UpdateFailMalformedHTLC) RandTestMessage(t *rapid.T) Message { return &UpdateFailMalformedHTLC{ ChanID: RandChannelID(t), ID: rapid.Uint64().Draw(t, "id"), ShaOnionBlob: RandSHA256Hash(t), FailureCode: RandFailCode(t), ExtraData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure UpdateFee implements the TestMessage // interface. var _ TestMessage = (*UpdateFee)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *UpdateFee) RandTestMessage(t *rapid.T) Message { return &UpdateFee{ ChanID: RandChannelID(t), FeePerKw: uint32(rapid.IntRange(1, 10000).Draw(t, "feePerKw")), ExtraData: RandExtraOpaqueData(t, nil), } } // A compile time check to ensure UpdateFulfillHTLC implements the TestMessage // interface. var _ TestMessage = (*UpdateFulfillHTLC)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *UpdateFulfillHTLC) RandTestMessage(t *rapid.T) Message { msg := &UpdateFulfillHTLC{ ChanID: RandChannelID(t), ID: rapid.Uint64().Draw(t, "id"), PaymentPreimage: RandPaymentPreimage(t), } cr, ignoreRecords := RandCustomRecords(t, nil, true) msg.CustomRecords = cr randData := RandExtraOpaqueData(t, ignoreRecords) if len(randData) > 0 { msg.ExtraData = randData } return msg } // A compile time check to ensure Warning implements the lnwire.TestMessage // interface. var _ TestMessage = (*Warning)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *Warning) RandTestMessage(t *rapid.T) Message { msg := &Warning{ ChanID: RandChannelID(t), } useASCII := rapid.Bool().Draw(t, "useASCII") if useASCII { length := rapid.IntRange(1, 100).Draw(t, "warningDataLength") data := make([]byte, length) for i := 0; i < length; i++ { data[i] = byte( rapid.IntRange(32, 126).Draw( t, fmt.Sprintf("warningDataByte-%d", i), ), ) } msg.Data = data } else { length := rapid.IntRange(1, 100).Draw(t, "warningDataLength") msg.Data = rapid.SliceOfN(rapid.Byte(), length, length).Draw( t, "warningData", ) } return msg } // A compile time check to ensure Error implements the lnwire.TestMessage // interface. var _ TestMessage = (*Error)(nil) // RandTestMessage populates the message with random data suitable for testing. // It uses the rapid testing framework to generate random values. // // This is part of the TestMessage interface. func (c *Error) RandTestMessage(t *rapid.T) Message { msg := &Error{ ChanID: RandChannelID(t), } useASCII := rapid.Bool().Draw(t, "useASCII") if useASCII { length := rapid.IntRange(1, 100).Draw(t, "errorDataLength") data := make([]byte, length) for i := 0; i < length; i++ { data[i] = byte( rapid.IntRange(32, 126).Draw( t, fmt.Sprintf("errorDataByte-%d", i), ), ) } msg.Data = data } else { // Generate random binary data length := rapid.IntRange(1, 100).Draw(t, "errorDataLength") msg.Data = rapid.SliceOfN( rapid.Byte(), length, length, ).Draw(t, "errorData") } return msg }