github.com/btcsuite/btcd@v0.24.0/wire/invvect.go (about) 1 // Copyright (c) 2013-2016 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package wire 6 7 import ( 8 "fmt" 9 "io" 10 11 "github.com/btcsuite/btcd/chaincfg/chainhash" 12 ) 13 14 const ( 15 // MaxInvPerMsg is the maximum number of inventory vectors that can be in a 16 // single bitcoin inv message. 17 MaxInvPerMsg = 50000 18 19 // Maximum payload size for an inventory vector. 20 maxInvVectPayload = 4 + chainhash.HashSize 21 22 // InvWitnessFlag denotes that the inventory vector type is requesting, 23 // or sending a version which includes witness data. 24 InvWitnessFlag = 1 << 30 25 ) 26 27 // InvType represents the allowed types of inventory vectors. See InvVect. 28 type InvType uint32 29 30 // These constants define the various supported inventory vector types. 31 const ( 32 InvTypeError InvType = 0 33 InvTypeTx InvType = 1 34 InvTypeBlock InvType = 2 35 InvTypeFilteredBlock InvType = 3 36 InvTypeWitnessBlock InvType = InvTypeBlock | InvWitnessFlag 37 InvTypeWitnessTx InvType = InvTypeTx | InvWitnessFlag 38 InvTypeFilteredWitnessBlock InvType = InvTypeFilteredBlock | InvWitnessFlag 39 ) 40 41 // Map of service flags back to their constant names for pretty printing. 42 var ivStrings = map[InvType]string{ 43 InvTypeError: "ERROR", 44 InvTypeTx: "MSG_TX", 45 InvTypeBlock: "MSG_BLOCK", 46 InvTypeFilteredBlock: "MSG_FILTERED_BLOCK", 47 InvTypeWitnessBlock: "MSG_WITNESS_BLOCK", 48 InvTypeWitnessTx: "MSG_WITNESS_TX", 49 InvTypeFilteredWitnessBlock: "MSG_FILTERED_WITNESS_BLOCK", 50 } 51 52 // String returns the InvType in human-readable form. 53 func (invtype InvType) String() string { 54 if s, ok := ivStrings[invtype]; ok { 55 return s 56 } 57 58 return fmt.Sprintf("Unknown InvType (%d)", uint32(invtype)) 59 } 60 61 // InvVect defines a bitcoin inventory vector which is used to describe data, 62 // as specified by the Type field, that a peer wants, has, or does not have to 63 // another peer. 64 type InvVect struct { 65 Type InvType // Type of data 66 Hash chainhash.Hash // Hash of the data 67 } 68 69 // NewInvVect returns a new InvVect using the provided type and hash. 70 func NewInvVect(typ InvType, hash *chainhash.Hash) *InvVect { 71 return &InvVect{ 72 Type: typ, 73 Hash: *hash, 74 } 75 } 76 77 // readInvVectBuf reads an encoded InvVect from r depending on the protocol 78 // version. 79 // 80 // If b is non-nil, the provided buffer will be used for serializing small 81 // values. Otherwise a buffer will be drawn from the binarySerializer's pool 82 // and return when the method finishes. 83 // 84 // NOTE: b MUST either be nil or at least an 8-byte slice. 85 func readInvVectBuf(r io.Reader, pver uint32, iv *InvVect, buf []byte) error { 86 if _, err := io.ReadFull(r, buf[:4]); err != nil { 87 return err 88 } 89 iv.Type = InvType(littleEndian.Uint32(buf[:4])) 90 91 _, err := io.ReadFull(r, iv.Hash[:]) 92 return err 93 } 94 95 // writeInvVectBuf serializes an InvVect to w depending on the protocol version. 96 // 97 // If b is non-nil, the provided buffer will be used for serializing small 98 // values. Otherwise a buffer will be drawn from the binarySerializer's pool 99 // and return when the method finishes. 100 // 101 // NOTE: b MUST either be nil or at least an 8-byte slice. 102 func writeInvVectBuf(w io.Writer, pver uint32, iv *InvVect, buf []byte) error { 103 littleEndian.PutUint32(buf[:4], uint32(iv.Type)) 104 if _, err := w.Write(buf[:4]); err != nil { 105 return err 106 } 107 108 _, err := w.Write(iv.Hash[:]) 109 return err 110 }