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.

102 lines
2.7 KiB

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