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  }