github.com/btcsuite/btcd@v0.24.0/wire/msgnotfound.go (about) 1 // Copyright (c) 2013-2015 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 12 // MsgNotFound defines a bitcoin notfound message which is sent in response to 13 // a getdata message if any of the requested data in not available on the peer. 14 // Each message is limited to a maximum number of inventory vectors, which is 15 // currently 50,000. 16 // 17 // Use the AddInvVect function to build up the list of inventory vectors when 18 // sending a notfound message to another peer. 19 type MsgNotFound struct { 20 InvList []*InvVect 21 } 22 23 // AddInvVect adds an inventory vector to the message. 24 func (msg *MsgNotFound) AddInvVect(iv *InvVect) error { 25 if len(msg.InvList)+1 > MaxInvPerMsg { 26 str := fmt.Sprintf("too many invvect in message [max %v]", 27 MaxInvPerMsg) 28 return messageError("MsgNotFound.AddInvVect", str) 29 } 30 31 msg.InvList = append(msg.InvList, iv) 32 return nil 33 } 34 35 // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. 36 // This is part of the Message interface implementation. 37 func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error { 38 buf := binarySerializer.Borrow() 39 defer binarySerializer.Return(buf) 40 41 count, err := ReadVarIntBuf(r, pver, buf) 42 if err != nil { 43 return err 44 } 45 46 // Limit to max inventory vectors per message. 47 if count > MaxInvPerMsg { 48 str := fmt.Sprintf("too many invvect in message [%v]", count) 49 return messageError("MsgNotFound.BtcDecode", str) 50 } 51 52 // Create a contiguous slice of inventory vectors to deserialize into in 53 // order to reduce the number of allocations. 54 invList := make([]InvVect, count) 55 msg.InvList = make([]*InvVect, 0, count) 56 for i := uint64(0); i < count; i++ { 57 iv := &invList[i] 58 err := readInvVectBuf(r, pver, iv, buf) 59 if err != nil { 60 return err 61 } 62 msg.AddInvVect(iv) 63 } 64 65 return nil 66 } 67 68 // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 69 // This is part of the Message interface implementation. 70 func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 71 // Limit to max inventory vectors per message. 72 count := len(msg.InvList) 73 if count > MaxInvPerMsg { 74 str := fmt.Sprintf("too many invvect in message [%v]", count) 75 return messageError("MsgNotFound.BtcEncode", str) 76 } 77 78 buf := binarySerializer.Borrow() 79 defer binarySerializer.Return(buf) 80 81 err := WriteVarIntBuf(w, pver, uint64(count), buf) 82 if err != nil { 83 return err 84 } 85 86 for _, iv := range msg.InvList { 87 err := writeInvVectBuf(w, pver, iv, buf) 88 if err != nil { 89 return err 90 } 91 } 92 93 return nil 94 } 95 96 // Command returns the protocol command string for the message. This is part 97 // of the Message interface implementation. 98 func (msg *MsgNotFound) Command() string { 99 return CmdNotFound 100 } 101 102 // MaxPayloadLength returns the maximum length the payload can be for the 103 // receiver. This is part of the Message interface implementation. 104 func (msg *MsgNotFound) MaxPayloadLength(pver uint32) uint32 { 105 // Max var int 9 bytes + max InvVects at 36 bytes each. 106 // Num inventory vectors (varInt) + max allowed inventory vectors. 107 return MaxVarIntPayload + (MaxInvPerMsg * maxInvVectPayload) 108 } 109 110 // NewMsgNotFound returns a new bitcoin notfound message that conforms to the 111 // Message interface. See MsgNotFound for details. 112 func NewMsgNotFound() *MsgNotFound { 113 return &MsgNotFound{ 114 InvList: make([]*InvVect, 0, defaultInvListAlloc), 115 } 116 }