This adds the errorlint linter to the list of linters and addresses a few false positives it complains about.
253 lines
8.3 KiB
Go
253 lines
8.3 KiB
Go
// Copyright (c) 2013-2015 The btcsuite developers
|
|
// Copyright (c) 2015-2023 The Decred developers
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package wire
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
// ErrorCode describes a kind of message error.
|
|
type ErrorCode int
|
|
|
|
// These constants are used to identify a specific Error.
|
|
const (
|
|
// ErrNonCanonicalVarInt is returned when a variable length integer is
|
|
// not canonically encoded.
|
|
ErrNonCanonicalVarInt ErrorCode = iota
|
|
|
|
// ErrVarStringTooLong is returned when a variable string exceeds the
|
|
// maximum message size allowed.
|
|
ErrVarStringTooLong
|
|
|
|
// ErrVarBytesTooLong is returned when a variable-length byte slice
|
|
// exceeds the maximum message size allowed.
|
|
ErrVarBytesTooLong
|
|
|
|
// ErrCmdTooLong is returned when a command exceeds the maximum command
|
|
// size allowed.
|
|
ErrCmdTooLong
|
|
|
|
// ErrPayloadTooLarge is returned when a payload exceeds the maximum
|
|
// payload size allowed.
|
|
ErrPayloadTooLarge
|
|
|
|
// ErrWrongNetwork is returned when a message intended for a different
|
|
// network is received.
|
|
ErrWrongNetwork
|
|
|
|
// ErrMalformedCmd is returned when a malformed command is received.
|
|
ErrMalformedCmd
|
|
|
|
// ErrUnknownCmd is returned when an unknown command is received.
|
|
ErrUnknownCmd
|
|
|
|
// ErrPayloadChecksum is returned when a message with an invalid checksum
|
|
// is received.
|
|
ErrPayloadChecksum
|
|
|
|
// ErrTooManyAddrs is returned when an address list exceeds the maximum
|
|
// allowed.
|
|
ErrTooManyAddrs
|
|
|
|
// ErrTooManyTxs is returned when a the number of transactions exceed the
|
|
// maximum allowed.
|
|
ErrTooManyTxs
|
|
|
|
// ErrMsgInvalidForPVer is returned when a message is invalid for
|
|
// the expected protocol version.
|
|
ErrMsgInvalidForPVer
|
|
|
|
// ErrFilterTooLarge is returned when a committed filter exceeds
|
|
// the maximum size allowed.
|
|
ErrFilterTooLarge
|
|
|
|
// ErrTooManyProofs is returned when the number of proof hashes
|
|
// exceeds the maximum allowed.
|
|
ErrTooManyProofs
|
|
|
|
// ErrTooManyFilterTypes is returned when the number of filter types
|
|
// exceeds the maximum allowed.
|
|
ErrTooManyFilterTypes
|
|
|
|
// ErrTooManyLocators is returned when the number of block locators exceed
|
|
// the maximum allowed.
|
|
ErrTooManyLocators
|
|
|
|
// ErrTooManyVectors is returned when the number of inventory vectors
|
|
// exceed the maximum allowed.
|
|
ErrTooManyVectors
|
|
|
|
// ErrTooManyHeaders is returned when the number of block headers exceed
|
|
// the maximum allowed.
|
|
ErrTooManyHeaders
|
|
|
|
// ErrHeaderContainsTxs is returned when a header's transactions
|
|
// count is greater than zero.
|
|
ErrHeaderContainsTxs
|
|
|
|
// ErrTooManyVotes is returned when the number of vote hashes exceed the
|
|
// maximum allowed.
|
|
ErrTooManyVotes
|
|
|
|
// ErrTooManyBlocks is returned when the number of block hashes exceed the
|
|
// maximum allowed.
|
|
ErrTooManyBlocks
|
|
|
|
// ErrMismatchedWitnessCount returned when a transaction has unequal witness
|
|
// and prefix txin quantities.
|
|
ErrMismatchedWitnessCount
|
|
|
|
// ErrUnknownTxType is returned when a transaction type is unknown.
|
|
ErrUnknownTxType
|
|
|
|
// ErrReadInPrefixFromWitnessOnlyTx is returned when attempting to read a
|
|
// transaction input prefix from a witness only transaction.
|
|
ErrReadInPrefixFromWitnessOnlyTx
|
|
|
|
// ErrInvalidMsg is returned for an invalid message structure.
|
|
ErrInvalidMsg
|
|
|
|
// ErrUserAgentTooLong is returned when the provided user agent exceeds
|
|
// the maximum allowed.
|
|
ErrUserAgentTooLong
|
|
|
|
// ErrTooManyFilterHeaders is returned when the number of committed filter
|
|
// headers exceed the maximum allowed.
|
|
ErrTooManyFilterHeaders
|
|
|
|
// ErrMalformedStrictString is returned when a string that has strict
|
|
// formatting requirements does not conform to the requirements.
|
|
ErrMalformedStrictString
|
|
|
|
// ErrTooManyInitialStateTypes is returned when the number of initial
|
|
// state types is larger than the maximum allowed by the protocol.
|
|
ErrTooManyInitStateTypes
|
|
|
|
// ErrInitialStateTypeTooLong is returned when an individual initial
|
|
// state type is longer than allowed by the protocol.
|
|
ErrInitStateTypeTooLong
|
|
|
|
// ErrTooManyTSpends is returned when the number of tspend hashes
|
|
// exceeds the maximum allowed.
|
|
ErrTooManyTSpends
|
|
)
|
|
|
|
// Map of ErrorCode values back to their constant names for pretty printing.
|
|
var errorCodeStrings = map[ErrorCode]string{
|
|
ErrNonCanonicalVarInt: "ErrNonCanonicalVarInt",
|
|
ErrVarStringTooLong: "ErrVarStringTooLong",
|
|
ErrVarBytesTooLong: "ErrVarBytesTooLong",
|
|
ErrCmdTooLong: "ErrCmdTooLong",
|
|
ErrPayloadTooLarge: "ErrPayloadTooLarge",
|
|
ErrWrongNetwork: "ErrWrongNetwork",
|
|
ErrMalformedCmd: "ErrMalformedCmd",
|
|
ErrUnknownCmd: "ErrUnknownCmd",
|
|
ErrPayloadChecksum: "ErrPayloadChecksum",
|
|
ErrTooManyAddrs: "ErrTooManyAddrs",
|
|
ErrTooManyTxs: "ErrTooManyTxs",
|
|
ErrMsgInvalidForPVer: "ErrMsgInvalidForPVer",
|
|
ErrFilterTooLarge: "ErrFilterTooLarge",
|
|
ErrTooManyProofs: "ErrTooManyProofs",
|
|
ErrTooManyFilterTypes: "ErrTooManyFilterTypes",
|
|
ErrTooManyLocators: "ErrTooManyLocators",
|
|
ErrTooManyVectors: "ErrTooManyVectors",
|
|
ErrTooManyHeaders: "ErrTooManyHeaders",
|
|
ErrHeaderContainsTxs: "ErrHeaderContainsTxs",
|
|
ErrTooManyVotes: "ErrTooManyVotes",
|
|
ErrTooManyBlocks: "ErrTooManyBlocks",
|
|
ErrMismatchedWitnessCount: "ErrMismatchedWitnessCount",
|
|
ErrUnknownTxType: "ErrUnknownTxType",
|
|
ErrReadInPrefixFromWitnessOnlyTx: "ErrReadInPrefixFromWitnessOnlyTx",
|
|
ErrInvalidMsg: "ErrInvalidMsg",
|
|
ErrUserAgentTooLong: "ErrUserAgentTooLong",
|
|
ErrTooManyFilterHeaders: "ErrTooManyFilterHeaders",
|
|
ErrMalformedStrictString: "ErrMalformedStrictString",
|
|
ErrTooManyInitStateTypes: "ErrTooManyInitStateTypes",
|
|
ErrInitStateTypeTooLong: "ErrInitStateTypeTooLong",
|
|
ErrTooManyTSpends: "ErrTooManyTSpends",
|
|
}
|
|
|
|
// String returns the ErrorCode as a human-readable name.
|
|
func (e ErrorCode) String() string {
|
|
if s := errorCodeStrings[e]; s != "" {
|
|
return s
|
|
}
|
|
return fmt.Sprintf("Unknown ErrorCode (%d)", int(e))
|
|
}
|
|
|
|
// Error implements the error interface.
|
|
func (e ErrorCode) Error() string {
|
|
return e.String()
|
|
}
|
|
|
|
// Is implements the interface to work with the standard library's errors.Is.
|
|
//
|
|
// It returns true in the following cases:
|
|
// - The target is a *MessageError and the error codes match
|
|
// - The target is an ErrorCode and it the error codes match
|
|
func (e ErrorCode) Is(target error) bool {
|
|
// nolint: errorlint
|
|
switch target := target.(type) {
|
|
case *MessageError:
|
|
return e == target.ErrorCode
|
|
|
|
case ErrorCode:
|
|
return e == target
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// MessageError describes an issue with a message.
|
|
// An example of some potential issues are messages from the wrong decred
|
|
// network, invalid commands, mismatched checksums, and exceeding max payloads.
|
|
//
|
|
// This provides a mechanism for the caller to type assert the error to
|
|
// differentiate between general io errors such as io.EOF and issues that
|
|
// resulted from malformed messages.
|
|
type MessageError struct {
|
|
Func string // Function name
|
|
ErrorCode ErrorCode // Describes the kind of error
|
|
Description string // Human readable description of the issue
|
|
}
|
|
|
|
// Error satisfies the error interface and prints human-readable errors.
|
|
func (m MessageError) Error() string {
|
|
if m.Func != "" {
|
|
return fmt.Sprintf("%v: %v", m.Func, m.Description)
|
|
}
|
|
return m.Description
|
|
}
|
|
|
|
// messageError creates an Error given a set of arguments.
|
|
func messageError(funcName string, c ErrorCode, desc string) *MessageError {
|
|
return &MessageError{Func: funcName, ErrorCode: c, Description: desc}
|
|
}
|
|
|
|
// Is implements the interface to work with the standard library's errors.Is.
|
|
//
|
|
// It returns true in the following cases:
|
|
// - The target is a *MessageError and the error codes match
|
|
// - The target is an ErrorCode and it the error codes match
|
|
func (m *MessageError) Is(target error) bool {
|
|
// nolint: errorlint
|
|
switch target := target.(type) {
|
|
case *MessageError:
|
|
return m.ErrorCode == target.ErrorCode
|
|
|
|
case ErrorCode:
|
|
return target == m.ErrorCode
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// Unwrap returns the underlying wrapped error if it is not ErrOther.
|
|
// Unwrap returns the ErrorCode. Else, it returns nil.
|
|
func (m *MessageError) Unwrap() error {
|
|
return m.ErrorCode
|
|
}
|