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.