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.

230 lines
7.3 KiB

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