forked from TrueCloudLab/neoneo-go
Merge pull request #380 from nspcc-dev/drop-endpoint-fix-321
util: drop Endpoint structure, fix #321
This commit is contained in:
commit
33bb371f9b
9 changed files with 50 additions and 85 deletions
|
@ -2,6 +2,7 @@ package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -111,22 +112,23 @@ func (t localTransport) Close() {}
|
||||||
var defaultMessageHandler = func(t *testing.T, msg *Message) {}
|
var defaultMessageHandler = func(t *testing.T, msg *Message) {}
|
||||||
|
|
||||||
type localPeer struct {
|
type localPeer struct {
|
||||||
endpoint util.Endpoint
|
netaddr net.TCPAddr
|
||||||
version *payload.Version
|
version *payload.Version
|
||||||
t *testing.T
|
t *testing.T
|
||||||
messageHandler func(t *testing.T, msg *Message)
|
messageHandler func(t *testing.T, msg *Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLocalPeer(t *testing.T) *localPeer {
|
func newLocalPeer(t *testing.T) *localPeer {
|
||||||
|
naddr, _ := net.ResolveTCPAddr("tcp", "0.0.0.0:0")
|
||||||
return &localPeer{
|
return &localPeer{
|
||||||
t: t,
|
t: t,
|
||||||
endpoint: util.NewEndpoint("0.0.0.0:0"),
|
netaddr: *naddr,
|
||||||
messageHandler: defaultMessageHandler,
|
messageHandler: defaultMessageHandler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *localPeer) Endpoint() util.Endpoint {
|
func (p *localPeer) NetAddr() *net.TCPAddr {
|
||||||
return p.endpoint
|
return &p.netaddr
|
||||||
}
|
}
|
||||||
func (p *localPeer) Disconnect(err error) {}
|
func (p *localPeer) Disconnect(err error) {}
|
||||||
func (p *localPeer) WriteMsg(msg *Message) error {
|
func (p *localPeer) WriteMsg(msg *Message) error {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package payload
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
"github.com/CityOfZion/neo-go/pkg/util"
|
||||||
|
@ -11,16 +12,19 @@ import (
|
||||||
type AddressAndTime struct {
|
type AddressAndTime struct {
|
||||||
Timestamp uint32
|
Timestamp uint32
|
||||||
Services uint64
|
Services uint64
|
||||||
Endpoint util.Endpoint
|
IP [16]byte
|
||||||
|
Port uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewAddressAndTime creates a new AddressAndTime object.
|
// NewAddressAndTime creates a new AddressAndTime object.
|
||||||
func NewAddressAndTime(e util.Endpoint, t time.Time) *AddressAndTime {
|
func NewAddressAndTime(e *net.TCPAddr, t time.Time) *AddressAndTime {
|
||||||
return &AddressAndTime{
|
aat := AddressAndTime{
|
||||||
Timestamp: uint32(t.UTC().Unix()),
|
Timestamp: uint32(t.UTC().Unix()),
|
||||||
Services: 1,
|
Services: 1,
|
||||||
Endpoint: e,
|
Port: uint16(e.Port),
|
||||||
}
|
}
|
||||||
|
copy(aat.IP[:], e.IP)
|
||||||
|
return &aat
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeBinary implements the Payload interface.
|
// DecodeBinary implements the Payload interface.
|
||||||
|
@ -28,8 +32,8 @@ func (p *AddressAndTime) DecodeBinary(r io.Reader) error {
|
||||||
br := util.BinReader{R: r}
|
br := util.BinReader{R: r}
|
||||||
br.ReadLE(&p.Timestamp)
|
br.ReadLE(&p.Timestamp)
|
||||||
br.ReadLE(&p.Services)
|
br.ReadLE(&p.Services)
|
||||||
br.ReadBE(&p.Endpoint.IP)
|
br.ReadBE(&p.IP)
|
||||||
br.ReadBE(&p.Endpoint.Port)
|
br.ReadBE(&p.Port)
|
||||||
return br.Err
|
return br.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +42,8 @@ func (p *AddressAndTime) EncodeBinary(w io.Writer) error {
|
||||||
bw := util.BinWriter{W: w}
|
bw := util.BinWriter{W: w}
|
||||||
bw.WriteLE(p.Timestamp)
|
bw.WriteLE(p.Timestamp)
|
||||||
bw.WriteLE(p.Services)
|
bw.WriteLE(p.Services)
|
||||||
bw.WriteBE(p.Endpoint.IP)
|
bw.WriteBE(p.IP)
|
||||||
bw.WriteBE(p.Endpoint.Port)
|
bw.WriteBE(p.Port)
|
||||||
return bw.Err
|
return bw.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,23 +3,26 @@ package payload
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestEncodeDecodeAddress(t *testing.T) {
|
func TestEncodeDecodeAddress(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
e = util.NewEndpoint("127.0.0.1:2000")
|
e, _ = net.ResolveTCPAddr("tcp", "127.0.0.1:2000")
|
||||||
ts = time.Now()
|
ts = time.Now()
|
||||||
addr = NewAddressAndTime(e, ts)
|
addr = NewAddressAndTime(e, ts)
|
||||||
buf = new(bytes.Buffer)
|
buf = new(bytes.Buffer)
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.Equal(t, ts.UTC().Unix(), int64(addr.Timestamp))
|
assert.Equal(t, ts.UTC().Unix(), int64(addr.Timestamp))
|
||||||
assert.Equal(t, e, addr.Endpoint)
|
aatip := make(net.IP, 16)
|
||||||
|
copy(aatip, addr.IP[:])
|
||||||
|
assert.Equal(t, e.IP, aatip)
|
||||||
|
assert.Equal(t, e.Port, int(addr.Port))
|
||||||
err := addr.EncodeBinary(buf)
|
err := addr.EncodeBinary(buf)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
@ -34,7 +37,7 @@ func TestEncodeDecodeAddressList(t *testing.T) {
|
||||||
var lenList uint8 = 4
|
var lenList uint8 = 4
|
||||||
addrList := &AddressList{make([]*AddressAndTime, lenList)}
|
addrList := &AddressList{make([]*AddressAndTime, lenList)}
|
||||||
for i := 0; i < int(lenList); i++ {
|
for i := 0; i < int(lenList); i++ {
|
||||||
e := util.NewEndpoint(fmt.Sprintf("127.0.0.1:200%d", i))
|
e, _ := net.ResolveTCPAddr("tcp", fmt.Sprintf("127.0.0.1:200%d", i))
|
||||||
addrList.Addrs[i] = NewAddressAndTime(e, time.Now())
|
addrList.Addrs[i] = NewAddressAndTime(e, time.Now())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/network/payload"
|
"github.com/CityOfZion/neo-go/pkg/network/payload"
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Peer represents a network node neo-go is connected to.
|
// Peer represents a network node neo-go is connected to.
|
||||||
type Peer interface {
|
type Peer interface {
|
||||||
Endpoint() util.Endpoint
|
NetAddr() *net.TCPAddr
|
||||||
Disconnect(error)
|
Disconnect(error)
|
||||||
WriteMsg(msg *Message) error
|
WriteMsg(msg *Message) error
|
||||||
Done() chan error
|
Done() chan error
|
||||||
|
|
|
@ -133,17 +133,17 @@ func (s *Server) run() {
|
||||||
// When a new peer is connected we send out our version immediately.
|
// When a new peer is connected we send out our version immediately.
|
||||||
if err := s.sendVersion(p); err != nil {
|
if err := s.sendVersion(p); err != nil {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"endpoint": p.Endpoint(),
|
"addr": p.NetAddr(),
|
||||||
}).Error(err)
|
}).Error(err)
|
||||||
}
|
}
|
||||||
s.peers[p] = true
|
s.peers[p] = true
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"endpoint": p.Endpoint(),
|
"addr": p.NetAddr(),
|
||||||
}).Info("new peer connected")
|
}).Info("new peer connected")
|
||||||
case drop := <-s.unregister:
|
case drop := <-s.unregister:
|
||||||
delete(s.peers, drop.peer)
|
delete(s.peers, drop.peer)
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"endpoint": drop.peer.Endpoint(),
|
"addr": drop.peer.NetAddr(),
|
||||||
"reason": drop.reason,
|
"reason": drop.reason,
|
||||||
"peerCount": s.PeerCount(),
|
"peerCount": s.PeerCount(),
|
||||||
}).Warn("peer disconnected")
|
}).Warn("peer disconnected")
|
||||||
|
@ -168,7 +168,7 @@ func (s *Server) PeerCount() int {
|
||||||
// every ProtoTickInterval with the peer.
|
// every ProtoTickInterval with the peer.
|
||||||
func (s *Server) startProtocol(p Peer) {
|
func (s *Server) startProtocol(p Peer) {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"endpoint": p.Endpoint(),
|
"addr": p.NetAddr(),
|
||||||
"userAgent": string(p.Version().UserAgent),
|
"userAgent": string(p.Version().UserAgent),
|
||||||
"startHeight": p.Version().StartHeight,
|
"startHeight": p.Version().StartHeight,
|
||||||
"id": p.Version().Nonce,
|
"id": p.Version().Nonce,
|
||||||
|
@ -207,7 +207,7 @@ func (s *Server) sendVersion(p Peer) error {
|
||||||
// When a peer sends out his version we reply with verack after validating
|
// When a peer sends out his version we reply with verack after validating
|
||||||
// the version.
|
// the version.
|
||||||
func (s *Server) handleVersionCmd(p Peer, version *payload.Version) error {
|
func (s *Server) handleVersionCmd(p Peer, version *payload.Version) error {
|
||||||
if p.Endpoint().Port != version.Port {
|
if p.NetAddr().Port != int(version.Port) {
|
||||||
return errPortMismatch
|
return errPortMismatch
|
||||||
}
|
}
|
||||||
if s.id == version.Nonce {
|
if s.id == version.Nonce {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package network
|
package network
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/network/payload"
|
"github.com/CityOfZion/neo-go/pkg/network/payload"
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,7 +39,8 @@ func TestVerackAfterHandleVersionCmd(t *testing.T) {
|
||||||
s = newTestServer()
|
s = newTestServer()
|
||||||
p = newLocalPeer(t)
|
p = newLocalPeer(t)
|
||||||
)
|
)
|
||||||
p.endpoint = util.NewEndpoint("0.0.0.0:3000")
|
na, _ := net.ResolveTCPAddr("tcp", "0.0.0.0:3000")
|
||||||
|
p.netaddr = *na
|
||||||
|
|
||||||
// Should have a verack
|
// Should have a verack
|
||||||
p.messageHandler = func(t *testing.T, msg *Message) {
|
p.messageHandler = func(t *testing.T, msg *Message) {
|
||||||
|
@ -62,7 +63,8 @@ func TestServerNotSendsVerack(t *testing.T) {
|
||||||
s.id = 1
|
s.id = 1
|
||||||
go s.run()
|
go s.run()
|
||||||
|
|
||||||
p.endpoint = util.NewEndpoint("0.0.0.0:3000")
|
na, _ := net.ResolveTCPAddr("tcp", "0.0.0.0:3000")
|
||||||
|
p.netaddr = *na
|
||||||
s.register <- p
|
s.register <- p
|
||||||
|
|
||||||
// Port should mismatch
|
// Port should mismatch
|
||||||
|
|
|
@ -5,15 +5,14 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/CityOfZion/neo-go/pkg/network/payload"
|
"github.com/CityOfZion/neo-go/pkg/network/payload"
|
||||||
"github.com/CityOfZion/neo-go/pkg/util"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TCPPeer represents a connected remote node in the
|
// TCPPeer represents a connected remote node in the
|
||||||
// network over TCP.
|
// network over TCP.
|
||||||
type TCPPeer struct {
|
type TCPPeer struct {
|
||||||
// underlying TCP connection.
|
// underlying TCP connection.
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
endpoint util.Endpoint
|
addr net.TCPAddr
|
||||||
|
|
||||||
// The version of the peer.
|
// The version of the peer.
|
||||||
version *payload.Version
|
version *payload.Version
|
||||||
|
@ -25,10 +24,13 @@ type TCPPeer struct {
|
||||||
|
|
||||||
// NewTCPPeer returns a TCPPeer structure based on the given connection.
|
// NewTCPPeer returns a TCPPeer structure based on the given connection.
|
||||||
func NewTCPPeer(conn net.Conn) *TCPPeer {
|
func NewTCPPeer(conn net.Conn) *TCPPeer {
|
||||||
|
raddr := conn.RemoteAddr()
|
||||||
|
// can't fail because raddr is a real connection
|
||||||
|
tcpaddr, _ := net.ResolveTCPAddr(raddr.Network(), raddr.String())
|
||||||
return &TCPPeer{
|
return &TCPPeer{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
done: make(chan error, 1),
|
done: make(chan error, 1),
|
||||||
endpoint: util.NewEndpoint(conn.RemoteAddr().String()),
|
addr: *tcpaddr,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,9 +45,9 @@ func (p *TCPPeer) WriteMsg(msg *Message) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Endpoint implements the Peer interface.
|
// NetAddr implements the Peer interface.
|
||||||
func (p *TCPPeer) Endpoint() util.Endpoint {
|
func (p *TCPPeer) NetAddr() *net.TCPAddr {
|
||||||
return p.endpoint
|
return &p.addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done implements the Peer interface and notifies
|
// Done implements the Peer interface and notifies
|
||||||
|
|
|
@ -180,7 +180,7 @@ Methods:
|
||||||
}
|
}
|
||||||
|
|
||||||
for addr := range s.coreServer.Peers() {
|
for addr := range s.coreServer.Peers() {
|
||||||
peers.AddPeer("connected", addr.Endpoint().String())
|
peers.AddPeer("connected", addr.NetAddr().String())
|
||||||
}
|
}
|
||||||
|
|
||||||
results = peers
|
results = peers
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
package util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Endpoint host + port of a node, compatible with net.Addr.
|
|
||||||
type Endpoint struct {
|
|
||||||
IP [16]byte // TODO: make a uint128 type
|
|
||||||
Port uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewEndpoint creates an Endpoint from the given string.
|
|
||||||
func NewEndpoint(s string) (e Endpoint) {
|
|
||||||
hostPort := strings.Split(s, ":")
|
|
||||||
if len(hostPort) != 2 {
|
|
||||||
return e
|
|
||||||
}
|
|
||||||
host := hostPort[0]
|
|
||||||
port := hostPort[1]
|
|
||||||
|
|
||||||
ch := strings.Split(host, ".")
|
|
||||||
|
|
||||||
buf := [16]byte{}
|
|
||||||
var n int
|
|
||||||
for i := 0; i < len(ch); i++ {
|
|
||||||
n = 12 + i
|
|
||||||
nn, _ := strconv.Atoi(ch[i])
|
|
||||||
buf[n] = byte(nn)
|
|
||||||
}
|
|
||||||
|
|
||||||
p, _ := strconv.Atoi(port)
|
|
||||||
|
|
||||||
return Endpoint{buf, uint16(p)}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Network implements the net.Addr interface.
|
|
||||||
func (e Endpoint) Network() string { return "tcp" }
|
|
||||||
|
|
||||||
// String implements the net.Addr interface.
|
|
||||||
func (e Endpoint) String() string {
|
|
||||||
b := make([]uint8, 4)
|
|
||||||
for i := 0; i < 4; i++ {
|
|
||||||
b[i] = e.IP[len(e.IP)-4+i]
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("%d.%d.%d.%d:%d", b[0], b[1], b[2], b[3], e.Port)
|
|
||||||
}
|
|
Loading…
Reference in a new issue