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.

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