github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/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  }