github.com/nspcc-dev/neo-go@v0.105.2-0.20240517133400-6be757af3eba/pkg/network/payload/address.go (about)

     1  package payload
     2  
     3  import (
     4  	"errors"
     5  	"net"
     6  	"strconv"
     7  	"time"
     8  
     9  	"github.com/nspcc-dev/neo-go/pkg/io"
    10  	"github.com/nspcc-dev/neo-go/pkg/network/capability"
    11  )
    12  
    13  // MaxAddrsCount is the maximum number of addresses that could be packed into
    14  // one payload.
    15  const MaxAddrsCount = 200
    16  
    17  // AddressAndTime payload.
    18  type AddressAndTime struct {
    19  	Timestamp    uint32
    20  	IP           [16]byte
    21  	Capabilities capability.Capabilities
    22  }
    23  
    24  // NewAddressAndTime creates a new AddressAndTime object.
    25  func NewAddressAndTime(e *net.TCPAddr, t time.Time, c capability.Capabilities) *AddressAndTime {
    26  	aat := AddressAndTime{
    27  		Timestamp:    uint32(t.UTC().Unix()),
    28  		Capabilities: c,
    29  	}
    30  	copy(aat.IP[:], e.IP)
    31  	return &aat
    32  }
    33  
    34  // DecodeBinary implements the Serializable interface.
    35  func (p *AddressAndTime) DecodeBinary(br *io.BinReader) {
    36  	p.Timestamp = br.ReadU32LE()
    37  	br.ReadBytes(p.IP[:])
    38  	p.Capabilities.DecodeBinary(br)
    39  }
    40  
    41  // EncodeBinary implements the Serializable interface.
    42  func (p *AddressAndTime) EncodeBinary(bw *io.BinWriter) {
    43  	bw.WriteU32LE(p.Timestamp)
    44  	bw.WriteBytes(p.IP[:])
    45  	p.Capabilities.EncodeBinary(bw)
    46  }
    47  
    48  // GetTCPAddress makes a string from the IP and the port specified in TCPCapability.
    49  // It returns an error if there's no such capability.
    50  func (p *AddressAndTime) GetTCPAddress() (string, error) {
    51  	var netip = make(net.IP, 16)
    52  
    53  	copy(netip, p.IP[:])
    54  	port := -1
    55  	for _, cap := range p.Capabilities {
    56  		if cap.Type == capability.TCPServer {
    57  			port = int(cap.Data.(*capability.Server).Port)
    58  			break
    59  		}
    60  	}
    61  	if port == -1 {
    62  		return "", errors.New("no TCP capability found")
    63  	}
    64  	return net.JoinHostPort(netip.String(), strconv.Itoa(port)), nil
    65  }
    66  
    67  // AddressList is a list with AddrAndTime.
    68  type AddressList struct {
    69  	Addrs []*AddressAndTime
    70  }
    71  
    72  // NewAddressList creates a list for n AddressAndTime elements.
    73  func NewAddressList(n int) *AddressList {
    74  	alist := AddressList{
    75  		Addrs: make([]*AddressAndTime, n),
    76  	}
    77  	return &alist
    78  }
    79  
    80  // DecodeBinary implements the Serializable interface.
    81  func (p *AddressList) DecodeBinary(br *io.BinReader) {
    82  	br.ReadArray(&p.Addrs, MaxAddrsCount)
    83  	if len(p.Addrs) == 0 {
    84  		br.Err = errors.New("no addresses listed")
    85  	}
    86  }
    87  
    88  // EncodeBinary implements the Serializable interface.
    89  func (p *AddressList) EncodeBinary(bw *io.BinWriter) {
    90  	bw.WriteArray(p.Addrs)
    91  }