2018-01-26 18:04:13 +00:00
|
|
|
package network
|
|
|
|
|
|
|
|
import (
|
2018-01-31 08:27:08 +00:00
|
|
|
"fmt"
|
2018-01-26 18:04:13 +00:00
|
|
|
"log"
|
|
|
|
"net"
|
2018-01-29 18:17:49 +00:00
|
|
|
|
|
|
|
"github.com/anthdm/neo-go/pkg/util"
|
2018-01-26 18:04:13 +00:00
|
|
|
)
|
|
|
|
|
2018-01-31 08:27:08 +00:00
|
|
|
// Peer is the local representation of a remote node. It's an interface that may
|
|
|
|
// be backed by any concrete transport: local, HTTP, tcp.
|
|
|
|
type Peer interface {
|
|
|
|
id() uint32
|
|
|
|
endpoint() util.Endpoint
|
|
|
|
send(*Message)
|
|
|
|
verack() bool
|
|
|
|
verify(uint32)
|
|
|
|
disconnect()
|
|
|
|
}
|
|
|
|
|
|
|
|
// LocalPeer is a peer without any transport, mainly used for testing.
|
|
|
|
type LocalPeer struct {
|
|
|
|
_id uint32
|
|
|
|
_verack bool
|
|
|
|
_endpoint util.Endpoint
|
|
|
|
_send chan *Message
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewLocalPeer return a LocalPeer.
|
|
|
|
func NewLocalPeer() *LocalPeer {
|
|
|
|
e, _ := util.EndpointFromString("1.1.1.1:1111")
|
|
|
|
return &LocalPeer{_endpoint: e}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *LocalPeer) id() uint32 { return p._id }
|
|
|
|
func (p *LocalPeer) verack() bool { return p._verack }
|
|
|
|
func (p *LocalPeer) endpoint() util.Endpoint { return p._endpoint }
|
|
|
|
func (p *LocalPeer) disconnect() {}
|
|
|
|
|
|
|
|
func (p *LocalPeer) send(msg *Message) {
|
|
|
|
p._send <- msg
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *LocalPeer) verify(id uint32) {
|
|
|
|
fmt.Println(id)
|
|
|
|
p._verack = true
|
|
|
|
p._id = id
|
|
|
|
}
|
|
|
|
|
|
|
|
// TCPPeer represents a remote node, backed by TCP transport.
|
|
|
|
type TCPPeer struct {
|
|
|
|
_id uint32
|
2018-01-28 13:59:32 +00:00
|
|
|
// underlying TCP connection
|
2018-01-26 18:04:13 +00:00
|
|
|
conn net.Conn
|
2018-01-29 18:17:49 +00:00
|
|
|
// host and port information about this peer.
|
2018-01-31 08:27:08 +00:00
|
|
|
_endpoint util.Endpoint
|
2018-01-29 18:17:49 +00:00
|
|
|
// channel to coordinate messages writen back to the connection.
|
2018-01-31 08:27:08 +00:00
|
|
|
_send chan *Message
|
2018-01-29 18:17:49 +00:00
|
|
|
// whether this peers version was acknowledged.
|
2018-01-31 08:27:08 +00:00
|
|
|
_verack bool
|
2018-01-26 18:04:13 +00:00
|
|
|
}
|
|
|
|
|
2018-01-31 08:27:08 +00:00
|
|
|
// NewTCPPeer returns a pointer to a TCP Peer.
|
|
|
|
func NewTCPPeer(conn net.Conn) *TCPPeer {
|
2018-01-29 18:17:49 +00:00
|
|
|
e, _ := util.EndpointFromString(conn.RemoteAddr().String())
|
|
|
|
|
2018-01-31 08:27:08 +00:00
|
|
|
return &TCPPeer{
|
|
|
|
conn: conn,
|
|
|
|
_send: make(chan *Message),
|
|
|
|
_endpoint: e,
|
2018-01-26 18:04:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-31 08:27:08 +00:00
|
|
|
// id implements the peer interface
|
|
|
|
func (p *TCPPeer) id() uint32 {
|
|
|
|
return p._id
|
|
|
|
}
|
|
|
|
|
|
|
|
// endpoint implements the peer interface
|
|
|
|
func (p *TCPPeer) endpoint() util.Endpoint {
|
|
|
|
return p._endpoint
|
|
|
|
}
|
|
|
|
|
|
|
|
// verack implements the peer interface
|
|
|
|
func (p *TCPPeer) verack() bool {
|
|
|
|
return p._verack
|
|
|
|
}
|
|
|
|
|
|
|
|
// verify implements the peer interface
|
|
|
|
func (p *TCPPeer) verify(id uint32) {
|
|
|
|
p._id = id
|
|
|
|
p._verack = true
|
|
|
|
}
|
|
|
|
|
|
|
|
// send implements the peer interface
|
|
|
|
func (p *TCPPeer) send(msg *Message) {
|
|
|
|
p._send <- msg
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *TCPPeer) disconnect() {
|
|
|
|
close(p._send)
|
|
|
|
p.conn.Close()
|
|
|
|
}
|
|
|
|
|
2018-01-26 18:04:13 +00:00
|
|
|
// writeLoop writes messages to the underlying TCP connection.
|
|
|
|
// A goroutine writeLoop is started for each connection.
|
|
|
|
// There should be at most one writer to a connection executing
|
|
|
|
// all writes from this goroutine.
|
2018-01-31 08:27:08 +00:00
|
|
|
func (p *TCPPeer) writeLoop() {
|
2018-01-26 18:04:13 +00:00
|
|
|
// clean up the connection.
|
|
|
|
defer func() {
|
|
|
|
p.conn.Close()
|
|
|
|
}()
|
|
|
|
|
|
|
|
for {
|
2018-01-31 08:27:08 +00:00
|
|
|
msg := <-p._send
|
|
|
|
|
|
|
|
rpcLogger.Printf("[SERVER] :: OUT :: %s :: %+v", msg.commandType(), msg.Payload)
|
|
|
|
|
2018-01-26 18:04:13 +00:00
|
|
|
if err := msg.encode(p.conn); err != nil {
|
|
|
|
log.Printf("encode error: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|