* lint docs with write-good, stop-words * remove package-lock.json * update changelog * fix wrong paragraph formatting * fix some docs formatting * fix docs format * fix abci spec format
3.2 KiB
ADR 012: PeerTransport
Context
One of the more apparent problems with the current architecture in the p2p
package is that there is no clear separation of concerns between different
components. Most notably the Switch
is currently doing physical connection
handling. An artifact is the dependency of the Switch on
[config.P2PConfig
](05a76fb517/config/config.go (L272-L339)
).
Addresses:
First iteraton in #2067
Decision
Transport concerns will be handled by a new component (PeerTransport
) which
will provide Peers at its boundary to the caller. In turn Switch
will use
this new component accept new Peer
s and dial them based on NetAddress
.
PeerTransport
Responsible for emitting and connecting to Peers. The implementation of Peer
is left to the transport, which implies that the chosen transport dictates the
characteristics of the implementation handed back to the Switch
. Each
transport implementation is responsible to filter establishing peers specific
to its domain, for the default multiplexed implementation the following will
apply:
- connections from our own node
- handshake fails
- upgrade to secret connection fails
- prevent duplicate ip
- prevent duplicate id
- nodeinfo incompatibility
// PeerTransport proxies incoming and outgoing peer connections.
type PeerTransport interface {
// Accept returns a newly connected Peer.
Accept() (Peer, error)
// Dial connects to a Peer.
Dial(NetAddress) (Peer, error)
}
// EXAMPLE OF DEFAULT IMPLEMENTATION
// multiplexTransport accepts tcp connections and upgrades to multiplexted
// peers.
type multiplexTransport struct {
listener net.Listener
acceptc chan accept
closec <-chan struct{}
listenc <-chan struct{}
dialTimeout time.Duration
handshakeTimeout time.Duration
nodeAddr NetAddress
nodeInfo NodeInfo
nodeKey NodeKey
// TODO(xla): Remove when MConnection is refactored into mPeer.
mConfig conn.MConnConfig
}
var _ PeerTransport = (*multiplexTransport)(nil)
// NewMTransport returns network connected multiplexed peers.
func NewMTransport(
nodeAddr NetAddress,
nodeInfo NodeInfo,
nodeKey NodeKey,
) *multiplexTransport
Switch
From now the Switch will depend on a fully setup PeerTransport
to
retrieve/reach out to its peers. As the more low-level concerns are pushed to
the transport, we can omit passing the config.P2PConfig
to the Switch.
func NewSwitch(transport PeerTransport, opts ...SwitchOption) *Switch
Status
In Review.
Consequences
Positive
- free Switch from transport concerns - simpler implementation
- pluggable transport implementation - simpler test setup
- remove Switch dependency on P2PConfig - easier to test
Negative
- more setup for tests which depend on Switches
Neutral
- multiplexed will be the default implementation
[0] These guards could be potentially extended to be pluggable much like middlewares to express different concerns required by differentally configured environments.