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.

237 lines
7.5 KiB

  1. package eventbus
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "strings"
  7. abci "github.com/tendermint/tendermint/abci/types"
  8. "github.com/tendermint/tendermint/libs/log"
  9. tmpubsub "github.com/tendermint/tendermint/libs/pubsub"
  10. "github.com/tendermint/tendermint/libs/service"
  11. "github.com/tendermint/tendermint/types"
  12. )
  13. // Subscription is a proxy interface for a pubsub Subscription.
  14. type Subscription interface {
  15. ID() string
  16. Next(context.Context) (tmpubsub.Message, error)
  17. }
  18. // EventBus is a common bus for all events going through the system.
  19. // It is a type-aware wrapper around an underlying pubsub server.
  20. // All events should be published via the bus.
  21. type EventBus struct {
  22. service.BaseService
  23. pubsub *tmpubsub.Server
  24. }
  25. // NewDefault returns a new event bus with default options.
  26. func NewDefault(l log.Logger) *EventBus {
  27. logger := l.With("module", "eventbus")
  28. pubsub := tmpubsub.NewServer(tmpubsub.BufferCapacity(0),
  29. func(s *tmpubsub.Server) {
  30. s.Logger = logger
  31. })
  32. b := &EventBus{pubsub: pubsub}
  33. b.BaseService = *service.NewBaseService(logger, "EventBus", b)
  34. return b
  35. }
  36. func (b *EventBus) OnStart(ctx context.Context) error {
  37. return b.pubsub.Start(ctx)
  38. }
  39. func (b *EventBus) OnStop() {
  40. if err := b.pubsub.Stop(); err != nil {
  41. if !errors.Is(err, service.ErrAlreadyStopped) {
  42. b.pubsub.Logger.Error("error trying to stop eventBus", "error", err)
  43. }
  44. }
  45. }
  46. func (b *EventBus) NumClients() int {
  47. return b.pubsub.NumClients()
  48. }
  49. func (b *EventBus) NumClientSubscriptions(clientID string) int {
  50. return b.pubsub.NumClientSubscriptions(clientID)
  51. }
  52. // Deprecated: Use SubscribeWithArgs instead.
  53. func (b *EventBus) Subscribe(ctx context.Context,
  54. clientID string, query tmpubsub.Query, capacities ...int) (Subscription, error) {
  55. return b.pubsub.Subscribe(ctx, clientID, query, capacities...)
  56. }
  57. func (b *EventBus) SubscribeWithArgs(ctx context.Context, args tmpubsub.SubscribeArgs) (Subscription, error) {
  58. return b.pubsub.SubscribeWithArgs(ctx, args)
  59. }
  60. func (b *EventBus) Unsubscribe(ctx context.Context, args tmpubsub.UnsubscribeArgs) error {
  61. return b.pubsub.Unsubscribe(ctx, args)
  62. }
  63. func (b *EventBus) UnsubscribeAll(ctx context.Context, subscriber string) error {
  64. return b.pubsub.UnsubscribeAll(ctx, subscriber)
  65. }
  66. func (b *EventBus) Observe(ctx context.Context, observe func(tmpubsub.Message) error, queries ...tmpubsub.Query) error {
  67. return b.pubsub.Observe(ctx, observe, queries...)
  68. }
  69. func (b *EventBus) Publish(ctx context.Context, eventValue string, eventData types.TMEventData) error {
  70. tokens := strings.Split(types.EventTypeKey, ".")
  71. event := abci.Event{
  72. Type: tokens[0],
  73. Attributes: []abci.EventAttribute{
  74. {
  75. Key: tokens[1],
  76. Value: eventValue,
  77. },
  78. },
  79. }
  80. return b.pubsub.PublishWithEvents(ctx, eventData, []abci.Event{event})
  81. }
  82. func (b *EventBus) PublishEventNewBlock(ctx context.Context, data types.EventDataNewBlock) error {
  83. events := append(data.ResultBeginBlock.Events, data.ResultEndBlock.Events...)
  84. // add Tendermint-reserved new block event
  85. events = append(events, types.EventNewBlock)
  86. return b.pubsub.PublishWithEvents(ctx, data, events)
  87. }
  88. func (b *EventBus) PublishEventNewBlockHeader(ctx context.Context, data types.EventDataNewBlockHeader) error {
  89. // no explicit deadline for publishing events
  90. events := append(data.ResultBeginBlock.Events, data.ResultEndBlock.Events...)
  91. // add Tendermint-reserved new block header event
  92. events = append(events, types.EventNewBlockHeader)
  93. return b.pubsub.PublishWithEvents(ctx, data, events)
  94. }
  95. func (b *EventBus) PublishEventNewEvidence(ctx context.Context, evidence types.EventDataNewEvidence) error {
  96. return b.Publish(ctx, types.EventNewEvidenceValue, evidence)
  97. }
  98. func (b *EventBus) PublishEventVote(ctx context.Context, data types.EventDataVote) error {
  99. return b.Publish(ctx, types.EventVoteValue, data)
  100. }
  101. func (b *EventBus) PublishEventValidBlock(ctx context.Context, data types.EventDataRoundState) error {
  102. return b.Publish(ctx, types.EventValidBlockValue, data)
  103. }
  104. func (b *EventBus) PublishEventBlockSyncStatus(ctx context.Context, data types.EventDataBlockSyncStatus) error {
  105. return b.Publish(ctx, types.EventBlockSyncStatusValue, data)
  106. }
  107. func (b *EventBus) PublishEventStateSyncStatus(ctx context.Context, data types.EventDataStateSyncStatus) error {
  108. return b.Publish(ctx, types.EventStateSyncStatusValue, data)
  109. }
  110. // PublishEventTx publishes tx event with events from Result. Note it will add
  111. // predefined keys (EventTypeKey, TxHashKey). Existing events with the same keys
  112. // will be overwritten.
  113. func (b *EventBus) PublishEventTx(ctx context.Context, data types.EventDataTx) error {
  114. events := data.Result.Events
  115. // add Tendermint-reserved events
  116. events = append(events, types.EventTx)
  117. tokens := strings.Split(types.TxHashKey, ".")
  118. events = append(events, abci.Event{
  119. Type: tokens[0],
  120. Attributes: []abci.EventAttribute{
  121. {
  122. Key: tokens[1],
  123. Value: fmt.Sprintf("%X", types.Tx(data.Tx).Hash()),
  124. },
  125. },
  126. })
  127. tokens = strings.Split(types.TxHeightKey, ".")
  128. events = append(events, abci.Event{
  129. Type: tokens[0],
  130. Attributes: []abci.EventAttribute{
  131. {
  132. Key: tokens[1],
  133. Value: fmt.Sprintf("%d", data.Height),
  134. },
  135. },
  136. })
  137. return b.pubsub.PublishWithEvents(ctx, data, events)
  138. }
  139. func (b *EventBus) PublishEventNewRoundStep(ctx context.Context, data types.EventDataRoundState) error {
  140. return b.Publish(ctx, types.EventNewRoundStepValue, data)
  141. }
  142. func (b *EventBus) PublishEventTimeoutPropose(ctx context.Context, data types.EventDataRoundState) error {
  143. return b.Publish(ctx, types.EventTimeoutProposeValue, data)
  144. }
  145. func (b *EventBus) PublishEventTimeoutWait(ctx context.Context, data types.EventDataRoundState) error {
  146. return b.Publish(ctx, types.EventTimeoutWaitValue, data)
  147. }
  148. func (b *EventBus) PublishEventNewRound(ctx context.Context, data types.EventDataNewRound) error {
  149. return b.Publish(ctx, types.EventNewRoundValue, data)
  150. }
  151. func (b *EventBus) PublishEventCompleteProposal(ctx context.Context, data types.EventDataCompleteProposal) error {
  152. return b.Publish(ctx, types.EventCompleteProposalValue, data)
  153. }
  154. func (b *EventBus) PublishEventPolka(ctx context.Context, data types.EventDataRoundState) error {
  155. return b.Publish(ctx, types.EventPolkaValue, data)
  156. }
  157. func (b *EventBus) PublishEventUnlock(ctx context.Context, data types.EventDataRoundState) error {
  158. return b.Publish(ctx, types.EventUnlockValue, data)
  159. }
  160. func (b *EventBus) PublishEventRelock(ctx context.Context, data types.EventDataRoundState) error {
  161. return b.Publish(ctx, types.EventRelockValue, data)
  162. }
  163. func (b *EventBus) PublishEventLock(ctx context.Context, data types.EventDataRoundState) error {
  164. return b.Publish(ctx, types.EventLockValue, data)
  165. }
  166. func (b *EventBus) PublishEventValidatorSetUpdates(ctx context.Context, data types.EventDataValidatorSetUpdates) error {
  167. return b.Publish(ctx, types.EventValidatorSetUpdatesValue, data)
  168. }
  169. //-----------------------------------------------------------------------------
  170. // NopEventBus implements a types.BlockEventPublisher that discards all events.
  171. type NopEventBus struct{}
  172. func (NopEventBus) PublishEventNewBlock(context.Context, types.EventDataNewBlock) error {
  173. return nil
  174. }
  175. func (NopEventBus) PublishEventNewBlockHeader(context.Context, types.EventDataNewBlockHeader) error {
  176. return nil
  177. }
  178. func (NopEventBus) PublishEventNewEvidence(context.Context, types.EventDataNewEvidence) error {
  179. return nil
  180. }
  181. func (NopEventBus) PublishEventTx(context.Context, types.EventDataTx) error {
  182. return nil
  183. }
  184. func (NopEventBus) PublishEventValidatorSetUpdates(context.Context, types.EventDataValidatorSetUpdates) error {
  185. return nil
  186. }