github.com/palcoin-project/palcd@v1.0.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 count, err := ReadVarInt(r, pver) 39 if err != nil { 40 return err 41 } 42 43 // Limit to max inventory vectors per message. 44 if count > MaxInvPerMsg { 45 str := fmt.Sprintf("too many invvect in message [%v]", count) 46 return messageError("MsgNotFound.BtcDecode", str) 47 } 48 49 // Create a contiguous slice of inventory vectors to deserialize into in 50 // order to reduce the number of allocations. 51 invList := make([]InvVect, count) 52 msg.InvList = make([]*InvVect, 0, count) 53 for i := uint64(0); i < count; i++ { 54 iv := &invList[i] 55 err := readInvVect(r, pver, iv) 56 if err != nil { 57 return err 58 } 59 msg.AddInvVect(iv) 60 } 61 62 return nil 63 } 64 65 // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. 66 // This is part of the Message interface implementation. 67 func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error { 68 // Limit to max inventory vectors per message. 69 count := len(msg.InvList) 70 if count > MaxInvPerMsg { 71 str := fmt.Sprintf("too many invvect in message [%v]", count) 72 return messageError("MsgNotFound.BtcEncode", str) 73 } 74 75 err := WriteVarInt(w, pver, uint64(count)) 76 if err != nil { 77 return err 78 } 79 80 for _, iv := range msg.InvList { 81 err := writeInvVect(w, pver, iv) 82 if err != nil { 83 return err 84 } 85 } 86 87 return nil 88 } 89 90 // Command returns the protocol command string for the message. This is part 91 // of the Message interface implementation. 92 func (msg *MsgNotFound) Command() string { 93 return CmdNotFound 94 } 95 96 // MaxPayloadLength returns the maximum length the payload can be for the 97 // receiver. This is part of the Message interface implementation. 98 func (msg *MsgNotFound) MaxPayloadLength(pver uint32) uint32 { 99 // Max var int 9 bytes + max InvVects at 36 bytes each. 100 // Num inventory vectors (varInt) + max allowed inventory vectors. 101 return MaxVarIntPayload + (MaxInvPerMsg * maxInvVectPayload) 102 } 103 104 // NewMsgNotFound returns a new bitcoin notfound message that conforms to the 105 // Message interface. See MsgNotFound for details. 106 func NewMsgNotFound() *MsgNotFound { 107 return &MsgNotFound{ 108 InvList: make([]*InvVect, 0, defaultInvListAlloc), 109 } 110 }