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.

200 lines
5.9 KiB

  1. package types
  2. import (
  3. // for registering TMEventData as events.EventData
  4. abci "github.com/tendermint/abci/types"
  5. . "github.com/tendermint/go-common"
  6. "github.com/tendermint/go-events"
  7. "github.com/tendermint/go-wire"
  8. )
  9. // Functions to generate eventId strings
  10. // Reserved
  11. func EventStringBond() string { return "Bond" }
  12. func EventStringUnbond() string { return "Unbond" }
  13. func EventStringRebond() string { return "Rebond" }
  14. func EventStringDupeout() string { return "Dupeout" }
  15. func EventStringFork() string { return "Fork" }
  16. func EventStringTx(tx Tx) string { return Fmt("Tx:%X", tx.Hash()) }
  17. func EventStringNewBlock() string { return "NewBlock" }
  18. func EventStringNewBlockHeader() string { return "NewBlockHeader" }
  19. func EventStringNewRound() string { return "NewRound" }
  20. func EventStringNewRoundStep() string { return "NewRoundStep" }
  21. func EventStringTimeoutPropose() string { return "TimeoutPropose" }
  22. func EventStringCompleteProposal() string { return "CompleteProposal" }
  23. func EventStringPolka() string { return "Polka" }
  24. func EventStringUnlock() string { return "Unlock" }
  25. func EventStringLock() string { return "Lock" }
  26. func EventStringRelock() string { return "Relock" }
  27. func EventStringTimeoutWait() string { return "TimeoutWait" }
  28. func EventStringVote() string { return "Vote" }
  29. //----------------------------------------
  30. // implements events.EventData
  31. type TMEventData interface {
  32. events.EventData
  33. AssertIsTMEventData()
  34. }
  35. const (
  36. EventDataTypeNewBlock = byte(0x01)
  37. EventDataTypeFork = byte(0x02)
  38. EventDataTypeTx = byte(0x03)
  39. EventDataTypeNewBlockHeader = byte(0x04)
  40. EventDataTypeRoundState = byte(0x11)
  41. EventDataTypeVote = byte(0x12)
  42. )
  43. var _ = wire.RegisterInterface(
  44. struct{ TMEventData }{},
  45. wire.ConcreteType{EventDataNewBlock{}, EventDataTypeNewBlock},
  46. wire.ConcreteType{EventDataNewBlockHeader{}, EventDataTypeNewBlockHeader},
  47. // wire.ConcreteType{EventDataFork{}, EventDataTypeFork },
  48. wire.ConcreteType{EventDataTx{}, EventDataTypeTx},
  49. wire.ConcreteType{EventDataRoundState{}, EventDataTypeRoundState},
  50. wire.ConcreteType{EventDataVote{}, EventDataTypeVote},
  51. )
  52. // Most event messages are basic types (a block, a transaction)
  53. // but some (an input to a call tx or a receive) are more exotic
  54. type EventDataNewBlock struct {
  55. Block *Block `json:"block"`
  56. }
  57. // light weight event for benchmarking
  58. type EventDataNewBlockHeader struct {
  59. Header *Header `json:"header"`
  60. }
  61. // All txs fire EventDataTx
  62. type EventDataTx struct {
  63. Height int `json:"height"`
  64. Tx Tx `json:"tx"`
  65. Data []byte `json:"data"`
  66. Log string `json:"log"`
  67. Code abci.CodeType `json:"code"`
  68. Error string `json:"error"` // this is redundant information for now
  69. }
  70. // NOTE: This goes into the replay WAL
  71. type EventDataRoundState struct {
  72. Height int `json:"height"`
  73. Round int `json:"round"`
  74. Step string `json:"step"`
  75. // private, not exposed to websockets
  76. RoundState interface{} `json:"-"`
  77. }
  78. type EventDataVote struct {
  79. Vote *Vote
  80. }
  81. func (_ EventDataNewBlock) AssertIsTMEventData() {}
  82. func (_ EventDataNewBlockHeader) AssertIsTMEventData() {}
  83. func (_ EventDataTx) AssertIsTMEventData() {}
  84. func (_ EventDataRoundState) AssertIsTMEventData() {}
  85. func (_ EventDataVote) AssertIsTMEventData() {}
  86. //----------------------------------------
  87. // Wrappers for type safety
  88. type Fireable interface {
  89. events.Fireable
  90. }
  91. type Eventable interface {
  92. SetEventSwitch(EventSwitch)
  93. }
  94. type EventSwitch interface {
  95. events.EventSwitch
  96. }
  97. type EventCache interface {
  98. Fireable
  99. Flush()
  100. }
  101. func NewEventSwitch() EventSwitch {
  102. return events.NewEventSwitch()
  103. }
  104. func NewEventCache(evsw EventSwitch) EventCache {
  105. return events.NewEventCache(evsw)
  106. }
  107. // All events should be based on this FireEvent to ensure they are TMEventData
  108. func fireEvent(fireable events.Fireable, event string, data TMEventData) {
  109. if fireable != nil {
  110. fireable.FireEvent(event, data)
  111. }
  112. }
  113. func AddListenerForEvent(evsw EventSwitch, id, event string, cb func(data TMEventData)) {
  114. evsw.AddListenerForEvent(id, event, func(data events.EventData) {
  115. cb(data.(TMEventData))
  116. })
  117. }
  118. //--- block, tx, and vote events
  119. func FireEventNewBlock(fireable events.Fireable, block EventDataNewBlock) {
  120. fireEvent(fireable, EventStringNewBlock(), block)
  121. }
  122. func FireEventNewBlockHeader(fireable events.Fireable, header EventDataNewBlockHeader) {
  123. fireEvent(fireable, EventStringNewBlockHeader(), header)
  124. }
  125. func FireEventVote(fireable events.Fireable, vote EventDataVote) {
  126. fireEvent(fireable, EventStringVote(), vote)
  127. }
  128. func FireEventTx(fireable events.Fireable, tx EventDataTx) {
  129. fireEvent(fireable, EventStringTx(tx.Tx), tx)
  130. }
  131. //--- EventDataRoundState events
  132. func FireEventNewRoundStep(fireable events.Fireable, rs EventDataRoundState) {
  133. fireEvent(fireable, EventStringNewRoundStep(), rs)
  134. }
  135. func FireEventTimeoutPropose(fireable events.Fireable, rs EventDataRoundState) {
  136. fireEvent(fireable, EventStringTimeoutPropose(), rs)
  137. }
  138. func FireEventTimeoutWait(fireable events.Fireable, rs EventDataRoundState) {
  139. fireEvent(fireable, EventStringTimeoutWait(), rs)
  140. }
  141. func FireEventNewRound(fireable events.Fireable, rs EventDataRoundState) {
  142. fireEvent(fireable, EventStringNewRound(), rs)
  143. }
  144. func FireEventCompleteProposal(fireable events.Fireable, rs EventDataRoundState) {
  145. fireEvent(fireable, EventStringCompleteProposal(), rs)
  146. }
  147. func FireEventPolka(fireable events.Fireable, rs EventDataRoundState) {
  148. fireEvent(fireable, EventStringPolka(), rs)
  149. }
  150. func FireEventUnlock(fireable events.Fireable, rs EventDataRoundState) {
  151. fireEvent(fireable, EventStringUnlock(), rs)
  152. }
  153. func FireEventRelock(fireable events.Fireable, rs EventDataRoundState) {
  154. fireEvent(fireable, EventStringRelock(), rs)
  155. }
  156. func FireEventLock(fireable events.Fireable, rs EventDataRoundState) {
  157. fireEvent(fireable, EventStringLock(), rs)
  158. }