peer

package
v1.7.17 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2022 License: BSD-3-Clause Imports: 37 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NoPrecondition

func NoPrecondition(Peer) bool

func TLSConfig

func TLSConfig(cert tls.Certificate) *tls.Config

Types

type Config

type Config struct {
	// Size, in bytes, of the buffer this peer reads messages into
	ReadBufferSize int
	// Size, in bytes, of the buffer this peer writes messages into
	WriteBufferSize      int
	Clock                mockable.Clock
	Metrics              *Metrics
	MessageCreator       message.Creator
	Log                  logging.Logger
	InboundMsgThrottler  throttling.InboundMsgThrottler
	Network              Network
	Router               router.InboundHandler
	VersionCompatibility version.Compatibility
	MySubnets            ids.Set
	Beacons              validators.Set
	NetworkID            uint32
	PingFrequency        time.Duration
	PongTimeout          time.Duration
	MaxClockDifference   time.Duration

	// Unix time of the last message sent and received respectively
	// Must only be accessed atomically
	LastSent, LastReceived int64

	// Tracks CPU/disk usage caused by each peer.
	ResourceTracker tracker.ResourceTracker

	PingMessage message.OutboundMessage
}

type Info

type Info struct {
	IP             string     `json:"ip"`
	PublicIP       string     `json:"publicIP,omitempty"`
	ID             ids.NodeID `json:"nodeID"`
	Version        string     `json:"version"`
	LastSent       time.Time  `json:"lastSent"`
	LastReceived   time.Time  `json:"lastReceived"`
	ObservedUptime json.Uint8 `json:"observedUptime"`
	TrackedSubnets []ids.ID   `json:"trackedSubnets"`
}

type MessageMetrics

type MessageMetrics struct {
	ReceivedBytes, SentBytes, NumSent, NumFailed, NumReceived prometheus.Counter
	SavedReceivedBytes, SavedSentBytes                        metric.Averager
}

func NewMessageMetrics

func NewMessageMetrics(
	op message.Op,
	namespace string,
	metrics prometheus.Registerer,
	errs *wrappers.Errs,
) *MessageMetrics

type MessageQueue

type MessageQueue interface {
	// Push attempts to add the message to the queue. If the context is
	// canceled, then pushing the message will return `false` and the message
	// will not be added to the queue.
	Push(ctx context.Context, msg message.OutboundMessage) bool

	// Pop blocks until a message is available and then returns the message. If
	// the queue is closed, then `false` is returned.
	Pop() (message.OutboundMessage, bool)

	// PopNow attempts to return a message without blocking. If a message is not
	// available or the queue is closed, then `false` is returned.
	PopNow() (message.OutboundMessage, bool)

	// Close empties the queue and prevents further messages from being pushed
	// onto it. After calling close once, future calls to close will do nothing.
	Close()
}

func NewBlockingMessageQueue

func NewBlockingMessageQueue(
	onFailed SendFailedCallback,
	log logging.Logger,
	bufferSize int,
) MessageQueue

func NewThrottledMessageQueue

func NewThrottledMessageQueue(
	onFailed SendFailedCallback,
	id ids.NodeID,
	log logging.Logger,
	outboundMsgThrottler throttling.OutboundMsgThrottler,
) MessageQueue

type Metrics

type Metrics struct {
	Log                     logging.Logger
	FailedToParse           prometheus.Counter
	NumUselessPeerListBytes prometheus.Counter
	MessageMetrics          map[message.Op]*MessageMetrics
}

func NewMetrics

func NewMetrics(
	log logging.Logger,
	namespace string,
	registerer prometheus.Registerer,
) (*Metrics, error)

func (*Metrics) MultipleSendsFailed

func (m *Metrics) MultipleSendsFailed(op message.Op, count int)

func (*Metrics) Received

func (m *Metrics) Received(msg message.InboundMessage, msgLen uint32)

func (*Metrics) SendFailed

func (m *Metrics) SendFailed(msg message.OutboundMessage)

SendFailed updates the metrics for having failed to send [msg] and removes a reference from the [msg].

func (*Metrics) Sent

func (m *Metrics) Sent(msg message.OutboundMessage)

Sent updates the metrics for having sent [msg] and removes a reference from the [msg].

type Network

type Network interface {
	// Connected is called by the peer once the handshake is finished.
	Connected(ids.NodeID)

	// AllowConnection enables the network is signal to the peer that its
	// connection is no longer desired and should be terminated.
	AllowConnection(ids.NodeID) bool

	// Track allows the peer to notify the network of a potential new peer to
	// connect to.
	//
	// Returns false if this call was not "useful". That is, we were already
	// connected to this node, we already had this tracking information, the
	// signature is invalid or we don't want to connect.
	Track(ips.ClaimedIPPort) bool

	// Disconnected is called when the peer finishes shutting down. It is not
	// guaranteed that [Connected] was called for the provided peer. However, it
	// is guaranteed that [Connected] will not be called after [Disconnected]
	// for a given [Peer] object.
	Disconnected(ids.NodeID)

	// Version provides the peer with the Version message to send to the peer
	// during the handshake.
	Version() (message.OutboundMessage, error)

	// Peers provides the peer with the PeerList message to send to the peer
	// during the handshake.
	Peers() (message.OutboundMessage, error)

	// Pong provides the peer with a Pong message to send to the peer in
	// response to a Ping message.
	Pong(ids.NodeID) (message.OutboundMessage, error)
}

Network defines the interface that is used by a peer to help establish a well connected p2p network.

func NewTestNetwork

func NewTestNetwork(
	mc message.Creator,
	networkID uint32,
	ipPort ips.IPPort,
	version *version.Application,
	signer crypto.Signer,
	subnets ids.Set,
	uptime uint8,
) Network

NewTestNetwork creates and returns a new TestNetwork

type Peer

type Peer interface {
	// ID returns the nodeID of the remote peer.
	ID() ids.NodeID

	// Cert returns the certificate that the remote peer is using to
	// authenticate their messages.
	Cert() *x509.Certificate

	// LastSent returns the last time a message was sent to the peer.
	LastSent() time.Time

	// LastReceived returns the last time a message was received from the peer.
	LastReceived() time.Time

	// Ready returns true if the peer has finished the p2p handshake and is
	// ready to send and receive messages.
	Ready() bool

	// AwaitReady will block until the peer has finished the p2p handshake. If
	// the context is cancelled or the peer starts closing, then an error will
	// be returned.
	AwaitReady(ctx context.Context) error

	// Info returns a description of the state of this peer. It should only be
	// called after [Ready] returns true.
	Info() Info

	// IP returns the claimed IP and signature provided by this peer during the
	// handshake. It should only be called after [Ready] returns true.
	IP() *SignedIP

	// Version returns the claimed node version this peer is running. It should
	// only be called after [Ready] returns true.
	Version() *version.Application

	// TrackedSubnets returns the subnets this peer is running. It should only
	// be called after [Ready] returns true.
	TrackedSubnets() ids.Set

	// ObservedUptime returns the local node's uptime according to the peer. The
	// value ranges from [0, 100]. It should only be called after [Ready]
	// returns true.
	ObservedUptime() uint8

	// Send attempts to send [msg] to the peer. The peer takes ownership of
	// [msg] for reference counting. This returns false if the message is
	// guaranteed not to be delivered to the peer.
	Send(ctx context.Context, msg message.OutboundMessage) bool

	// StartClose will begin shutting down the peer. It will not block.
	StartClose()

	// Closed returns true once the peer has been fully shutdown. It is
	// guaranteed that no more messages will be received by this peer once this
	// returns true.
	Closed() bool

	// AwaitClosed will block until the peer has been fully shutdown. If the
	// context is cancelled, then an error will be returned.
	AwaitClosed(ctx context.Context) error
}

Peer encapsulates all of the functionality required to send and receive messages with a remote peer.

func Start

func Start(
	config *Config,
	conn net.Conn,
	cert *x509.Certificate,
	id ids.NodeID,
	messageQueue MessageQueue,
) Peer

Start a new peer instance.

Invariant: There must only be one peer running at a time with a reference to the same [config.InboundMsgThrottler].

func StartTestPeer

func StartTestPeer(
	ctx context.Context,
	ip ips.IPPort,
	networkID uint32,
	router router.InboundHandler,
) (Peer, error)

StartTestPeer provides a simple interface to create a peer that has finished the p2p handshake.

This function will generate a new TLS key to use when connecting to the peer.

The returned peer will not throttle inbound or outbound messages.

  • [ctx] provides a way of canceling the connection request.
  • [ip] is the remote that will be dialed to create the connection.
  • [networkID] will be sent to the peer during the handshake. If the peer is expecting a different [networkID], the handshake will fail and an error will be returned.
  • router will be called with all non-handshake messages received by the peer.
Example
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, 15*time.Second)
defer cancel()

peerIP := ips.IPPort{
	IP:   net.IPv6loopback,
	Port: 9651,
}
peer, err := StartTestPeer(
	ctx,
	peerIP,
	constants.LocalID,
	router.InboundHandlerFunc(func(msg message.InboundMessage) {
		fmt.Printf("handling %s\n", msg.Op())
	}),
)
if err != nil {
	panic(err)
}

// Send messages here with [peer.Send].

peer.StartClose()
err = peer.AwaitClosed(ctx)
if err != nil {
	panic(err)
}
Output:

type SendFailedCallback

type SendFailedCallback interface {
	SendFailed(message.OutboundMessage)
}

type SendFailedFunc

type SendFailedFunc func(message.OutboundMessage)

func (SendFailedFunc) SendFailed

func (f SendFailedFunc) SendFailed(msg message.OutboundMessage)

type Set

type Set interface {
	// Add this peer to the set.
	//
	// If a peer with the same [peer.ID] is already in the set, then the new
	// peer instance will replace the old peer instance.
	//
	// Add does not change the [peer.ID] returned from calls to [GetByIndex].
	Add(peer Peer)

	// GetByID attempts to fetch a [peer] whose [peer.ID] is equal to [nodeID].
	// If no such peer exists in the set, then [false] will be returned.
	GetByID(nodeID ids.NodeID) (Peer, bool)

	// GetByIndex attempts to fetch a peer who has been allocated [index]. If
	// [index] < 0 or [index] >= [Len], then false will be returned.
	GetByIndex(index int) (Peer, bool)

	// Remove any [peer] whose [peer.ID] is equal to [nodeID] from the set.
	Remove(nodeID ids.NodeID)

	// Len returns the number of peers currently in this set.
	Len() int

	// Sample attempts to return a random slice of peers with length [n]. The
	// slice will not inclide any duplicates. Only peers that cause the
	// [precondition] to return true will be returned in the slice.
	Sample(n int, precondition func(Peer) bool) []Peer

	// Returns information about all the peers.
	AllInfo() []Info

	// Info returns information about the requested peers if they are in the
	// set.
	Info(nodeIDs []ids.NodeID) []Info
}

Set contains a group of peers.

func NewSet

func NewSet() Set

NewSet returns a set that does not internally manage synchronization.

Only [Add] and [Remove] require exclusion on the data structure. The remaining methods are safe for concurrent use.

type SignedIP

type SignedIP struct {
	IP        UnsignedIP
	Signature []byte
}

SignedIP is a wrapper of an UnsignedIP with the signature from a signer.

func (*SignedIP) Verify

func (ip *SignedIP) Verify(cert *x509.Certificate) error

type UnsignedIP

type UnsignedIP struct {
	IP        ips.IPPort
	Timestamp uint64
}

UnsignedIP is used for a validator to claim an IP. The [Timestamp] is used to ensure that the most updated IP claim is tracked by peers for a given validator.

func (*UnsignedIP) Sign

func (ip *UnsignedIP) Sign(signer crypto.Signer) (*SignedIP, error)

Sign this IP with the provided signer and return the signed IP.

type Upgrader

type Upgrader interface {
	// Must be thread safe
	Upgrade(net.Conn) (ids.NodeID, net.Conn, *x509.Certificate, error)
}

func NewTLSClientUpgrader

func NewTLSClientUpgrader(config *tls.Config) Upgrader

func NewTLSServerUpgrader

func NewTLSServerUpgrader(config *tls.Config) Upgrader

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL