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.

227 lines
7.2 KiB

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