You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.2 KiB

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