github.com/lbryio/lbcd@v0.22.119/wire/msgaddr.go (about) 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 }