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