pex

package
v0.35.4 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2022 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package PEX (Peer exchange) handles all the logic necessary for nodes to share information about their peers to other nodes. Specifically, this is the exchange of addresses that a peer can use to discover more peers within the network.

The PEX reactor is a continuous service which periodically requests addresses and serves addresses to other peers. There are two versions of this service aligning with the two p2p frameworks that Tendermint currently supports.

V1 is coupled with the Switch (which handles peer connections and routing of messages) and, alongside exchanging peer information in the form of port/IP pairs, also has the responsibility of dialing peers and ensuring that a node has a sufficient amount of peers connected.

V2 is embedded with the new p2p stack and uses the peer manager to advertise peers as well as add new peers to the peer store. The V2 reactor passes a different set of proto messages which include a list of [urls](https://golang.org/pkg/net/url/#URL).These can be used to save a set of endpoints that each peer uses. The V2 reactor has backwards compatibility with V1. It can also handle V1 messages.

The V2 reactor is able to tweak the intensity of it's search by decreasing or increasing the interval between each request. It tracks connected peers via a linked list, sending a request to the node at the front of the list and adding it to the back of the list once a response is received. Using this method, a node is able to spread out the load of requesting peers across all the peers it is currently connected with.

With each inbound set of addresses, the reactor monitors the amount of new addresses to already seen addresses and uses the information to dynamically build a picture of the size of the network in order to ascertain how often the node needs to search for new peers.

Index

Constants

View Source
const (
	// PexChannel is a channel for PEX messages
	PexChannel = byte(0x00)
)

Variables

View Source
var ErrUnsolicitedList = errors.New("unsolicited pexAddrsMessage")

ErrUnsolicitedList is thrown when a peer provides a list of addresses that have not been asked for.

Functions

func ChannelDescriptor

func ChannelDescriptor() conn.ChannelDescriptor

TODO: We should decide whether we want channel descriptors to be housed within each reactor (as they are now) or, considering that the reactor doesn't really need to care about the channel descriptors, if they should be housed in the node module.

func NetAddressFromProto

func NetAddressFromProto(pb tmp2p.PexAddress) (*types.NetAddress, error)

NetAddressFromProto converts a Protobuf PexAddress into a native struct.

func NetAddressesFromProto

func NetAddressesFromProto(pbs []tmp2p.PexAddress) ([]*types.NetAddress, error)

NetAddressesFromProto converts a slice of Protobuf PexAddresses into a native slice.

func NetAddressesToProto

func NetAddressesToProto(nas []*types.NetAddress) []tmp2p.PexAddress

NetAddressesToProto converts a slice of NetAddresses into a Protobuf PexAddress slice.

Types

type AddrBook

type AddrBook interface {
	service.Service

	// Add our own addresses so we don't later add ourselves
	AddOurAddress(*p2p.NetAddress)
	// Check if it is our address
	OurAddress(*p2p.NetAddress) bool

	AddPrivateIDs([]string)

	// Add and remove an address
	AddAddress(addr *p2p.NetAddress, src *p2p.NetAddress) error
	RemoveAddress(*p2p.NetAddress)

	// Check if the address is in the book
	HasAddress(*p2p.NetAddress) bool

	// Do we need more peers?
	NeedMoreAddrs() bool
	// Is Address Book Empty? Answer should not depend on being in your own
	// address book, or private peers
	Empty() bool

	// Pick an address to dial
	PickAddress(biasTowardsNewAddrs int) *p2p.NetAddress

	// Mark address
	MarkGood(types.NodeID)
	MarkAttempt(*p2p.NetAddress)
	MarkBad(*p2p.NetAddress, time.Duration) // Move peer to bad peers list
	// Add bad peers back to addrBook
	ReinstateBadPeers()

	IsGood(*p2p.NetAddress) bool
	IsBanned(*p2p.NetAddress) bool

	// Send a selection of addresses to peers
	GetSelection() []*p2p.NetAddress
	// Send a selection of addresses with bias
	GetSelectionWithBias(biasTowardsNewAddrs int) []*p2p.NetAddress

	Size() int

	// Persist to disk
	Save()
}

AddrBook is an address book used for tracking peers so we can gossip about them to others and select peers to dial. TODO: break this up?

func NewAddrBook

func NewAddrBook(filePath string, routabilityStrict bool) AddrBook

NewAddrBook creates a new address book. Use Start to begin processing asynchronous address updates.

type ErrAddrBookInvalidAddr

type ErrAddrBookInvalidAddr struct {
	Addr    *p2p.NetAddress
	AddrErr error
}

func (ErrAddrBookInvalidAddr) Error

func (err ErrAddrBookInvalidAddr) Error() string

type ErrAddrBookNilAddr

type ErrAddrBookNilAddr struct {
	Addr *p2p.NetAddress
	Src  *p2p.NetAddress
}

func (ErrAddrBookNilAddr) Error

func (err ErrAddrBookNilAddr) Error() string

type ErrAddrBookNonRoutable

type ErrAddrBookNonRoutable struct {
	Addr *p2p.NetAddress
}

func (ErrAddrBookNonRoutable) Error

func (err ErrAddrBookNonRoutable) Error() string

type ErrAddrBookPrivate

type ErrAddrBookPrivate struct {
	Addr *p2p.NetAddress
}

func (ErrAddrBookPrivate) Error

func (err ErrAddrBookPrivate) Error() string

func (ErrAddrBookPrivate) PrivateAddr

func (err ErrAddrBookPrivate) PrivateAddr() bool

type ErrAddrBookPrivateSrc

type ErrAddrBookPrivateSrc struct {
	Src *p2p.NetAddress
}

func (ErrAddrBookPrivateSrc) Error

func (err ErrAddrBookPrivateSrc) Error() string

func (ErrAddrBookPrivateSrc) PrivateAddr

func (err ErrAddrBookPrivateSrc) PrivateAddr() bool

type ErrAddrBookSelf

type ErrAddrBookSelf struct {
	Addr *p2p.NetAddress
}

func (ErrAddrBookSelf) Error

func (err ErrAddrBookSelf) Error() string

type ErrAddressBanned

type ErrAddressBanned struct {
	Addr *p2p.NetAddress
}

ErrAddressBanned is thrown when the address has been banned and therefore cannot be used

func (ErrAddressBanned) Error

func (err ErrAddressBanned) Error() string

type Peer

type Peer = p2p.Peer

type Reactor

type Reactor struct {
	p2p.BaseReactor
	// contains filtered or unexported fields
}

Reactor handles PEX (peer exchange) and ensures that an adequate number of peers are connected to the switch.

It uses `AddrBook` (address book) to store `NetAddress`es of the peers.

## Preventing abuse

Only accept pexAddrsMsg from peers we sent a corresponding pexRequestMsg too. Only accept one pexRequestMsg every ~defaultEnsurePeersPeriod.

func NewReactor

func NewReactor(b AddrBook, config *ReactorConfig) *Reactor

NewReactor creates new PEX reactor.

func (*Reactor) AddPeer

func (r *Reactor) AddPeer(p Peer)

AddPeer implements Reactor by adding peer to the address book (if inbound) or by requesting more addresses (if outbound).

func (*Reactor) AttemptsToDial

func (r *Reactor) AttemptsToDial(addr *p2p.NetAddress) int

AttemptsToDial returns the number of attempts to dial specific address. It returns 0 if never attempted or successfully connected.

func (*Reactor) GetChannels

func (r *Reactor) GetChannels() []*conn.ChannelDescriptor

GetChannels implements Reactor

func (*Reactor) OnStart

func (r *Reactor) OnStart() error

OnStart implements BaseService

func (*Reactor) OnStop

func (r *Reactor) OnStop()

OnStop implements BaseService

func (*Reactor) Receive

func (r *Reactor) Receive(chID byte, src Peer, msgBytes []byte)

Receive implements Reactor by handling incoming PEX messages. XXX: do not call any methods that can block or incur heavy processing. https://github.com/tendermint/tendermint/issues/2888

func (*Reactor) ReceiveAddrs

func (r *Reactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error

ReceiveAddrs adds the given addrs to the addrbook if theres an open request for this peer and deletes the open request. If there's no open request for the src peer, it returns an error.

func (*Reactor) RemovePeer

func (r *Reactor) RemovePeer(p Peer, reason interface{})

RemovePeer implements Reactor by resetting peer's requests info.

func (*Reactor) RequestAddrs

func (r *Reactor) RequestAddrs(p Peer)

RequestAddrs asks peer for more addresses if we do not already have a request out for this peer.

func (*Reactor) SendAddrs

func (r *Reactor) SendAddrs(p Peer, netAddrs []*p2p.NetAddress)

SendAddrs sends addrs to the peer.

func (*Reactor) SetEnsurePeersPeriod

func (r *Reactor) SetEnsurePeersPeriod(d time.Duration)

SetEnsurePeersPeriod sets period to ensure peers connected.

type ReactorConfig

type ReactorConfig struct {
	// Seed/Crawler mode
	SeedMode bool

	// We want seeds to only advertise good peers. Therefore they should wait at
	// least as long as we expect it to take for a peer to become good before
	// disconnecting.
	SeedDisconnectWaitPeriod time.Duration

	// Maximum pause when redialing a persistent peer (if zero, exponential backoff is used)
	PersistentPeersMaxDialPeriod time.Duration

	// Seeds is a list of addresses reactor may use
	// if it can't connect to peers in the addrbook.
	Seeds []string
}

ReactorConfig holds reactor specific configuration data.

type ReactorV2

type ReactorV2 struct {
	service.BaseService
	// contains filtered or unexported fields
}

ReactorV2 is a PEX reactor for the new P2P stack. The legacy reactor is Reactor.

FIXME: Rename this when Reactor is removed, and consider moving to p2p/.

The peer exchange or PEX reactor supports the peer manager by sending requests to other peers for addresses that can be given to the peer manager and at the same time advertises addresses to peers that need more.

The reactor is able to tweak the intensity of it's search by decreasing or increasing the interval between each request. It tracks connected peers via a linked list, sending a request to the node at the front of the list and adding it to the back of the list once a response is received.

func NewReactorV2

func NewReactorV2(
	logger log.Logger,
	peerManager *p2p.PeerManager,
	pexCh *p2p.Channel,
	peerUpdates *p2p.PeerUpdates,
) *ReactorV2

NewReactor returns a reference to a new reactor.

func (*ReactorV2) OnStart

func (r *ReactorV2) OnStart() error

OnStart starts separate go routines for each p2p Channel and listens for envelopes on each. In addition, it also listens for peer updates and handles messages on that p2p channel accordingly. The caller must be sure to execute OnStop to ensure the outbound p2p Channels are closed.

func (*ReactorV2) OnStop

func (r *ReactorV2) OnStop()

OnStop stops the reactor by signaling to all spawned goroutines to exit and blocking until they all exit.

Jump to

Keyboard shortcuts

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