github.com/badrootd/nibiru-cometbft@v0.37.5-0.20240307173500-2a75559eee9b/docs/architecture/adr-012-peer-transport.md (about) 1 # ADR 012: PeerTransport 2 3 ## Context 4 5 One of the more apparent problems with the current architecture in the p2p 6 package is that there is no clear separation of concerns between different 7 components. Most notably the `Switch` is currently doing physical connection 8 handling. An artifact is the dependency of the Switch on 9 `[config.P2PConfig`](https://github.com/tendermint/tendermint/blob/05a76fb517f50da27b4bfcdc7b4cf185fc61eff6/config/config.go#L272-L339). 10 11 Addresses: 12 13 - [#2046](https://github.com/tendermint/tendermint/issues/2046) 14 - [#2047](https://github.com/tendermint/tendermint/issues/2047) 15 16 First iteraton in [#2067](https://github.com/tendermint/tendermint/issues/2067) 17 18 ## Decision 19 20 Transport concerns will be handled by a new component (`PeerTransport`) which 21 will provide Peers at its boundary to the caller. In turn `Switch` will use 22 this new component accept new `Peer`s and dial them based on `NetAddress`. 23 24 ### PeerTransport 25 26 Responsible for emitting and connecting to Peers. The implementation of `Peer` 27 is left to the transport, which implies that the chosen transport dictates the 28 characteristics of the implementation handed back to the `Switch`. Each 29 transport implementation is responsible to filter establishing peers specific 30 to its domain, for the default multiplexed implementation the following will 31 apply: 32 33 - connections from our own node 34 - handshake fails 35 - upgrade to secret connection fails 36 - prevent duplicate ip 37 - prevent duplicate id 38 - nodeinfo incompatibility 39 40 ```go 41 // PeerTransport proxies incoming and outgoing peer connections. 42 type PeerTransport interface { 43 // Accept returns a newly connected Peer. 44 Accept() (Peer, error) 45 46 // Dial connects to a Peer. 47 Dial(NetAddress) (Peer, error) 48 } 49 50 // EXAMPLE OF DEFAULT IMPLEMENTATION 51 52 // multiplexTransport accepts tcp connections and upgrades to multiplexted 53 // peers. 54 type multiplexTransport struct { 55 listener net.Listener 56 57 acceptc chan accept 58 closec <-chan struct{} 59 listenc <-chan struct{} 60 61 dialTimeout time.Duration 62 handshakeTimeout time.Duration 63 nodeAddr NetAddress 64 nodeInfo NodeInfo 65 nodeKey NodeKey 66 67 // TODO(xla): Remove when MConnection is refactored into mPeer. 68 mConfig conn.MConnConfig 69 } 70 71 var _ PeerTransport = (*multiplexTransport)(nil) 72 73 // NewMTransport returns network connected multiplexed peers. 74 func NewMTransport( 75 nodeAddr NetAddress, 76 nodeInfo NodeInfo, 77 nodeKey NodeKey, 78 ) *multiplexTransport 79 ``` 80 81 ### Switch 82 83 From now the Switch will depend on a fully setup `PeerTransport` to 84 retrieve/reach out to its peers. As the more low-level concerns are pushed to 85 the transport, we can omit passing the `config.P2PConfig` to the Switch. 86 87 ```go 88 func NewSwitch(transport PeerTransport, opts ...SwitchOption) *Switch 89 ``` 90 91 ## Status 92 93 In Review. 94 95 ## Consequences 96 97 ### Positive 98 99 - free Switch from transport concerns - simpler implementation 100 - pluggable transport implementation - simpler test setup 101 - remove Switch dependency on P2PConfig - easier to test 102 103 ### Negative 104 105 - more setup for tests which depend on Switches 106 107 ### Neutral 108 109 - multiplexed will be the default implementation 110 111 [0] These guards could be potentially extended to be pluggable much like 112 middlewares to express different concerns required by differentally configured 113 environments.