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.
12 // defaultInvListAlloc is the default size used for the backing array for an
13 // inventory list. The array will dynamically grow as needed, but this
14 // figure is intended to provide enough space for the max number of inventory
15 // vectors in a *typical* inventory message without needing to grow the backing
16 // array multiple times. Technically, the list can grow to MaxInvPerMsg, but
17 // rather than using that large figure, this figure more accurately reflects the
19 const defaultInvListAlloc = 1000
21 // MsgInv implements the Message interface and represents a bitcoin inv message.
22 // It is used to advertise a peer's known data such as blocks and transactions
23 // through inventory vectors. It may be sent unsolicited to inform other peers
24 // of the data or in response to a getblocks message (MsgGetBlocks). Each
25 // message is limited to a maximum number of inventory vectors, which is
28 // Use the AddInvVect function to build up the list of inventory vectors when
29 // sending an inv message to another peer.
34 // AddInvVect adds an inventory vector to the message.
35 func (msg *MsgInv) AddInvVect(iv *InvVect) error {
36 if len(msg.InvList)+1 > MaxInvPerMsg {
37 str := fmt.Sprintf("too many invvect in message [max %v]",
39 return messageError("MsgInv.AddInvVect", str)
42 msg.InvList = append(msg.InvList, iv)
46 // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
47 // This is part of the Message interface implementation.
48 func (msg *MsgInv) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
49 count, err := ReadVarInt(r, pver)
54 // Limit to max inventory vectors per message.
55 if count > MaxInvPerMsg {
56 str := fmt.Sprintf("too many invvect in message [%v]", count)
57 return messageError("MsgInv.BtcDecode", str)
60 // Create a contiguous slice of inventory vectors to deserialize into in
61 // order to reduce the number of allocations.
62 invList := make([]InvVect, count)
63 msg.InvList = make([]*InvVect, 0, count)
64 for i := uint64(0); i < count; i++ {
66 err := readInvVect(r, pver, iv)
76 // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
77 // This is part of the Message interface implementation.
78 func (msg *MsgInv) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
79 // Limit to max inventory vectors per message.
80 count := len(msg.InvList)
81 if count > MaxInvPerMsg {
82 str := fmt.Sprintf("too many invvect in message [%v]", count)
83 return messageError("MsgInv.BtcEncode", str)
86 err := WriteVarInt(w, pver, uint64(count))
91 for _, iv := range msg.InvList {
92 err := writeInvVect(w, pver, iv)
101 // Command returns the protocol command string for the message. This is part
102 // of the Message interface implementation.
103 func (msg *MsgInv) Command() string {
107 // MaxPayloadLength returns the maximum length the payload can be for the
108 // receiver. This is part of the Message interface implementation.
109 func (msg *MsgInv) MaxPayloadLength(pver uint32) uint32 {
110 // Num inventory vectors (varInt) + max allowed inventory vectors.
111 return MaxVarIntPayload + (MaxInvPerMsg * maxInvVectPayload)
114 // NewMsgInv returns a new bitcoin inv message that conforms to the Message
115 // interface. See MsgInv for details.
116 func NewMsgInv() *MsgInv {
118 InvList: make([]*InvVect, 0, defaultInvListAlloc),
122 // NewMsgInvSizeHint returns a new bitcoin inv message that conforms to the
123 // Message interface. See MsgInv for details. This function differs from
124 // NewMsgInv in that it allows a default allocation size for the backing array
125 // which houses the inventory vector list. This allows callers who know in
126 // advance how large the inventory list will grow to avoid the overhead of
127 // growing the internal backing array several times when appending large amounts
128 // of inventory vectors with AddInvVect. Note that the specified hint is just
129 // that - a hint that is used for the default allocation size. Adding more
130 // (or less) inventory vectors will still work properly. The size hint is
131 // limited to MaxInvPerMsg.
132 func NewMsgInvSizeHint(sizeHint uint) *MsgInv {
133 // Limit the specified hint to the maximum allow per message.
134 if sizeHint > MaxInvPerMsg {
135 sizeHint = MaxInvPerMsg
139 InvList: make([]*InvVect, 0, sizeHint),