OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / btcsuite / btcd / wire / msgaddr.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 // MaxAddrPerMsg is the maximum number of addresses that can be in a single
13 // bitcoin addr message (MsgAddr).
14 const MaxAddrPerMsg = 1000
15
16 // MsgAddr implements the Message interface and represents a bitcoin
17 // addr message.  It is used to provide a list of known active peers on the
18 // network.  An active peer is considered one that has transmitted a message
19 // within the last 3 hours.  Nodes which have not transmitted in that time
20 // frame should be forgotten.  Each message is limited to a maximum number of
21 // addresses, which is currently 1000.  As a result, multiple messages must
22 // be used to relay the full list.
23 //
24 // Use the AddAddress function to build up the list of known addresses when
25 // sending an addr message to another peer.
26 type MsgAddr struct {
27         AddrList []*NetAddress
28 }
29
30 // AddAddress adds a known active peer to the message.
31 func (msg *MsgAddr) AddAddress(na *NetAddress) error {
32         if len(msg.AddrList)+1 > MaxAddrPerMsg {
33                 str := fmt.Sprintf("too many addresses in message [max %v]",
34                         MaxAddrPerMsg)
35                 return messageError("MsgAddr.AddAddress", str)
36         }
37
38         msg.AddrList = append(msg.AddrList, na)
39         return nil
40 }
41
42 // AddAddresses adds multiple known active peers to the message.
43 func (msg *MsgAddr) AddAddresses(netAddrs ...*NetAddress) error {
44         for _, na := range netAddrs {
45                 err := msg.AddAddress(na)
46                 if err != nil {
47                         return err
48                 }
49         }
50         return nil
51 }
52
53 // ClearAddresses removes all addresses from the message.
54 func (msg *MsgAddr) ClearAddresses() {
55         msg.AddrList = []*NetAddress{}
56 }
57
58 // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
59 // This is part of the Message interface implementation.
60 func (msg *MsgAddr) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
61         count, err := ReadVarInt(r, pver)
62         if err != nil {
63                 return err
64         }
65
66         // Limit to max addresses per message.
67         if count > MaxAddrPerMsg {
68                 str := fmt.Sprintf("too many addresses for message "+
69                         "[count %v, max %v]", count, MaxAddrPerMsg)
70                 return messageError("MsgAddr.BtcDecode", str)
71         }
72
73         addrList := make([]NetAddress, count)
74         msg.AddrList = make([]*NetAddress, 0, count)
75         for i := uint64(0); i < count; i++ {
76                 na := &addrList[i]
77                 err := readNetAddress(r, pver, na, true)
78                 if err != nil {
79                         return err
80                 }
81                 msg.AddAddress(na)
82         }
83         return nil
84 }
85
86 // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
87 // This is part of the Message interface implementation.
88 func (msg *MsgAddr) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
89         // Protocol versions before MultipleAddressVersion only allowed 1 address
90         // per message.
91         count := len(msg.AddrList)
92         if pver < MultipleAddressVersion && count > 1 {
93                 str := fmt.Sprintf("too many addresses for message of "+
94                         "protocol version %v [count %v, max 1]", pver, count)
95                 return messageError("MsgAddr.BtcEncode", str)
96
97         }
98         if count > MaxAddrPerMsg {
99                 str := fmt.Sprintf("too many addresses for message "+
100                         "[count %v, max %v]", count, MaxAddrPerMsg)
101                 return messageError("MsgAddr.BtcEncode", str)
102         }
103
104         err := WriteVarInt(w, pver, uint64(count))
105         if err != nil {
106                 return err
107         }
108
109         for _, na := range msg.AddrList {
110                 err = writeNetAddress(w, pver, na, true)
111                 if err != nil {
112                         return err
113                 }
114         }
115
116         return nil
117 }
118
119 // Command returns the protocol command string for the message.  This is part
120 // of the Message interface implementation.
121 func (msg *MsgAddr) Command() string {
122         return CmdAddr
123 }
124
125 // MaxPayloadLength returns the maximum length the payload can be for the
126 // receiver.  This is part of the Message interface implementation.
127 func (msg *MsgAddr) MaxPayloadLength(pver uint32) uint32 {
128         if pver < MultipleAddressVersion {
129                 // Num addresses (varInt) + a single net addresses.
130                 return MaxVarIntPayload + maxNetAddressPayload(pver)
131         }
132
133         // Num addresses (varInt) + max allowed addresses.
134         return MaxVarIntPayload + (MaxAddrPerMsg * maxNetAddressPayload(pver))
135 }
136
137 // NewMsgAddr returns a new bitcoin addr message that conforms to the
138 // Message interface.  See MsgAddr for details.
139 func NewMsgAddr() *MsgAddr {
140         return &MsgAddr{
141                 AddrList: make([]*NetAddress, 0, MaxAddrPerMsg),
142         }
143 }