OSDN Git Service

Merge pull request #41 from Bytom/dev
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / wire / msgnotfound.go
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 }