neoneo-go/pkg/network/peer.go
Roman Khimov 23f118a1a9 network: rework discoverer/server interaction
* treat connected/handshaked peers separately in the discoverer, save
   "original" address for connected ones, it can be a name instead of IP and
   it's important to keep it to avoid reconnections
 * store name->IP mapping for seeds if and when they're connected to avoid
   reconnections
 * block seed if it's detected to be our own node (which is often the case for
   small private networks)
 * add an event for handshaked peers in the server, connected but
   non-handshaked ones are not really helpful for MinPeers or GetAddr logic

Fixes #2796.
2022-11-17 17:07:19 +03:00

95 lines
3.6 KiB
Go

package network
import (
"context"
"net"
"github.com/nspcc-dev/neo-go/pkg/network/payload"
)
type AddressablePeer interface {
// ConnectionAddr returns an address-like identifier of this connection
// before we have a proper one (after the handshake). It's either the
// address from discoverer (if initiated from node) or one from socket
// (if connected to node from outside).
ConnectionAddr() string
// PeerAddr returns the remote address that should be used to establish
// a new connection to the node. It can differ from the RemoteAddr
// address in case the remote node is a client and its current
// connection port is different from the one the other node should use
// to connect to it. It's only valid after the handshake is completed.
// Before that, it returns the same address as RemoteAddr.
PeerAddr() net.Addr
// Version returns peer's version message if the peer has handshaked
// already.
Version() *payload.Version
}
// Peer represents a network node neo-go is connected to.
type Peer interface {
AddressablePeer
// RemoteAddr returns the remote address that we're connected to now.
RemoteAddr() net.Addr
Disconnect(error)
// BroadcastPacket is a context-bound packet enqueuer, it either puts the
// given packet into the queue or exits with errors if the context expires
// or peer disconnects. It accepts a slice of bytes that
// can be shared with other queues (so that message marshalling can be
// done once for all peers). It returns an error if the peer has not yet
// completed handshaking.
BroadcastPacket(context.Context, []byte) error
// BroadcastHPPacket is the same as BroadcastPacket, but uses a high-priority
// queue.
BroadcastHPPacket(context.Context, []byte) error
// EnqueueP2PMessage is a blocking packet enqueuer, it doesn't return until
// it puts the given message into the queue. It returns an error if the peer
// has not yet completed handshaking. This queue is intended to be used for
// unicast peer to peer communication that is more important than broadcasts
// (handled by BroadcastPacket) but less important than high-priority
// messages (handled by EnqueueHPMessage).
EnqueueP2PMessage(*Message) error
// EnqueueP2PPacket is similar to EnqueueP2PMessage, but accepts a slice of
// message(s) bytes.
EnqueueP2PPacket([]byte) error
// EnqueueHPMessage is similar to EnqueueP2PMessage, but uses a high-priority
// queue.
EnqueueHPMessage(*Message) error
// EnqueueHPPacket is similar to EnqueueHPMessage, but accepts a slice of
// message(s) bytes.
EnqueueHPPacket([]byte) error
LastBlockIndex() uint32
Handshaked() bool
IsFullNode() bool
// SetPingTimer adds an outgoing ping to the counter and sets a PingTimeout
// timer that will shut the connection down in case of no response.
SetPingTimer()
// SendVersion checks handshake status and sends a version message to
// the peer.
SendVersion() error
SendVersionAck(*Message) error
// StartProtocol is a goroutine to be run after the handshake. It
// implements basic peer-related protocol handling.
StartProtocol()
HandleVersion(*payload.Version) error
HandleVersionAck() error
// HandlePing checks ping contents against Peer's state and updates it.
HandlePing(ping *payload.Ping) error
// HandlePong checks pong contents against Peer's state and updates it.
HandlePong(pong *payload.Ping) error
// AddGetAddrSent is to inform local peer context that a getaddr command
// is sent. The decision to send getaddr is server-wide, but it needs to be
// accounted for in peer's context, thus this method.
AddGetAddrSent()
// CanProcessAddr checks whether an addr command is expected to come from
// this peer and can be processed.
CanProcessAddr() bool
}