package types import ( "fmt" "github.com/tendermint/go-amino" tmpubsub "github.com/tendermint/tmlibs/pubsub" tmquery "github.com/tendermint/tmlibs/pubsub/query" ) // Reserved event types const ( EventBond = "Bond" EventCompleteProposal = "CompleteProposal" EventDupeout = "Dupeout" EventFork = "Fork" EventLock = "Lock" EventNewBlock = "NewBlock" EventNewBlockHeader = "NewBlockHeader" EventNewRound = "NewRound" EventNewRoundStep = "NewRoundStep" EventPolka = "Polka" EventRebond = "Rebond" EventRelock = "Relock" EventTimeoutPropose = "TimeoutPropose" EventTimeoutWait = "TimeoutWait" EventTx = "Tx" EventUnbond = "Unbond" EventUnlock = "Unlock" EventVote = "Vote" EventProposalHeartbeat = "ProposalHeartbeat" ) /////////////////////////////////////////////////////////////////////////////// // ENCODING / DECODING /////////////////////////////////////////////////////////////////////////////// // implements events.EventData type TMEventData interface { AssertIsTMEventData() // empty interface } func (_ EventDataNewBlock) AssertIsTMEventData() {} func (_ EventDataNewBlockHeader) AssertIsTMEventData() {} func (_ EventDataTx) AssertIsTMEventData() {} func (_ EventDataRoundState) AssertIsTMEventData() {} func (_ EventDataVote) AssertIsTMEventData() {} func (_ EventDataProposalHeartbeat) AssertIsTMEventData() {} func (_ EventDataString) AssertIsTMEventData() {} func RegisterEventDatas(cdc *amino.Codec) { cdc.RegisterInterface((*TMEventData)(nil), nil) cdc.RegisterConcrete(EventDataNewBlock{}, "tendermint/event/NewBlock", nil) cdc.RegisterConcrete(EventDataNewBlockHeader{}, "tendermint/event/NewBlockHeader", nil) cdc.RegisterConcrete(EventDataTx{}, "tendermint/event/Tx", nil) cdc.RegisterConcrete(EventDataRoundState{}, "tendermint/event/RoundState", nil) cdc.RegisterConcrete(EventDataVote{}, "tendermint/event/Vote", nil) cdc.RegisterConcrete(EventDataProposalHeartbeat{}, "tendermint/event/ProposalHeartbeat", nil) cdc.RegisterConcrete(EventDataString(""), "tendermint/event/ProposalString", nil) } // Most event messages are basic types (a block, a transaction) // but some (an input to a call tx or a receive) are more exotic type EventDataNewBlock struct { Block *Block `json:"block"` } // light weight event for benchmarking type EventDataNewBlockHeader struct { Header *Header `json:"header"` } // All txs fire EventDataTx type EventDataTx struct { TxResult } type EventDataProposalHeartbeat struct { Heartbeat *Heartbeat } // NOTE: This goes into the replay WAL type EventDataRoundState struct { Height int64 `json:"height"` Round int `json:"round"` Step string `json:"step"` // private, not exposed to websockets RoundState interface{} `json:"-"` } type EventDataVote struct { Vote *Vote } type EventDataString string /////////////////////////////////////////////////////////////////////////////// // PUBSUB /////////////////////////////////////////////////////////////////////////////// const ( // EventTypeKey is a reserved key, used to specify event type in tags. EventTypeKey = "tm.event" // TxHashKey is a reserved key, used to specify transaction's hash. // see EventBus#PublishEventTx TxHashKey = "tx.hash" // TxHeightKey is a reserved key, used to specify transaction block's height. // see EventBus#PublishEventTx TxHeightKey = "tx.height" ) var ( EventQueryBond = QueryForEvent(EventBond) EventQueryUnbond = QueryForEvent(EventUnbond) EventQueryRebond = QueryForEvent(EventRebond) EventQueryDupeout = QueryForEvent(EventDupeout) EventQueryFork = QueryForEvent(EventFork) EventQueryNewBlock = QueryForEvent(EventNewBlock) EventQueryNewBlockHeader = QueryForEvent(EventNewBlockHeader) EventQueryNewRound = QueryForEvent(EventNewRound) EventQueryNewRoundStep = QueryForEvent(EventNewRoundStep) EventQueryTimeoutPropose = QueryForEvent(EventTimeoutPropose) EventQueryCompleteProposal = QueryForEvent(EventCompleteProposal) EventQueryPolka = QueryForEvent(EventPolka) EventQueryUnlock = QueryForEvent(EventUnlock) EventQueryLock = QueryForEvent(EventLock) EventQueryRelock = QueryForEvent(EventRelock) EventQueryTimeoutWait = QueryForEvent(EventTimeoutWait) EventQueryVote = QueryForEvent(EventVote) EventQueryProposalHeartbeat = QueryForEvent(EventProposalHeartbeat) EventQueryTx = QueryForEvent(EventTx) ) func EventQueryTxFor(tx Tx) tmpubsub.Query { return tmquery.MustParse(fmt.Sprintf("%s='%s' AND %s='%X'", EventTypeKey, EventTx, TxHashKey, tx.Hash())) } func QueryForEvent(eventType string) tmpubsub.Query { return tmquery.MustParse(fmt.Sprintf("%s='%s'", EventTypeKey, eventType)) } // BlockEventPublisher publishes all block related events type BlockEventPublisher interface { PublishEventNewBlock(block EventDataNewBlock) error PublishEventNewBlockHeader(header EventDataNewBlockHeader) error PublishEventTx(EventDataTx) error } type TxEventPublisher interface { PublishEventTx(EventDataTx) error }