mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-09 05:22:13 +00:00
* 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
114 lines
3.2 KiB
Markdown
114 lines
3.2 KiB
Markdown
# 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`](https://github.com/tendermint/tendermint/blob/05a76fb517f50da27b4bfcdc7b4cf185fc61eff6/config/config.go#L272-L339).
|
|
|
|
Addresses:
|
|
|
|
- [#2046](https://github.com/tendermint/tendermint/issues/2046)
|
|
- [#2047](https://github.com/tendermint/tendermint/issues/2047)
|
|
|
|
First iteraton in [#2067](https://github.com/tendermint/tendermint/issues/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
|
|
|
|
```go
|
|
// 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.
|
|
|
|
```go
|
|
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.
|