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