btcd/wire/invvect.go

132 lines
4.0 KiB
Go

// Copyright (c) 2013-2016 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package wire
import (
"fmt"
"io"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
const (
// MaxInvPerMsg is the maximum number of inventory vectors that can be in a
// single bitcoin inv message.
MaxInvPerMsg = 50000
// Maximum payload size for an inventory vector.
maxInvVectPayload = 4 + chainhash.HashSize
// InvWitnessFlag denotes that the inventory vector type is requesting,
// or sending a version which includes witness data.
InvWitnessFlag = 1 << 30
)
// InvType represents the allowed types of inventory vectors. See InvVect.
type InvType uint32
// These constants define the various supported inventory vector types.
const (
InvTypeError InvType = 0
InvTypeTx InvType = 1
InvTypeBlock InvType = 2
InvTypeFilteredBlock InvType = 3
InvTypeWitnessBlock InvType = InvTypeBlock | InvWitnessFlag
InvTypeWitnessTx InvType = InvTypeTx | InvWitnessFlag
InvTypeFilteredWitnessBlock InvType = InvTypeFilteredBlock | InvWitnessFlag
)
// Map of service flags back to their constant names for pretty printing.
var ivStrings = map[InvType]string{
InvTypeError: "ERROR",
InvTypeTx: "MSG_TX",
InvTypeBlock: "MSG_BLOCK",
InvTypeFilteredBlock: "MSG_FILTERED_BLOCK",
InvTypeWitnessBlock: "MSG_WITNESS_BLOCK",
InvTypeWitnessTx: "MSG_WITNESS_TX",
InvTypeFilteredWitnessBlock: "MSG_FILTERED_WITNESS_BLOCK",
}
// String returns the InvType in human-readable form.
func (invtype InvType) String() string {
if s, ok := ivStrings[invtype]; ok {
return s
}
return fmt.Sprintf("Unknown InvType (%d)", uint32(invtype))
}
// InvVect defines a bitcoin inventory vector which is used to describe data,
// as specified by the Type field, that a peer wants, has, or does not have to
// another peer.
type InvVect struct {
Type InvType // Type of data
Hash chainhash.Hash // Hash of the data
}
// NewInvVect returns a new InvVect using the provided type and hash.
func NewInvVect(typ InvType, hash *chainhash.Hash) *InvVect {
return &InvVect{
Type: typ,
Hash: *hash,
}
}
// readInvVect reads an encoded InvVect from r depending on the protocol
// version.
//
// DEPRECATED: Use readInvVectBuf instead.
func readInvVect(r io.Reader, pver uint32, iv *InvVect) error {
buf := binarySerializer.Borrow()
err := readInvVectBuf(r, pver, iv, buf)
binarySerializer.Return(buf)
return err
}
// readInvVectBuf reads an encoded InvVect from r depending on the protocol
// version.
//
// If b is non-nil, the provided buffer will be used for serializing small
// values. Otherwise a buffer will be drawn from the binarySerializer's pool
// and return when the method finishes.
//
// NOTE: b MUST either be nil or at least an 8-byte slice.
func readInvVectBuf(r io.Reader, pver uint32, iv *InvVect, buf []byte) error {
if _, err := io.ReadFull(r, buf[:4]); err != nil {
return err
}
iv.Type = InvType(littleEndian.Uint32(buf[:4]))
_, err := io.ReadFull(r, iv.Hash[:])
return err
}
// writeInvVect serializes an InvVect to w depending on the protocol version.
//
// DEPRECATED: Use writeInvVectBuf instead.
func writeInvVect(w io.Writer, pver uint32, iv *InvVect) error {
buf := binarySerializer.Borrow()
err := writeInvVectBuf(w, pver, iv, buf)
binarySerializer.Return(buf)
return err
}
// writeInvVectBuf serializes an InvVect to w depending on the protocol version.
//
// If b is non-nil, the provided buffer will be used for serializing small
// values. Otherwise a buffer will be drawn from the binarySerializer's pool
// and return when the method finishes.
//
// NOTE: b MUST either be nil or at least an 8-byte slice.
func writeInvVectBuf(w io.Writer, pver uint32, iv *InvVect, buf []byte) error {
littleEndian.PutUint32(buf[:4], uint32(iv.Type))
if _, err := w.Write(buf[:4]); err != nil {
return err
}
_, err := w.Write(iv.Hash[:])
return err
}