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.

234 lines
7.0 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-wire/data"
  6. cmn "github.com/tendermint/tmlibs/common"
  7. "github.com/tendermint/tmlibs/events"
  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 cmn.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. var (
  31. EventDataNameNewBlock = "new_block"
  32. EventDataNameNewBlockHeader = "new_block_header"
  33. EventDataNameTx = "tx"
  34. EventDataNameRoundState = "round_state"
  35. EventDataNameVote = "vote"
  36. )
  37. //----------------------------------------
  38. // implements events.EventData
  39. type TMEventDataInner interface {
  40. events.EventData
  41. }
  42. type TMEventData struct {
  43. TMEventDataInner `json:"unwrap"`
  44. }
  45. func (tmr TMEventData) MarshalJSON() ([]byte, error) {
  46. return tmEventDataMapper.ToJSON(tmr.TMEventDataInner)
  47. }
  48. func (tmr *TMEventData) UnmarshalJSON(data []byte) (err error) {
  49. parsed, err := tmEventDataMapper.FromJSON(data)
  50. if err == nil && parsed != nil {
  51. tmr.TMEventDataInner = parsed.(TMEventDataInner)
  52. }
  53. return
  54. }
  55. func (tmr TMEventData) Unwrap() TMEventDataInner {
  56. tmrI := tmr.TMEventDataInner
  57. for wrap, ok := tmrI.(TMEventData); ok; wrap, ok = tmrI.(TMEventData) {
  58. tmrI = wrap.TMEventDataInner
  59. }
  60. return tmrI
  61. }
  62. func (tmr TMEventData) Empty() bool {
  63. return tmr.TMEventDataInner == nil
  64. }
  65. const (
  66. EventDataTypeNewBlock = byte(0x01)
  67. EventDataTypeFork = byte(0x02)
  68. EventDataTypeTx = byte(0x03)
  69. EventDataTypeNewBlockHeader = byte(0x04)
  70. EventDataTypeRoundState = byte(0x11)
  71. EventDataTypeVote = byte(0x12)
  72. )
  73. var tmEventDataMapper = data.NewMapper(TMEventData{}).
  74. RegisterImplementation(EventDataNewBlock{}, EventDataNameNewBlock, EventDataTypeNewBlock).
  75. RegisterImplementation(EventDataNewBlockHeader{}, EventDataNameNewBlockHeader, EventDataTypeNewBlockHeader).
  76. RegisterImplementation(EventDataTx{}, EventDataNameTx, EventDataTypeTx).
  77. RegisterImplementation(EventDataRoundState{}, EventDataNameRoundState, EventDataTypeRoundState).
  78. RegisterImplementation(EventDataVote{}, EventDataNameVote, EventDataTypeVote)
  79. // Most event messages are basic types (a block, a transaction)
  80. // but some (an input to a call tx or a receive) are more exotic
  81. type EventDataNewBlock struct {
  82. Block *Block `json:"block"`
  83. }
  84. // light weight event for benchmarking
  85. type EventDataNewBlockHeader struct {
  86. Header *Header `json:"header"`
  87. }
  88. // All txs fire EventDataTx
  89. type EventDataTx struct {
  90. Height int `json:"height"`
  91. Tx Tx `json:"tx"`
  92. Data data.Bytes `json:"data"`
  93. Log string `json:"log"`
  94. Code abci.CodeType `json:"code"`
  95. Error string `json:"error"` // this is redundant information for now
  96. }
  97. // NOTE: This goes into the replay WAL
  98. type EventDataRoundState struct {
  99. Height int `json:"height"`
  100. Round int `json:"round"`
  101. Step string `json:"step"`
  102. // private, not exposed to websockets
  103. RoundState interface{} `json:"-"`
  104. }
  105. type EventDataVote struct {
  106. Vote *Vote
  107. }
  108. func (_ EventDataNewBlock) AssertIsTMEventData() {}
  109. func (_ EventDataNewBlockHeader) AssertIsTMEventData() {}
  110. func (_ EventDataTx) AssertIsTMEventData() {}
  111. func (_ EventDataRoundState) AssertIsTMEventData() {}
  112. func (_ EventDataVote) AssertIsTMEventData() {}
  113. //----------------------------------------
  114. // Wrappers for type safety
  115. type Fireable interface {
  116. events.Fireable
  117. }
  118. type Eventable interface {
  119. SetEventSwitch(EventSwitch)
  120. }
  121. type EventSwitch interface {
  122. events.EventSwitch
  123. }
  124. type EventCache interface {
  125. Fireable
  126. Flush()
  127. }
  128. func NewEventSwitch() EventSwitch {
  129. return events.NewEventSwitch()
  130. }
  131. func NewEventCache(evsw EventSwitch) EventCache {
  132. return events.NewEventCache(evsw)
  133. }
  134. // All events should be based on this FireEvent to ensure they are TMEventData
  135. func fireEvent(fireable events.Fireable, event string, data TMEventData) {
  136. if fireable != nil {
  137. fireable.FireEvent(event, data)
  138. }
  139. }
  140. func AddListenerForEvent(evsw EventSwitch, id, event string, cb func(data TMEventData)) {
  141. evsw.AddListenerForEvent(id, event, func(data events.EventData) {
  142. cb(data.(TMEventData))
  143. })
  144. }
  145. //--- block, tx, and vote events
  146. func FireEventNewBlock(fireable events.Fireable, block EventDataNewBlock) {
  147. fireEvent(fireable, EventStringNewBlock(), TMEventData{block})
  148. }
  149. func FireEventNewBlockHeader(fireable events.Fireable, header EventDataNewBlockHeader) {
  150. fireEvent(fireable, EventStringNewBlockHeader(), TMEventData{header})
  151. }
  152. func FireEventVote(fireable events.Fireable, vote EventDataVote) {
  153. fireEvent(fireable, EventStringVote(), TMEventData{vote})
  154. }
  155. func FireEventTx(fireable events.Fireable, tx EventDataTx) {
  156. fireEvent(fireable, EventStringTx(tx.Tx), TMEventData{tx})
  157. }
  158. //--- EventDataRoundState events
  159. func FireEventNewRoundStep(fireable events.Fireable, rs EventDataRoundState) {
  160. fireEvent(fireable, EventStringNewRoundStep(), TMEventData{rs})
  161. }
  162. func FireEventTimeoutPropose(fireable events.Fireable, rs EventDataRoundState) {
  163. fireEvent(fireable, EventStringTimeoutPropose(), TMEventData{rs})
  164. }
  165. func FireEventTimeoutWait(fireable events.Fireable, rs EventDataRoundState) {
  166. fireEvent(fireable, EventStringTimeoutWait(), TMEventData{rs})
  167. }
  168. func FireEventNewRound(fireable events.Fireable, rs EventDataRoundState) {
  169. fireEvent(fireable, EventStringNewRound(), TMEventData{rs})
  170. }
  171. func FireEventCompleteProposal(fireable events.Fireable, rs EventDataRoundState) {
  172. fireEvent(fireable, EventStringCompleteProposal(), TMEventData{rs})
  173. }
  174. func FireEventPolka(fireable events.Fireable, rs EventDataRoundState) {
  175. fireEvent(fireable, EventStringPolka(), TMEventData{rs})
  176. }
  177. func FireEventUnlock(fireable events.Fireable, rs EventDataRoundState) {
  178. fireEvent(fireable, EventStringUnlock(), TMEventData{rs})
  179. }
  180. func FireEventRelock(fireable events.Fireable, rs EventDataRoundState) {
  181. fireEvent(fireable, EventStringRelock(), TMEventData{rs})
  182. }
  183. func FireEventLock(fireable events.Fireable, rs EventDataRoundState) {
  184. fireEvent(fireable, EventStringLock(), TMEventData{rs})
  185. }