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.

115 lines
3.2 KiB

  1. package p2p
  2. import (
  3. "sort"
  4. "github.com/gogo/protobuf/proto"
  5. "github.com/tendermint/tendermint/config"
  6. "github.com/tendermint/tendermint/internal/p2p/conn"
  7. "github.com/tendermint/tendermint/libs/log"
  8. )
  9. // ChannelDescriptorShim defines a shim wrapper around a legacy p2p channel
  10. // and the proto.Message the new p2p Channel is responsible for handling.
  11. // A ChannelDescriptorShim is not contained in ReactorShim, but is rather
  12. // used to construct a ReactorShim.
  13. type ChannelDescriptorShim struct {
  14. MsgType proto.Message
  15. Descriptor *ChannelDescriptor
  16. }
  17. // ChannelShim defines a generic shim wrapper around a legacy p2p channel
  18. // and the new p2p Channel. It also includes the raw bi-directional Go channels
  19. // so we can proxy message delivery.
  20. type ChannelShim struct {
  21. Descriptor *ChannelDescriptor
  22. Channel *Channel
  23. inCh chan<- Envelope
  24. outCh <-chan Envelope
  25. errCh <-chan PeerError
  26. }
  27. // ReactorShim defines a generic shim wrapper around a BaseReactor. It is
  28. // responsible for wiring up legacy p2p behavior to the new p2p semantics
  29. // (e.g. proxying Envelope messages to legacy peers).
  30. type ReactorShim struct {
  31. Name string
  32. PeerUpdates *PeerUpdates
  33. Channels map[ChannelID]*ChannelShim
  34. }
  35. func NewReactorShim(logger log.Logger, name string, descriptors map[ChannelID]*ChannelDescriptorShim) *ReactorShim {
  36. channels := make(map[ChannelID]*ChannelShim)
  37. for _, cds := range descriptors {
  38. chShim := NewChannelShim(cds, 0)
  39. channels[chShim.Channel.ID] = chShim
  40. }
  41. rs := &ReactorShim{
  42. Name: name,
  43. PeerUpdates: NewPeerUpdates(make(chan PeerUpdate), 0),
  44. Channels: channels,
  45. }
  46. return rs
  47. }
  48. func NewChannelShim(cds *ChannelDescriptorShim, buf uint) *ChannelShim {
  49. inCh := make(chan Envelope, buf)
  50. outCh := make(chan Envelope, buf)
  51. errCh := make(chan PeerError, buf)
  52. return &ChannelShim{
  53. Descriptor: cds.Descriptor,
  54. Channel: NewChannel(
  55. ChannelID(cds.Descriptor.ID),
  56. cds.MsgType,
  57. inCh,
  58. outCh,
  59. errCh,
  60. ),
  61. inCh: inCh,
  62. outCh: outCh,
  63. errCh: errCh,
  64. }
  65. }
  66. // MConnConfig returns an MConnConfig based on the defaults, with fields updated
  67. // from the P2PConfig.
  68. func MConnConfig(cfg *config.P2PConfig) conn.MConnConfig {
  69. mConfig := conn.DefaultMConnConfig()
  70. mConfig.FlushThrottle = cfg.FlushThrottleTimeout
  71. mConfig.SendRate = cfg.SendRate
  72. mConfig.RecvRate = cfg.RecvRate
  73. mConfig.MaxPacketMsgPayloadSize = cfg.MaxPacketMsgPayloadSize
  74. return mConfig
  75. }
  76. // GetChannels implements the legacy Reactor interface for getting a slice of all
  77. // the supported ChannelDescriptors.
  78. func (rs *ReactorShim) GetChannels() []*ChannelDescriptor {
  79. sortedChIDs := make([]ChannelID, 0, len(rs.Channels))
  80. for cID := range rs.Channels {
  81. sortedChIDs = append(sortedChIDs, cID)
  82. }
  83. sort.Slice(sortedChIDs, func(i, j int) bool { return sortedChIDs[i] < sortedChIDs[j] })
  84. descriptors := make([]*ChannelDescriptor, len(rs.Channels))
  85. for i, cID := range sortedChIDs {
  86. descriptors[i] = rs.Channels[cID].Descriptor
  87. }
  88. return descriptors
  89. }
  90. // GetChannel returns a p2p Channel reference for a given ChannelID. If no
  91. // Channel exists, nil is returned.
  92. func (rs *ReactorShim) GetChannel(cID ChannelID) *Channel {
  93. channelShim, ok := rs.Channels[cID]
  94. if ok {
  95. return channelShim.Channel
  96. }
  97. return nil
  98. }