f82653cb06
This allows gofuzz to store the mutating input as coverage if it reaches any new coverage, even if it didn't make it to the end of the test.
136 lines
3.5 KiB
Go
136 lines
3.5 KiB
Go
// +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)
|
|
|
|
// Create an empty message so that the FuzzHarness func can check
|
|
// if the max payload constraint is violated.
|
|
emptyMsg := lnwire.AcceptChannel{}
|
|
|
|
// 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. We check this because
|
|
// otherwise `go-fuzz` will keep creating inputs that crash on ReadMessage
|
|
// due to a large message size.
|
|
payloadLen := uint32(len(data)) - 2
|
|
if payloadLen > emptyMsg.MaxPayloadLength(0) {
|
|
// Ignore this input - max payload constraint violated.
|
|
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
|
|
}
|