From 3d4d8cd6cc61badff9ce62d6a45e0700af6b2a64 Mon Sep 17 00:00:00 2001 From: Conner Date: Fri, 29 Jul 2022 17:42:42 -0400 Subject: [PATCH] lnwire: migrate fuzz tests --- fuzz/lnwire/accept_channel.go | 129 ---- fuzz/lnwire/announce_signatures.go | 17 - fuzz/lnwire/channel_announcement.go | 17 - fuzz/lnwire/channel_reestablish.go | 17 - fuzz/lnwire/channel_update.go | 17 - fuzz/lnwire/closing_signed.go | 17 - fuzz/lnwire/commit_sig.go | 17 - fuzz/lnwire/error.go | 17 - fuzz/lnwire/funding_created.go | 17 - fuzz/lnwire/funding_locked.go | 17 - fuzz/lnwire/funding_signed.go | 17 - fuzz/lnwire/fuzz_utils.go | 65 -- fuzz/lnwire/gossip_timestamp_range.go | 17 - fuzz/lnwire/init.go | 17 - fuzz/lnwire/node_announcement.go | 103 --- fuzz/lnwire/open_channel.go | 142 ---- fuzz/lnwire/ping.go | 17 - fuzz/lnwire/pong.go | 17 - fuzz/lnwire/query_channel_range.go | 17 - fuzz/lnwire/query_short_chan_ids.go | 17 - fuzz/lnwire/query_short_chan_ids_zlib.go | 48 -- fuzz/lnwire/reply_channel_range.go | 17 - fuzz/lnwire/reply_channel_range_zlib.go | 56 -- fuzz/lnwire/reply_short_chan_ids_end.go | 17 - fuzz/lnwire/revoke_and_ack.go | 17 - fuzz/lnwire/shutdown.go | 17 - fuzz/lnwire/update_add_htlc.go | 17 - fuzz/lnwire/update_fail_htlc.go | 17 - fuzz/lnwire/update_fail_malformed_htlc.go | 17 - fuzz/lnwire/update_fee.go | 17 - fuzz/lnwire/update_fulfill_htlc.go | 17 - lnwire/fuzz_test.go | 752 ++++++++++++++++++++++ 32 files changed, 752 insertions(+), 968 deletions(-) delete mode 100644 fuzz/lnwire/accept_channel.go delete mode 100644 fuzz/lnwire/announce_signatures.go delete mode 100644 fuzz/lnwire/channel_announcement.go delete mode 100644 fuzz/lnwire/channel_reestablish.go delete mode 100644 fuzz/lnwire/channel_update.go delete mode 100644 fuzz/lnwire/closing_signed.go delete mode 100644 fuzz/lnwire/commit_sig.go delete mode 100644 fuzz/lnwire/error.go delete mode 100644 fuzz/lnwire/funding_created.go delete mode 100644 fuzz/lnwire/funding_locked.go delete mode 100644 fuzz/lnwire/funding_signed.go delete mode 100644 fuzz/lnwire/fuzz_utils.go delete mode 100644 fuzz/lnwire/gossip_timestamp_range.go delete mode 100644 fuzz/lnwire/init.go delete mode 100644 fuzz/lnwire/node_announcement.go delete mode 100644 fuzz/lnwire/open_channel.go delete mode 100644 fuzz/lnwire/ping.go delete mode 100644 fuzz/lnwire/pong.go delete mode 100644 fuzz/lnwire/query_channel_range.go delete mode 100644 fuzz/lnwire/query_short_chan_ids.go delete mode 100644 fuzz/lnwire/query_short_chan_ids_zlib.go delete mode 100644 fuzz/lnwire/reply_channel_range.go delete mode 100644 fuzz/lnwire/reply_channel_range_zlib.go delete mode 100644 fuzz/lnwire/reply_short_chan_ids_end.go delete mode 100644 fuzz/lnwire/revoke_and_ack.go delete mode 100644 fuzz/lnwire/shutdown.go delete mode 100644 fuzz/lnwire/update_add_htlc.go delete mode 100644 fuzz/lnwire/update_fail_htlc.go delete mode 100644 fuzz/lnwire/update_fail_malformed_htlc.go delete mode 100644 fuzz/lnwire/update_fee.go delete mode 100644 fuzz/lnwire/update_fulfill_htlc.go create mode 100644 lnwire/fuzz_test.go diff --git a/fuzz/lnwire/accept_channel.go b/fuzz/lnwire/accept_channel.go deleted file mode 100644 index f57c2af42..000000000 --- a/fuzz/lnwire/accept_channel.go +++ /dev/null @@ -1,129 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "bytes" - - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_accept_channel is used by go-fuzz. -func Fuzz_accept_channel(data []byte) int { - // Prefix with MsgAcceptChannel. - data = prefixWithMsgType(data, lnwire.MsgAcceptChannel) - - // We have to do this here instead of in fuzz.Harness so that - // reflect.DeepEqual isn't called. Because of the UpfrontShutdownScript - // encoding, the first message and second message aren't deeply equal since - // the first has a nil slice and the other has an empty slice. - - // Create a reader with the byte array. - r := bytes.NewReader(data) - - // Make sure byte array length (excluding 2 bytes for message type) is - // less than max payload size for the wire message. - payloadLen := uint32(len(data)) - 2 - if payloadLen > lnwire.MaxMsgBody { - return 1 - } - - msg, err := lnwire.ReadMessage(r, 0) - if err != nil { - // go-fuzz generated []byte that cannot be represented as a - // wire message but we will return 0 so go-fuzz can modify the - // input. - return 1 - } - - // We will serialize the message into a new bytes buffer. - var b bytes.Buffer - if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil { - // Could not serialize message into bytes buffer, panic - panic(err) - } - - // Deserialize the message from the serialized bytes buffer, and then - // assert that the original message is equal to the newly deserialized - // message. - newMsg, err := lnwire.ReadMessage(&b, 0) - if err != nil { - // Could not deserialize message from bytes buffer, panic - panic(err) - } - - // Now compare every field instead of using reflect.DeepEqual. - // For UpfrontShutdownScript, we only compare bytes. This probably takes - // up more branches than necessary, but that's fine for now. - var shouldPanic bool - first := msg.(*lnwire.AcceptChannel) - second := newMsg.(*lnwire.AcceptChannel) - - if !bytes.Equal(first.PendingChannelID[:], second.PendingChannelID[:]) { - shouldPanic = true - } - - if first.DustLimit != second.DustLimit { - shouldPanic = true - } - - if first.MaxValueInFlight != second.MaxValueInFlight { - shouldPanic = true - } - - if first.ChannelReserve != second.ChannelReserve { - shouldPanic = true - } - - if first.HtlcMinimum != second.HtlcMinimum { - shouldPanic = true - } - - if first.MinAcceptDepth != second.MinAcceptDepth { - shouldPanic = true - } - - if first.CsvDelay != second.CsvDelay { - shouldPanic = true - } - - if first.MaxAcceptedHTLCs != second.MaxAcceptedHTLCs { - shouldPanic = true - } - - if !first.FundingKey.IsEqual(second.FundingKey) { - shouldPanic = true - } - - if !first.RevocationPoint.IsEqual(second.RevocationPoint) { - shouldPanic = true - } - - if !first.PaymentPoint.IsEqual(second.PaymentPoint) { - shouldPanic = true - } - - if !first.DelayedPaymentPoint.IsEqual(second.DelayedPaymentPoint) { - shouldPanic = true - } - - if !first.HtlcPoint.IsEqual(second.HtlcPoint) { - shouldPanic = true - } - - if !first.FirstCommitmentPoint.IsEqual(second.FirstCommitmentPoint) { - shouldPanic = true - } - - if !bytes.Equal(first.UpfrontShutdownScript, second.UpfrontShutdownScript) { - shouldPanic = true - } - - if shouldPanic { - panic("original message and deserialized message are not equal") - } - - // Add this input to the corpus. - return 1 -} diff --git a/fuzz/lnwire/announce_signatures.go b/fuzz/lnwire/announce_signatures.go deleted file mode 100644 index c35d5a248..000000000 --- a/fuzz/lnwire/announce_signatures.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_announce_signatures is used by go-fuzz. -func Fuzz_announce_signatures(data []byte) int { - // Prefix with MsgAnnounceSignatures. - data = prefixWithMsgType(data, lnwire.MsgAnnounceSignatures) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/channel_announcement.go b/fuzz/lnwire/channel_announcement.go deleted file mode 100644 index 92800185b..000000000 --- a/fuzz/lnwire/channel_announcement.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_channel_announcement is used by go-fuzz. -func Fuzz_channel_announcement(data []byte) int { - // Prefix with MsgChannelAnnouncement. - data = prefixWithMsgType(data, lnwire.MsgChannelAnnouncement) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/channel_reestablish.go b/fuzz/lnwire/channel_reestablish.go deleted file mode 100644 index 841142c1c..000000000 --- a/fuzz/lnwire/channel_reestablish.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_channel_reestablish is used by go-fuzz. -func Fuzz_channel_reestablish(data []byte) int { - // Prefix with MsgChannelReestablish. - data = prefixWithMsgType(data, lnwire.MsgChannelReestablish) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/channel_update.go b/fuzz/lnwire/channel_update.go deleted file mode 100644 index cce82442c..000000000 --- a/fuzz/lnwire/channel_update.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_channel_update is used by go-fuzz. -func Fuzz_channel_update(data []byte) int { - // Prefix with MsgChannelUpdate. - data = prefixWithMsgType(data, lnwire.MsgChannelUpdate) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/closing_signed.go b/fuzz/lnwire/closing_signed.go deleted file mode 100644 index 4d3dd59f1..000000000 --- a/fuzz/lnwire/closing_signed.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_closing_signed is used by go-fuzz. -func Fuzz_closing_signed(data []byte) int { - // Prefix with MsgClosingSigned. - data = prefixWithMsgType(data, lnwire.MsgClosingSigned) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/commit_sig.go b/fuzz/lnwire/commit_sig.go deleted file mode 100644 index 7dae96518..000000000 --- a/fuzz/lnwire/commit_sig.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_commit_sig is used by go-fuzz. -func Fuzz_commit_sig(data []byte) int { - // Prefix with MsgCommitSig. - data = prefixWithMsgType(data, lnwire.MsgCommitSig) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/error.go b/fuzz/lnwire/error.go deleted file mode 100644 index f613606e4..000000000 --- a/fuzz/lnwire/error.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_error is used by go-fuzz. -func Fuzz_error(data []byte) int { - // Prefix with MsgError. - data = prefixWithMsgType(data, lnwire.MsgError) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/funding_created.go b/fuzz/lnwire/funding_created.go deleted file mode 100644 index a14b1083f..000000000 --- a/fuzz/lnwire/funding_created.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_funding_created is used by go-fuzz. -func Fuzz_funding_created(data []byte) int { - // Prefix with MsgFundingCreated. - data = prefixWithMsgType(data, lnwire.MsgFundingCreated) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/funding_locked.go b/fuzz/lnwire/funding_locked.go deleted file mode 100644 index c5512f97e..000000000 --- a/fuzz/lnwire/funding_locked.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_funding_locked is used by go-fuzz. -func Fuzz_funding_locked(data []byte) int { - // Prefix with MsgFundingLocked. - data = prefixWithMsgType(data, lnwire.MsgFundingLocked) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/funding_signed.go b/fuzz/lnwire/funding_signed.go deleted file mode 100644 index 1af68add6..000000000 --- a/fuzz/lnwire/funding_signed.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_funding_signed is used by go-fuzz. -func Fuzz_funding_signed(data []byte) int { - // Prefix with MsgFundingSigned. - prefixWithMsgType(data, lnwire.MsgFundingSigned) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/fuzz_utils.go b/fuzz/lnwire/fuzz_utils.go deleted file mode 100644 index 98ab50bce..000000000 --- a/fuzz/lnwire/fuzz_utils.go +++ /dev/null @@ -1,65 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "bytes" - "encoding/binary" - "reflect" - - "github.com/lightningnetwork/lnd/lnwire" -) - -// prefixWithMsgType takes []byte and adds a wire protocol prefix -// to make the []byte into an actual message to be used in fuzzing. -func prefixWithMsgType(data []byte, prefix lnwire.MessageType) []byte { - var prefixBytes [2]byte - binary.BigEndian.PutUint16(prefixBytes[:], uint16(prefix)) - data = append(prefixBytes[:], data...) - return data -} - -// harness performs the actual fuzz testing of the appropriate wire message. -// This function will check that the passed-in message passes wire length checks, -// is a valid message once deserialized, and passes a sequence of serialization -// and deserialization checks. Returns an int that determines whether the input -// is unique or not. -func harness(data []byte) int { - // Create a reader with the byte array. - r := bytes.NewReader(data) - - // Check that the created message is not greater than the maximum - // message size. - if len(data) > lnwire.MaxSliceLength { - return 1 - } - - msg, err := lnwire.ReadMessage(r, 0) - if err != nil { - return 1 - } - - // We will serialize the message into a new bytes buffer. - var b bytes.Buffer - if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil { - // Could not serialize message into bytes buffer, panic - panic(err) - } - - // Deserialize the message from the serialized bytes buffer, and then - // assert that the original message is equal to the newly deserialized - // message. - newMsg, err := lnwire.ReadMessage(&b, 0) - if err != nil { - // Could not deserialize message from bytes buffer, panic - panic(err) - } - - if !reflect.DeepEqual(msg, newMsg) { - // Deserialized message and original message are not deeply equal. - panic("original message and deserialized message are not deeply equal") - } - - return 1 -} diff --git a/fuzz/lnwire/gossip_timestamp_range.go b/fuzz/lnwire/gossip_timestamp_range.go deleted file mode 100644 index 5cfe89170..000000000 --- a/fuzz/lnwire/gossip_timestamp_range.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_gossip_timestamp_range is used by go-fuzz. -func Fuzz_gossip_timestamp_range(data []byte) int { - // Prefix with MsgGossipTimestampRange. - data = prefixWithMsgType(data, lnwire.MsgGossipTimestampRange) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/init.go b/fuzz/lnwire/init.go deleted file mode 100644 index 3a10fb675..000000000 --- a/fuzz/lnwire/init.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_init is used by go-fuzz. -func Fuzz_init(data []byte) int { - // Prefix with MsgInit. - data = prefixWithMsgType(data, lnwire.MsgInit) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/node_announcement.go b/fuzz/lnwire/node_announcement.go deleted file mode 100644 index 7f73c8371..000000000 --- a/fuzz/lnwire/node_announcement.go +++ /dev/null @@ -1,103 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "bytes" - "reflect" - - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_node_announcement is used by go-fuzz. -func Fuzz_node_announcement(data []byte) int { - // Prefix with MsgNodeAnnouncement. - data = prefixWithMsgType(data, lnwire.MsgNodeAnnouncement) - - // We have to do this here instead of in fuzz.Harness so that - // reflect.DeepEqual isn't called. Address (de)serialization messes up - // the fuzzing assertions. - - // Create a reader with the byte array. - r := bytes.NewReader(data) - - // Make sure byte array length (excluding 2 bytes for message type) is - // less than max payload size for the wire message. - payloadLen := uint32(len(data)) - 2 - if payloadLen > lnwire.MaxMsgBody { - return 1 - } - - msg, err := lnwire.ReadMessage(r, 0) - if err != nil { - return 1 - } - - // We will serialize the message into a new bytes buffer. - var b bytes.Buffer - if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil { - // Could not serialize message into bytes buffer, panic - panic(err) - } - - // Deserialize the message from the serialized bytes buffer, and then - // assert that the original message is equal to the newly deserialized - // message. - newMsg, err := lnwire.ReadMessage(&b, 0) - if err != nil { - // Could not deserialize message from bytes buffer, panic - panic(err) - } - - // Now compare every field instead of using reflect.DeepEqual for the - // Addresses field. - var shouldPanic bool - first := msg.(*lnwire.NodeAnnouncement) - second := newMsg.(*lnwire.NodeAnnouncement) - if !bytes.Equal(first.Signature[:], second.Signature[:]) { - shouldPanic = true - } - - if !reflect.DeepEqual(first.Features, second.Features) { - shouldPanic = true - } - - if first.Timestamp != second.Timestamp { - shouldPanic = true - } - - if !bytes.Equal(first.NodeID[:], second.NodeID[:]) { - shouldPanic = true - } - - if !reflect.DeepEqual(first.RGBColor, second.RGBColor) { - shouldPanic = true - } - - if !bytes.Equal(first.Alias[:], second.Alias[:]) { - shouldPanic = true - } - - if len(first.Addresses) != len(second.Addresses) { - shouldPanic = true - } - - for i := range first.Addresses { - if first.Addresses[i].String() != second.Addresses[i].String() { - shouldPanic = true - break - } - } - - if !reflect.DeepEqual(first.ExtraOpaqueData, second.ExtraOpaqueData) { - shouldPanic = true - } - - if shouldPanic { - panic("original message and deserialized message are not equal") - } - - // Add this input to the corpus. - return 1 -} diff --git a/fuzz/lnwire/open_channel.go b/fuzz/lnwire/open_channel.go deleted file mode 100644 index c7ab024a9..000000000 --- a/fuzz/lnwire/open_channel.go +++ /dev/null @@ -1,142 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "bytes" - - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_open_channel is used by go-fuzz. -func Fuzz_open_channel(data []byte) int { - // Prefix with MsgOpenChannel. - data = prefixWithMsgType(data, lnwire.MsgOpenChannel) - - // We have to do this here instead of in fuzz.Harness so that - // reflect.DeepEqual isn't called. Because of the UpfrontShutdownScript - // encoding, the first message and second message aren't deeply equal since - // the first has a nil slice and the other has an empty slice. - - // Create a reader with the byte array. - r := bytes.NewReader(data) - - // Make sure byte array length (excluding 2 bytes for message type) is - // less than max payload size for the wire message. - payloadLen := uint32(len(data)) - 2 - if payloadLen > lnwire.MaxMsgBody { - return 1 - } - - msg, err := lnwire.ReadMessage(r, 0) - if err != nil { - return 1 - } - - // We will serialize the message into a new bytes buffer. - var b bytes.Buffer - if _, err := lnwire.WriteMessage(&b, msg, 0); err != nil { - // Could not serialize message into bytes buffer, panic - panic(err) - } - - // Deserialize the message from the serialized bytes buffer, and then - // assert that the original message is equal to the newly deserialized - // message. - newMsg, err := lnwire.ReadMessage(&b, 0) - if err != nil { - // Could not deserialize message from bytes buffer, panic - panic(err) - } - - // Now compare every field instead of using reflect.DeepEqual. - // For UpfrontShutdownScript, we only compare bytes. This probably takes - // up more branches than necessary, but that's fine for now. - var shouldPanic bool - first := msg.(*lnwire.OpenChannel) - second := newMsg.(*lnwire.OpenChannel) - - if !first.ChainHash.IsEqual(&second.ChainHash) { - shouldPanic = true - } - - if !bytes.Equal(first.PendingChannelID[:], second.PendingChannelID[:]) { - shouldPanic = true - } - - if first.FundingAmount != second.FundingAmount { - shouldPanic = true - } - - if first.PushAmount != second.PushAmount { - shouldPanic = true - } - - if first.DustLimit != second.DustLimit { - shouldPanic = true - } - - if first.MaxValueInFlight != second.MaxValueInFlight { - shouldPanic = true - } - - if first.ChannelReserve != second.ChannelReserve { - shouldPanic = true - } - - if first.HtlcMinimum != second.HtlcMinimum { - shouldPanic = true - } - - if first.FeePerKiloWeight != second.FeePerKiloWeight { - shouldPanic = true - } - - if first.CsvDelay != second.CsvDelay { - shouldPanic = true - } - - if first.MaxAcceptedHTLCs != second.MaxAcceptedHTLCs { - shouldPanic = true - } - - if !first.FundingKey.IsEqual(second.FundingKey) { - shouldPanic = true - } - - if !first.RevocationPoint.IsEqual(second.RevocationPoint) { - shouldPanic = true - } - - if !first.PaymentPoint.IsEqual(second.PaymentPoint) { - shouldPanic = true - } - - if !first.DelayedPaymentPoint.IsEqual(second.DelayedPaymentPoint) { - shouldPanic = true - } - - if !first.HtlcPoint.IsEqual(second.HtlcPoint) { - shouldPanic = true - } - - if !first.FirstCommitmentPoint.IsEqual(second.FirstCommitmentPoint) { - shouldPanic = true - } - - if first.ChannelFlags != second.ChannelFlags { - shouldPanic = true - } - - if !bytes.Equal(first.UpfrontShutdownScript, second.UpfrontShutdownScript) { - shouldPanic = true - } - - if shouldPanic { - panic("original message and deserialized message are not equal") - } - - // Add this input to the corpus. - return 1 -} diff --git a/fuzz/lnwire/ping.go b/fuzz/lnwire/ping.go deleted file mode 100644 index 2147dc8a6..000000000 --- a/fuzz/lnwire/ping.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_ping is used by go-fuzz. -func Fuzz_ping(data []byte) int { - // Prefix with MsgPing. - data = prefixWithMsgType(data, lnwire.MsgPing) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/pong.go b/fuzz/lnwire/pong.go deleted file mode 100644 index bc8b1a174..000000000 --- a/fuzz/lnwire/pong.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_pong is used by go-fuzz. -func Fuzz_pong(data []byte) int { - // Prefix with MsgPong. - data = prefixWithMsgType(data, lnwire.MsgPong) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/query_channel_range.go b/fuzz/lnwire/query_channel_range.go deleted file mode 100644 index c8bdbc2db..000000000 --- a/fuzz/lnwire/query_channel_range.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_query_channel_range is used by go-fuzz. -func Fuzz_query_channel_range(data []byte) int { - // Prefix with MsgQueryChannelRange. - data = prefixWithMsgType(data, lnwire.MsgQueryChannelRange) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/query_short_chan_ids.go b/fuzz/lnwire/query_short_chan_ids.go deleted file mode 100644 index 8d4e99368..000000000 --- a/fuzz/lnwire/query_short_chan_ids.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_query_short_chan_ids is used by go-fuzz. -func Fuzz_query_short_chan_ids(data []byte) int { - // Prefix with MsgQueryShortChanIDs. - data = prefixWithMsgType(data, lnwire.MsgQueryShortChanIDs) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/query_short_chan_ids_zlib.go b/fuzz/lnwire/query_short_chan_ids_zlib.go deleted file mode 100644 index eaf1e1f77..000000000 --- a/fuzz/lnwire/query_short_chan_ids_zlib.go +++ /dev/null @@ -1,48 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "bytes" - "compress/zlib" - "encoding/binary" - - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_query_short_chan_ids_zlib is used by go-fuzz. -func Fuzz_query_short_chan_ids_zlib(data []byte) int { - - var buf bytes.Buffer - zlibWriter := zlib.NewWriter(&buf) - _, err := zlibWriter.Write(data) - if err != nil { - // Zlib bug? - panic(err) - } - - if err := zlibWriter.Close(); err != nil { - // Zlib bug? - panic(err) - } - - compressedPayload := buf.Bytes() - - chainhash := []byte("00000000000000000000000000000000") - numBytesInBody := len(compressedPayload) + 1 - zlibByte := []byte("\x01") - - bodyBytes := make([]byte, 2) - binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody)) - - payload := append(chainhash, bodyBytes...) - payload = append(payload, zlibByte...) - payload = append(payload, compressedPayload...) - - // Prefix with MsgQueryShortChanIDs. - payload = prefixWithMsgType(payload, lnwire.MsgQueryShortChanIDs) - - // Pass the message into our general fuzz harness for wire messages! - return harness(payload) -} diff --git a/fuzz/lnwire/reply_channel_range.go b/fuzz/lnwire/reply_channel_range.go deleted file mode 100644 index e1611aa77..000000000 --- a/fuzz/lnwire/reply_channel_range.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_reply_channel_range is used by go-fuzz. -func Fuzz_reply_channel_range(data []byte) int { - // Prefix with MsgReplyChannelRange. - data = prefixWithMsgType(data, lnwire.MsgReplyChannelRange) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/reply_channel_range_zlib.go b/fuzz/lnwire/reply_channel_range_zlib.go deleted file mode 100644 index fe2517179..000000000 --- a/fuzz/lnwire/reply_channel_range_zlib.go +++ /dev/null @@ -1,56 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "bytes" - "compress/zlib" - "encoding/binary" - - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_reply_channel_range_zlib is used by go-fuzz. -func Fuzz_reply_channel_range_zlib(data []byte) int { - - var buf bytes.Buffer - zlibWriter := zlib.NewWriter(&buf) - _, err := zlibWriter.Write(data) - if err != nil { - // Zlib bug? - panic(err) - } - - if err := zlibWriter.Close(); err != nil { - // Zlib bug? - panic(err) - } - - compressedPayload := buf.Bytes() - - // Initialize some []byte vars which will prefix our payload - chainhash := []byte("00000000000000000000000000000000") - firstBlockHeight := []byte("\x00\x00\x00\x00") - numBlocks := []byte("\x00\x00\x00\x00") - completeByte := []byte("\x00") - - numBytesInBody := len(compressedPayload) + 1 - zlibByte := []byte("\x01") - - bodyBytes := make([]byte, 2) - binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody)) - - payload := append(chainhash, firstBlockHeight...) - payload = append(payload, numBlocks...) - payload = append(payload, completeByte...) - payload = append(payload, bodyBytes...) - payload = append(payload, zlibByte...) - payload = append(payload, compressedPayload...) - - // Prefix with MsgReplyChannelRange. - payload = prefixWithMsgType(payload, lnwire.MsgReplyChannelRange) - - // Pass the message into our general fuzz harness for wire messages! - return harness(payload) -} diff --git a/fuzz/lnwire/reply_short_chan_ids_end.go b/fuzz/lnwire/reply_short_chan_ids_end.go deleted file mode 100644 index b91f3b548..000000000 --- a/fuzz/lnwire/reply_short_chan_ids_end.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_reply_short_chan_ids_end is used by go-fuzz. -func Fuzz_reply_short_chan_ids_end(data []byte) int { - // Prefix with MsgReplyShortChanIDsEnd. - data = prefixWithMsgType(data, lnwire.MsgReplyShortChanIDsEnd) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/revoke_and_ack.go b/fuzz/lnwire/revoke_and_ack.go deleted file mode 100644 index 276ba7c21..000000000 --- a/fuzz/lnwire/revoke_and_ack.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_revoke_and_ack is used by go-fuzz. -func Fuzz_revoke_and_ack(data []byte) int { - // Prefix with MsgRevokeAndAck. - data = prefixWithMsgType(data, lnwire.MsgRevokeAndAck) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/shutdown.go b/fuzz/lnwire/shutdown.go deleted file mode 100644 index 84e40cc7c..000000000 --- a/fuzz/lnwire/shutdown.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_shutdown is used by go-fuzz. -func Fuzz_shutdown(data []byte) int { - // Prefix with MsgShutdown. - data = prefixWithMsgType(data, lnwire.MsgShutdown) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/update_add_htlc.go b/fuzz/lnwire/update_add_htlc.go deleted file mode 100644 index 3ec84ff9b..000000000 --- a/fuzz/lnwire/update_add_htlc.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_update_add_htlc is used by go-fuzz. -func Fuzz_update_add_htlc(data []byte) int { - // Prefix with MsgUpdateAddHTLC. - data = prefixWithMsgType(data, lnwire.MsgUpdateAddHTLC) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/update_fail_htlc.go b/fuzz/lnwire/update_fail_htlc.go deleted file mode 100644 index 77b4bac8e..000000000 --- a/fuzz/lnwire/update_fail_htlc.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_update_fail_htlc is used by go-fuzz. -func Fuzz_update_fail_htlc(data []byte) int { - // Prefix with MsgUpdateFailHTLC. - data = prefixWithMsgType(data, lnwire.MsgUpdateFailHTLC) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/update_fail_malformed_htlc.go b/fuzz/lnwire/update_fail_malformed_htlc.go deleted file mode 100644 index 38ddfdf18..000000000 --- a/fuzz/lnwire/update_fail_malformed_htlc.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_update_fail_malformed_htlc is used by go-fuzz. -func Fuzz_update_fail_malformed_htlc(data []byte) int { - // Prefix with MsgUpdateFailMalformedHTLC. - data = prefixWithMsgType(data, lnwire.MsgUpdateFailMalformedHTLC) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/update_fee.go b/fuzz/lnwire/update_fee.go deleted file mode 100644 index 228d12fdb..000000000 --- a/fuzz/lnwire/update_fee.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_update_fee is used by go-fuzz. -func Fuzz_update_fee(data []byte) int { - // Prefix with MsgUpdateFee. - data = prefixWithMsgType(data, lnwire.MsgUpdateFee) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/fuzz/lnwire/update_fulfill_htlc.go b/fuzz/lnwire/update_fulfill_htlc.go deleted file mode 100644 index 241f37c74..000000000 --- a/fuzz/lnwire/update_fulfill_htlc.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build gofuzz -// +build gofuzz - -package lnwirefuzz - -import ( - "github.com/lightningnetwork/lnd/lnwire" -) - -// Fuzz_update_fulfill_htlc is used by go-fuzz. -func Fuzz_update_fulfill_htlc(data []byte) int { - // Prefix with MsgUpdateFulfillHTLC. - data = prefixWithMsgType(data, lnwire.MsgUpdateFulfillHTLC) - - // Pass the message into our general fuzz harness for wire messages! - return harness(data) -} diff --git a/lnwire/fuzz_test.go b/lnwire/fuzz_test.go new file mode 100644 index 000000000..bbb48056a --- /dev/null +++ b/lnwire/fuzz_test.go @@ -0,0 +1,752 @@ +package lnwire + +import ( + "bytes" + "compress/zlib" + "encoding/binary" + "reflect" + "testing" +) + +// prefixWithMsgType takes []byte and adds a wire protocol prefix +// to make the []byte into an actual message to be used in fuzzing. +func prefixWithMsgType(data []byte, prefix MessageType) []byte { + var prefixBytes [2]byte + binary.BigEndian.PutUint16(prefixBytes[:], uint16(prefix)) + data = append(prefixBytes[:], data...) + return data +} + +// harness performs the actual fuzz testing of the appropriate wire message. +// This function will check that the passed-in message passes wire length +// checks, is a valid message once deserialized, and passes a sequence of +// serialization and deserialization checks. +func harness(t *testing.T, data []byte) { + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Check that the created message is not greater than the maximum + // message size. + if len(data) > MaxSliceLength { + return + } + + msg, err := ReadMessage(r, 0) + if err != nil { + return + } + + // We will serialize the message into a new bytes buffer. + var b bytes.Buffer + if _, err := WriteMessage(&b, msg, 0); err != nil { + // Could not serialize message into bytes buffer, panic + t.Fatal(err) + } + + // Deserialize the message from the serialized bytes buffer, and then + // assert that the original message is equal to the newly deserialized + // message. + newMsg, err := ReadMessage(&b, 0) + if err != nil { + // Could not deserialize message from bytes buffer, panic + t.Fatal(err) + } + + if !reflect.DeepEqual(msg, newMsg) { + // Deserialized message and original message are not deeply + // equal. + t.Fatal("original message and deserialized message are not deeply equal") + } +} + +func Fuzz_accept_channel(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + data = prefixWithMsgType(data, MsgAcceptChannel) + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Make sure byte array length (excluding 2 bytes for message + // type) is less than max payload size for the wire message. + payloadLen := uint32(len(data)) - 2 + if payloadLen > MaxMsgBody { + return + } + + msg, err := ReadMessage(r, 0) + if err != nil { + return + } + + // We will serialize the message into a new bytes buffer. + var b bytes.Buffer + if _, err := WriteMessage(&b, msg, 0); err != nil { + // Could not serialize message into bytes buffer, panic + t.Fatal(err) + } + + // Deserialize the message from the serialized bytes buffer, and + // then assert that the original message is equal to the newly + // deserialized message. + newMsg, err := ReadMessage(&b, 0) + if err != nil { + // Could not deserialize message from bytes buffer, + // panic + t.Fatal(err) + } + + // Now compare every field instead of using reflect.DeepEqual. + // For UpfrontShutdownScript, we only compare bytes. This + // probably takes up more branches than necessary, but that's + // fine for now. + var shouldPanic bool + first := msg.(*AcceptChannel) + second := newMsg.(*AcceptChannel) + + if !bytes.Equal(first.PendingChannelID[:], second.PendingChannelID[:]) { + shouldPanic = true + } + + if first.DustLimit != second.DustLimit { + shouldPanic = true + } + + if first.MaxValueInFlight != second.MaxValueInFlight { + shouldPanic = true + } + + if first.ChannelReserve != second.ChannelReserve { + shouldPanic = true + } + + if first.HtlcMinimum != second.HtlcMinimum { + shouldPanic = true + } + + if first.MinAcceptDepth != second.MinAcceptDepth { + shouldPanic = true + } + + if first.CsvDelay != second.CsvDelay { + shouldPanic = true + } + + if first.MaxAcceptedHTLCs != second.MaxAcceptedHTLCs { + shouldPanic = true + } + + if !first.FundingKey.IsEqual(second.FundingKey) { + shouldPanic = true + } + + if !first.RevocationPoint.IsEqual(second.RevocationPoint) { + shouldPanic = true + } + + if !first.PaymentPoint.IsEqual(second.PaymentPoint) { + shouldPanic = true + } + + if !first.DelayedPaymentPoint.IsEqual(second.DelayedPaymentPoint) { + shouldPanic = true + } + + if !first.HtlcPoint.IsEqual(second.HtlcPoint) { + shouldPanic = true + } + + if !first.FirstCommitmentPoint.IsEqual(second.FirstCommitmentPoint) { + shouldPanic = true + } + + if !bytes.Equal(first.UpfrontShutdownScript, second.UpfrontShutdownScript) { + shouldPanic = true + } + + if shouldPanic { + t.Fatalf("original message and deseralized message are not equal") + } + }) +} + +func Fuzz_announce_signatures(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgAnnounceSignatures. + data = prefixWithMsgType(data, MsgAnnounceSignatures) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_channel_announcement(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgChannelAnnouncement. + data = prefixWithMsgType(data, MsgChannelAnnouncement) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_channel_reestablish(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgChannelReestablish. + data = prefixWithMsgType(data, MsgChannelReestablish) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_channel_update(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgChannelUpdate. + data = prefixWithMsgType(data, MsgChannelUpdate) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_closing_signed(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgClosingSigned. + data = prefixWithMsgType(data, MsgClosingSigned) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_commit_sig(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgCommitSig. + data = prefixWithMsgType(data, MsgCommitSig) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_error(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgError. + data = prefixWithMsgType(data, MsgError) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_funding_created(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgFundingCreated. + data = prefixWithMsgType(data, MsgFundingCreated) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_funding_locked(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgFundingLocked. + data = prefixWithMsgType(data, MsgFundingLocked) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_funding_signed(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgFundingSigned. + data = prefixWithMsgType(data, MsgFundingSigned) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_gossip_timestamp_range(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgGossipTimestampRange. + data = prefixWithMsgType(data, MsgGossipTimestampRange) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_init(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgInit. + data = prefixWithMsgType(data, MsgInit) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_node_announcement(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgNodeAnnouncement. + data = prefixWithMsgType(data, MsgNodeAnnouncement) + + // We have to do this here instead of in harness so that + // reflect.DeepEqual isn't called. Address (de)serialization + // messes up the fuzzing assertions. + + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Make sure byte array length (excluding 2 bytes for message + // type) is less than max payload size for the wire message. + payloadLen := uint32(len(data)) - 2 + if payloadLen > MaxMsgBody { + return + } + + msg, err := ReadMessage(r, 0) + if err != nil { + return + } + + // We will serialize the message into a new bytes buffer. + var b bytes.Buffer + if _, err := WriteMessage(&b, msg, 0); err != nil { + // Could not serialize message into bytes buffer, panic + t.Fatal(err) + } + + // Deserialize the message from the serialized bytes buffer, and + // then assert that the original message is equal to the newly + // deserialized message. + newMsg, err := ReadMessage(&b, 0) + if err != nil { + // Could not deserialize message from bytes buffer, + // panic + t.Fatal(err) + } + + // Now compare every field instead of using reflect.DeepEqual + // for the Addresses field. + var shouldPanic bool + first := msg.(*NodeAnnouncement) + second := newMsg.(*NodeAnnouncement) + if !bytes.Equal(first.Signature[:], second.Signature[:]) { + shouldPanic = true + } + + if !reflect.DeepEqual(first.Features, second.Features) { + shouldPanic = true + } + + if first.Timestamp != second.Timestamp { + shouldPanic = true + } + + if !bytes.Equal(first.NodeID[:], second.NodeID[:]) { + shouldPanic = true + } + + if !reflect.DeepEqual(first.RGBColor, second.RGBColor) { + shouldPanic = true + } + + if !bytes.Equal(first.Alias[:], second.Alias[:]) { + shouldPanic = true + } + + if len(first.Addresses) != len(second.Addresses) { + shouldPanic = true + } + + for i := range first.Addresses { + if first.Addresses[i].String() != second.Addresses[i].String() { + shouldPanic = true + break + } + } + + if !reflect.DeepEqual(first.ExtraOpaqueData, second.ExtraOpaqueData) { + shouldPanic = true + } + + if shouldPanic { + t.Fatal("original message and deserialized message are not equal") + } + }) +} + +func Fuzz_open_channel(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgOpenChannel. + data = prefixWithMsgType(data, MsgOpenChannel) + + // We have to do this here instead of in harness so that + // reflect.DeepEqual isn't called. Because of the + // UpfrontShutdownScript encoding, the first message and second + // message aren't deeply equal since the first has a nil slice + // and the other has an empty slice. + + // Create a reader with the byte array. + r := bytes.NewReader(data) + + // Make sure byte array length (excluding 2 bytes for message + // type) is less than max payload size for the wire message. + payloadLen := uint32(len(data)) - 2 + if payloadLen > MaxMsgBody { + return + } + + msg, err := ReadMessage(r, 0) + if err != nil { + return + } + + // We will serialize the message into a new bytes buffer. + var b bytes.Buffer + if _, err := WriteMessage(&b, msg, 0); err != nil { + // Could not serialize message into bytes buffer, panic + t.Fatal(err) + } + + // Deserialize the message from the serialized bytes buffer, and + // then assert that the original message is equal to the newly + // deserialized message. + newMsg, err := ReadMessage(&b, 0) + if err != nil { + // Could not deserialize message from bytes buffer, + // panic + t.Fatal(err) + } + + // Now compare every field instead of using reflect.DeepEqual. + // For UpfrontShutdownScript, we only compare bytes. This + // probably takes up more branches than necessary, but that's + // fine for now. + var shouldPanic bool + first := msg.(*OpenChannel) + second := newMsg.(*OpenChannel) + + if !first.ChainHash.IsEqual(&second.ChainHash) { + shouldPanic = true + } + + if !bytes.Equal(first.PendingChannelID[:], second.PendingChannelID[:]) { + shouldPanic = true + } + + if first.FundingAmount != second.FundingAmount { + shouldPanic = true + } + + if first.PushAmount != second.PushAmount { + shouldPanic = true + } + + if first.DustLimit != second.DustLimit { + shouldPanic = true + } + + if first.MaxValueInFlight != second.MaxValueInFlight { + shouldPanic = true + } + + if first.ChannelReserve != second.ChannelReserve { + shouldPanic = true + } + + if first.HtlcMinimum != second.HtlcMinimum { + shouldPanic = true + } + + if first.FeePerKiloWeight != second.FeePerKiloWeight { + shouldPanic = true + } + + if first.CsvDelay != second.CsvDelay { + shouldPanic = true + } + + if first.MaxAcceptedHTLCs != second.MaxAcceptedHTLCs { + shouldPanic = true + } + + if !first.FundingKey.IsEqual(second.FundingKey) { + shouldPanic = true + } + + if !first.RevocationPoint.IsEqual(second.RevocationPoint) { + shouldPanic = true + } + + if !first.PaymentPoint.IsEqual(second.PaymentPoint) { + shouldPanic = true + } + + if !first.DelayedPaymentPoint.IsEqual(second.DelayedPaymentPoint) { + shouldPanic = true + } + + if !first.HtlcPoint.IsEqual(second.HtlcPoint) { + shouldPanic = true + } + + if !first.FirstCommitmentPoint.IsEqual(second.FirstCommitmentPoint) { + shouldPanic = true + } + + if first.ChannelFlags != second.ChannelFlags { + shouldPanic = true + } + + if !bytes.Equal(first.UpfrontShutdownScript, second.UpfrontShutdownScript) { + shouldPanic = true + } + + if shouldPanic { + t.Fatal("original message and deserialized message are not equal") + } + }) +} + +func Fuzz_ping(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgPing. + data = prefixWithMsgType(data, MsgPing) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_pong(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgPong. + data = prefixWithMsgType(data, MsgPong) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_query_channel_range(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgQueryChannelRange. + data = prefixWithMsgType(data, MsgQueryChannelRange) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_zlib_query_short_chan_ids(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + var buf bytes.Buffer + zlibWriter := zlib.NewWriter(&buf) + _, err := zlibWriter.Write(data) + if err != nil { + // Zlib bug? + t.Fatal(err) + } + + if err := zlibWriter.Close(); err != nil { + // Zlib bug? + t.Fatal(err) + } + + compressedPayload := buf.Bytes() + + chainhash := []byte("00000000000000000000000000000000") + numBytesInBody := len(compressedPayload) + 1 + zlibByte := []byte("\x01") + + bodyBytes := make([]byte, 2) + binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody)) + + payload := chainhash + payload = append(payload, bodyBytes...) + payload = append(payload, zlibByte...) + payload = append(payload, compressedPayload...) + + // Prefix with MsgQueryShortChanIDs. + payload = prefixWithMsgType(payload, MsgQueryShortChanIDs) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, payload) + }) +} + +func Fuzz_query_short_chan_ids(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgQueryShortChanIDs. + data = prefixWithMsgType(data, MsgQueryShortChanIDs) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_zlib_reply_channel_range(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + var buf bytes.Buffer + zlibWriter := zlib.NewWriter(&buf) + _, err := zlibWriter.Write(data) + if err != nil { + // Zlib bug? + t.Fatal(err) + } + + if err := zlibWriter.Close(); err != nil { + // Zlib bug? + t.Fatal(err) + } + + compressedPayload := buf.Bytes() + + // Initialize some []byte vars which will prefix our payload + chainhash := []byte("00000000000000000000000000000000") + firstBlockHeight := []byte("\x00\x00\x00\x00") + numBlocks := []byte("\x00\x00\x00\x00") + completeByte := []byte("\x00") + + numBytesInBody := len(compressedPayload) + 1 + zlibByte := []byte("\x01") + + bodyBytes := make([]byte, 2) + binary.BigEndian.PutUint16(bodyBytes, uint16(numBytesInBody)) + + payload := chainhash + payload = append(payload, firstBlockHeight...) + payload = append(payload, numBlocks...) + payload = append(payload, completeByte...) + payload = append(payload, bodyBytes...) + payload = append(payload, zlibByte...) + payload = append(payload, compressedPayload...) + + // Prefix with MsgReplyChannelRange. + payload = prefixWithMsgType(payload, MsgReplyChannelRange) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, payload) + }) +} + +func Fuzz_reply_channel_range(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgReplyChannelRange. + data = prefixWithMsgType(data, MsgReplyChannelRange) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_reply_short_chan_ids_end(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgReplyShortChanIDsEnd. + data = prefixWithMsgType(data, MsgReplyShortChanIDsEnd) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_revoke_and_ack(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgRevokeAndAck. + data = prefixWithMsgType(data, MsgRevokeAndAck) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_shutdown(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgShutdown. + data = prefixWithMsgType(data, MsgShutdown) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_update_add_htlc(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgUpdateAddHTLC. + data = prefixWithMsgType(data, MsgUpdateAddHTLC) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_update_fail_htlc(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgUpdateFailHTLC. + data = prefixWithMsgType(data, MsgUpdateFailHTLC) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_update_fail_malformed_htlc(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgUpdateFailMalformedHTLC. + data = prefixWithMsgType(data, MsgUpdateFailMalformedHTLC) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_update_fee(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgUpdateFee. + data = prefixWithMsgType(data, MsgUpdateFee) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +} + +func Fuzz_update_fulfill_htlc(f *testing.F) { + f.Fuzz(func(t *testing.T, data []byte) { + // Prefix with MsgUpdateFulFillHTLC. + data = prefixWithMsgType(data, MsgUpdateFulfillHTLC) + + // Pass the message into our general fuzz harness for wire + // messages! + harness(t, data) + }) +}