github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/types/events.go (about) 1 package types 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 8 abci "github.com/ari-anchor/sei-tendermint/abci/types" 9 "github.com/ari-anchor/sei-tendermint/internal/jsontypes" 10 tmquery "github.com/ari-anchor/sei-tendermint/internal/pubsub/query" 11 "github.com/ari-anchor/sei-tendermint/proto/tendermint/types" 12 ) 13 14 // Reserved event types (alphabetically sorted). 15 const ( 16 // Block level events for mass consumption by users. 17 // These events are triggered from the state package, 18 // after a block has been committed. 19 // These are also used by the tx indexer for async indexing. 20 // All of this data can be fetched through the rpc. 21 EventNewBlockValue = "NewBlock" 22 EventNewBlockHeaderValue = "NewBlockHeader" 23 EventNewEvidenceValue = "NewEvidence" 24 EventTxValue = "Tx" 25 EventValidatorSetUpdatesValue = "ValidatorSetUpdates" 26 27 // Internal consensus events. 28 // These are used for testing the consensus state machine. 29 // They can also be used to build real-time consensus visualizers. 30 EventCompleteProposalValue = "CompleteProposal" 31 // The BlockSyncStatus event will be emitted when the node switching 32 // state sync mechanism between the consensus reactor and the blocksync reactor. 33 EventBlockSyncStatusValue = "BlockSyncStatus" 34 EventLockValue = "Lock" 35 EventNewRoundValue = "NewRound" 36 EventNewRoundStepValue = "NewRoundStep" 37 EventPolkaValue = "Polka" 38 EventRelockValue = "Relock" 39 EventStateSyncStatusValue = "StateSyncStatus" 40 EventTimeoutProposeValue = "TimeoutPropose" 41 EventTimeoutWaitValue = "TimeoutWait" 42 EventValidBlockValue = "ValidBlock" 43 EventVoteValue = "Vote" 44 45 // Events emitted by the evidence reactor when evidence is validated 46 // and before it is committed 47 EventEvidenceValidatedValue = "EvidenceValidated" 48 ) 49 50 // Pre-populated ABCI Tendermint-reserved events 51 var ( 52 EventNewBlock = abci.Event{ 53 Type: strings.Split(EventTypeKey, ".")[0], 54 Attributes: []abci.EventAttribute{ 55 { 56 Key: []byte(strings.Split(EventTypeKey, ".")[1]), 57 Value: []byte(EventNewBlockValue), 58 }, 59 }, 60 } 61 62 EventNewBlockHeader = abci.Event{ 63 Type: strings.Split(EventTypeKey, ".")[0], 64 Attributes: []abci.EventAttribute{ 65 { 66 Key: []byte(strings.Split(EventTypeKey, ".")[1]), 67 Value: []byte(EventNewBlockHeaderValue), 68 }, 69 }, 70 } 71 72 EventNewEvidence = abci.Event{ 73 Type: strings.Split(EventTypeKey, ".")[0], 74 Attributes: []abci.EventAttribute{ 75 { 76 Key: []byte(strings.Split(EventTypeKey, ".")[1]), 77 Value: []byte(EventNewEvidenceValue), 78 }, 79 }, 80 } 81 82 EventTx = abci.Event{ 83 Type: strings.Split(EventTypeKey, ".")[0], 84 Attributes: []abci.EventAttribute{ 85 { 86 Key: []byte(strings.Split(EventTypeKey, ".")[1]), 87 Value: []byte(EventTxValue), 88 }, 89 }, 90 } 91 ) 92 93 // ENCODING / DECODING 94 95 // EventData is satisfied by types that can be published as event data. 96 // 97 // Implementations of this interface that contain ABCI event metadata should 98 // also implement the eventlog.ABCIEventer extension interface to expose those 99 // metadata to the event log machinery. Event data that do not contain ABCI 100 // metadata can safely omit this. 101 type EventData interface { 102 // The value must support encoding as a type-tagged JSON object. 103 jsontypes.Tagged 104 ToLegacy() LegacyEventData 105 } 106 107 type LegacyEventData interface { 108 jsontypes.Tagged 109 } 110 111 func init() { 112 jsontypes.MustRegister(EventDataBlockSyncStatus{}) 113 jsontypes.MustRegister(EventDataCompleteProposal{}) 114 jsontypes.MustRegister(EventDataNewBlock{}) 115 jsontypes.MustRegister(EventDataNewBlockHeader{}) 116 jsontypes.MustRegister(EventDataNewEvidence{}) 117 jsontypes.MustRegister(EventDataNewRound{}) 118 jsontypes.MustRegister(EventDataRoundState{}) 119 jsontypes.MustRegister(EventDataStateSyncStatus{}) 120 jsontypes.MustRegister(EventDataTx{}) 121 jsontypes.MustRegister(EventDataValidatorSetUpdates{}) 122 jsontypes.MustRegister(EventDataVote{}) 123 jsontypes.MustRegister(EventDataEvidenceValidated{}) 124 jsontypes.MustRegister(LegacyEventDataNewBlock{}) 125 jsontypes.MustRegister(LegacyEventDataTx{}) 126 jsontypes.MustRegister(EventDataString("")) 127 } 128 129 // Most event messages are basic types (a block, a transaction) 130 // but some (an input to a call tx or a receive) are more exotic 131 132 type EventDataNewBlock struct { 133 Block *Block `json:"block"` 134 BlockID BlockID `json:"block_id"` 135 136 ResultFinalizeBlock abci.ResponseFinalizeBlock `json:"result_finalize_block"` 137 } 138 139 // TypeTag implements the required method of jsontypes.Tagged. 140 func (EventDataNewBlock) TypeTag() string { return "tendermint/event/NewBlock_new" } 141 142 // ABCIEvents implements the eventlog.ABCIEventer interface. 143 func (e EventDataNewBlock) ABCIEvents() []abci.Event { 144 base := []abci.Event{eventWithAttr(BlockHeightKey, fmt.Sprint(e.Block.Header.Height))} 145 return append(base, e.ResultFinalizeBlock.Events...) 146 } 147 148 type LegacyEventDataNewBlock struct { 149 Block *LegacyBlock `json:"block"` 150 ResultBeginBlock abci.ResponseBeginBlock `json:"result_begin_block"` 151 ResultEndBlock LegacyResponseEndBlock `json:"result_end_block"` 152 } 153 154 func (LegacyEventDataNewBlock) TypeTag() string { return "tendermint/event/NewBlock" } 155 156 type LegacyEvidence struct { 157 Evidence EvidenceList `json:"evidence"` 158 } 159 160 type LegacyBlock struct { 161 Header `json:"header"` 162 Data `json:"data"` 163 Evidence LegacyEvidence `json:"evidence"` 164 LastCommit *Commit `json:"last_commit"` 165 } 166 167 type LegacyResponseEndBlock struct { 168 ValidatorUpdates []abci.ValidatorUpdate `json:"validator_updates"` 169 ConsensusParamUpdates *LegacyConsensusParams `json:"consensus_param_updates,omitempty"` 170 Events []abci.Event `json:"events,omitempty"` 171 } 172 173 type LegacyConsensusParams struct { 174 Block *LegacyBlockParams `json:"block,omitempty"` 175 Evidence *LegacyEvidenceParams `json:"evidence,omitempty"` 176 Validator *types.ValidatorParams `json:"validator,omitempty"` 177 Version *LegacyVersionParams `json:"version,omitempty"` 178 } 179 180 type LegacyBlockParams struct { 181 MaxBytes string `json:"max_bytes,omitempty"` 182 MaxGas string `json:"max_gas,omitempty"` 183 } 184 185 type LegacyEvidenceParams struct { 186 MaxAgeNumBlocks string `json:"max_age_num_blocks,omitempty"` 187 MaxAgeDuration string `json:"max_age_duration"` 188 MaxBytes string `json:"max_bytes,omitempty"` 189 } 190 191 type LegacyVersionParams struct { 192 AppVersion string `json:"app_version,omitempty"` 193 } 194 195 func (e EventDataNewBlock) ToLegacy() LegacyEventData { 196 block := &LegacyBlock{} 197 if e.Block != nil { 198 block = &LegacyBlock{ 199 Header: e.Block.Header, 200 Data: e.Block.Data, 201 Evidence: LegacyEvidence{Evidence: e.Block.Evidence}, 202 LastCommit: e.Block.LastCommit, 203 } 204 } 205 consensusParamUpdates := &LegacyConsensusParams{} 206 if e.ResultFinalizeBlock.ConsensusParamUpdates != nil { 207 if e.ResultFinalizeBlock.ConsensusParamUpdates.Block != nil { 208 consensusParamUpdates.Block = &LegacyBlockParams{ 209 MaxBytes: fmt.Sprintf("%d", e.ResultFinalizeBlock.ConsensusParamUpdates.Block.MaxBytes), 210 MaxGas: fmt.Sprintf("%d", e.ResultFinalizeBlock.ConsensusParamUpdates.Block.MaxGas), 211 } 212 } 213 if e.ResultFinalizeBlock.ConsensusParamUpdates.Evidence != nil { 214 consensusParamUpdates.Evidence = &LegacyEvidenceParams{ 215 MaxAgeNumBlocks: fmt.Sprintf("%d", e.ResultFinalizeBlock.ConsensusParamUpdates.Evidence.MaxAgeNumBlocks), 216 MaxAgeDuration: fmt.Sprintf("%d", e.ResultFinalizeBlock.ConsensusParamUpdates.Evidence.MaxAgeDuration), 217 MaxBytes: fmt.Sprintf("%d", e.ResultFinalizeBlock.ConsensusParamUpdates.Evidence.MaxBytes), 218 } 219 } 220 if e.ResultFinalizeBlock.ConsensusParamUpdates.Validator != nil { 221 consensusParamUpdates.Validator = &types.ValidatorParams{ 222 PubKeyTypes: e.ResultFinalizeBlock.ConsensusParamUpdates.Validator.PubKeyTypes, 223 } 224 } 225 if e.ResultFinalizeBlock.ConsensusParamUpdates.Version != nil { 226 consensusParamUpdates.Version = &LegacyVersionParams{ 227 AppVersion: fmt.Sprintf("%d", e.ResultFinalizeBlock.ConsensusParamUpdates.Version.AppVersion), 228 } 229 } 230 } 231 return &LegacyEventDataNewBlock{ 232 Block: block, 233 ResultBeginBlock: abci.ResponseBeginBlock{Events: e.ResultFinalizeBlock.Events}, 234 ResultEndBlock: LegacyResponseEndBlock{ 235 ValidatorUpdates: e.ResultFinalizeBlock.ValidatorUpdates, 236 Events: []abci.Event{}, 237 ConsensusParamUpdates: consensusParamUpdates, 238 }, 239 } 240 } 241 242 type EventDataNewBlockHeader struct { 243 Header Header `json:"header"` 244 245 NumTxs int64 `json:"num_txs,string"` // Number of txs in a block 246 ResultFinalizeBlock abci.ResponseFinalizeBlock `json:"result_finalize_block"` 247 } 248 249 // TypeTag implements the required method of jsontypes.Tagged. 250 func (EventDataNewBlockHeader) TypeTag() string { return "tendermint/event/NewBlockHeader" } 251 252 // ABCIEvents implements the eventlog.ABCIEventer interface. 253 func (e EventDataNewBlockHeader) ABCIEvents() []abci.Event { 254 base := []abci.Event{eventWithAttr(BlockHeightKey, fmt.Sprint(e.Header.Height))} 255 return append(base, e.ResultFinalizeBlock.Events...) 256 } 257 258 func (e EventDataNewBlockHeader) ToLegacy() LegacyEventData { 259 return e 260 } 261 262 type EventDataNewEvidence struct { 263 Evidence Evidence `json:"evidence"` 264 265 Height int64 `json:"height,string"` 266 } 267 268 // TypeTag implements the required method of jsontypes.Tagged. 269 func (EventDataNewEvidence) TypeTag() string { return "tendermint/event/NewEvidence" } 270 271 func (e EventDataNewEvidence) ToLegacy() LegacyEventData { 272 return e 273 } 274 275 // All txs fire EventDataTx 276 type EventDataTx struct { 277 abci.TxResult 278 } 279 280 // TypeTag implements the required method of jsontypes.Tagged. 281 func (EventDataTx) TypeTag() string { return "tendermint/event/Tx_new" } 282 283 // ABCIEvents implements the eventlog.ABCIEventer interface. 284 func (e EventDataTx) ABCIEvents() []abci.Event { 285 base := []abci.Event{ 286 eventWithAttr(TxHashKey, fmt.Sprintf("%X", Tx(e.Tx).Hash())), 287 eventWithAttr(TxHeightKey, fmt.Sprintf("%d", e.Height)), 288 } 289 return append(base, e.Result.Events...) 290 } 291 292 type LegacyEventDataTx struct { 293 TxResult LegacyTxResult `json:"TxResult"` 294 } 295 296 type LegacyTxResult struct { 297 Height string `json:"height,omitempty"` 298 Index uint32 `json:"index,omitempty"` 299 Tx []byte `json:"tx,omitempty"` 300 Result LegacyResult `json:"result"` 301 } 302 303 type LegacyResult struct { 304 Log string `json:"log,omitempty"` 305 GasWanted string `json:"gas_wanted,omitempty"` 306 GasUsed string `json:"gas_used,omitempty"` 307 Events []abci.Event `json:"events,omitempty"` 308 } 309 310 func (LegacyEventDataTx) TypeTag() string { 311 return "tendermint/event/Tx" 312 } 313 314 func (e EventDataTx) ToLegacy() LegacyEventData { 315 return LegacyEventDataTx{ 316 TxResult: LegacyTxResult{ 317 Height: fmt.Sprintf("%d", e.Height), 318 Index: e.Index, 319 Tx: e.Tx, 320 Result: LegacyResult{ 321 Log: e.Result.Log, 322 GasWanted: fmt.Sprintf("%d", e.Result.GasWanted), 323 GasUsed: fmt.Sprintf("%d", e.Result.GasUsed), 324 Events: e.Result.Events, 325 }, 326 }, 327 } 328 } 329 330 // NOTE: This goes into the replay WAL 331 type EventDataRoundState struct { 332 Height int64 `json:"height,string"` 333 Round int32 `json:"round"` 334 Step string `json:"step"` 335 } 336 337 // TypeTag implements the required method of jsontypes.Tagged. 338 func (EventDataRoundState) TypeTag() string { return "tendermint/event/RoundState" } 339 340 func (e EventDataRoundState) ToLegacy() LegacyEventData { 341 return e 342 } 343 344 type ValidatorInfo struct { 345 Address Address `json:"address"` 346 Index int32 `json:"index"` 347 } 348 349 type EventDataNewRound struct { 350 Height int64 `json:"height,string"` 351 Round int32 `json:"round"` 352 Step string `json:"step"` 353 354 Proposer ValidatorInfo `json:"proposer"` 355 } 356 357 // TypeTag implements the required method of jsontypes.Tagged. 358 func (EventDataNewRound) TypeTag() string { return "tendermint/event/NewRound" } 359 360 func (e EventDataNewRound) ToLegacy() LegacyEventData { 361 return e 362 } 363 364 type EventDataCompleteProposal struct { 365 Height int64 `json:"height,string"` 366 Round int32 `json:"round"` 367 Step string `json:"step"` 368 369 BlockID BlockID `json:"block_id"` 370 } 371 372 // TypeTag implements the required method of jsontypes.Tagged. 373 func (EventDataCompleteProposal) TypeTag() string { return "tendermint/event/CompleteProposal" } 374 375 func (e EventDataCompleteProposal) ToLegacy() LegacyEventData { 376 return e 377 } 378 379 type EventDataVote struct { 380 Vote *Vote 381 } 382 383 // TypeTag implements the required method of jsontypes.Tagged. 384 func (EventDataVote) TypeTag() string { return "tendermint/event/Vote" } 385 386 func (e EventDataVote) ToLegacy() LegacyEventData { 387 return e 388 } 389 390 type EventDataString string 391 392 // TypeTag implements the required method of jsontypes.Tagged. 393 func (EventDataString) TypeTag() string { return "tendermint/event/ProposalString" } 394 395 func (e EventDataString) ToLegacy() LegacyEventData { 396 return e 397 } 398 399 type EventDataValidatorSetUpdates struct { 400 ValidatorUpdates []*Validator `json:"validator_updates"` 401 } 402 403 // TypeTag implements the required method of jsontypes.Tagged. 404 func (EventDataValidatorSetUpdates) TypeTag() string { return "tendermint/event/ValidatorSetUpdates" } 405 406 func (e EventDataValidatorSetUpdates) ToLegacy() LegacyEventData { 407 return e 408 } 409 410 // EventDataBlockSyncStatus shows the fastsync status and the 411 // height when the node state sync mechanism changes. 412 type EventDataBlockSyncStatus struct { 413 Complete bool `json:"complete"` 414 Height int64 `json:"height,string"` 415 } 416 417 // TypeTag implements the required method of jsontypes.Tagged. 418 func (EventDataBlockSyncStatus) TypeTag() string { return "tendermint/event/FastSyncStatus" } 419 420 func (e EventDataBlockSyncStatus) ToLegacy() LegacyEventData { 421 return e 422 } 423 424 // EventDataStateSyncStatus shows the statesync status and the 425 // height when the node state sync mechanism changes. 426 type EventDataStateSyncStatus struct { 427 Complete bool `json:"complete"` 428 Height int64 `json:"height,string"` 429 } 430 431 // TypeTag implements the required method of jsontypes.Tagged. 432 func (EventDataStateSyncStatus) TypeTag() string { return "tendermint/event/StateSyncStatus" } 433 434 func (e EventDataStateSyncStatus) ToLegacy() LegacyEventData { 435 return e 436 } 437 438 type EventDataEvidenceValidated struct { 439 Evidence Evidence `json:"evidence"` 440 441 Height int64 `json:"height,string"` 442 } 443 444 // TypeTag implements the required method of jsontypes.Tagged. 445 func (EventDataEvidenceValidated) TypeTag() string { return "tendermint/event/EvidenceValidated" } 446 447 func (e EventDataEvidenceValidated) ToLegacy() LegacyEventData { 448 return e 449 } 450 451 // PUBSUB 452 453 const ( 454 // EventTypeKey is a reserved composite key for event name. 455 EventTypeKey = "tm.event" 456 457 // TxHashKey is a reserved key, used to specify transaction's hash. 458 // see EventBus#PublishEventTx 459 TxHashKey = "tx.hash" 460 461 // TxHeightKey is a reserved key, used to specify transaction block's height. 462 // see EventBus#PublishEventTx 463 TxHeightKey = "tx.height" 464 465 // BlockHeightKey is a reserved key used for indexing FinalizeBlock events. 466 BlockHeightKey = "block.height" 467 ) 468 469 var ( 470 EventQueryCompleteProposal = QueryForEvent(EventCompleteProposalValue) 471 EventQueryLock = QueryForEvent(EventLockValue) 472 EventQueryNewBlock = QueryForEvent(EventNewBlockValue) 473 EventQueryNewBlockHeader = QueryForEvent(EventNewBlockHeaderValue) 474 EventQueryNewEvidence = QueryForEvent(EventNewEvidenceValue) 475 EventQueryNewRound = QueryForEvent(EventNewRoundValue) 476 EventQueryNewRoundStep = QueryForEvent(EventNewRoundStepValue) 477 EventQueryPolka = QueryForEvent(EventPolkaValue) 478 EventQueryRelock = QueryForEvent(EventRelockValue) 479 EventQueryTimeoutPropose = QueryForEvent(EventTimeoutProposeValue) 480 EventQueryTimeoutWait = QueryForEvent(EventTimeoutWaitValue) 481 EventQueryTx = QueryForEvent(EventTxValue) 482 EventQueryValidatorSetUpdates = QueryForEvent(EventValidatorSetUpdatesValue) 483 EventQueryValidBlock = QueryForEvent(EventValidBlockValue) 484 EventQueryVote = QueryForEvent(EventVoteValue) 485 EventQueryBlockSyncStatus = QueryForEvent(EventBlockSyncStatusValue) 486 EventQueryStateSyncStatus = QueryForEvent(EventStateSyncStatusValue) 487 EventQueryEvidenceValidated = QueryForEvent(EventEvidenceValidatedValue) 488 ) 489 490 func EventQueryTxFor(tx Tx) *tmquery.Query { 491 return tmquery.MustCompile(fmt.Sprintf("%s='%s' AND %s='%X'", EventTypeKey, EventTxValue, TxHashKey, tx.Hash())) 492 } 493 494 func QueryForEvent(eventValue string) *tmquery.Query { 495 return tmquery.MustCompile(fmt.Sprintf("%s='%s'", EventTypeKey, eventValue)) 496 } 497 498 // BlockEventPublisher publishes all block related events 499 type BlockEventPublisher interface { 500 PublishEventNewBlock(EventDataNewBlock) error 501 PublishEventNewBlockHeader(EventDataNewBlockHeader) error 502 PublishEventNewEvidence(EventDataNewEvidence) error 503 PublishEventTx(EventDataTx) error 504 PublishEventValidatorSetUpdates(EventDataValidatorSetUpdates) error 505 } 506 507 type TxEventPublisher interface { 508 PublishEventTx(EventDataTx) error 509 } 510 511 // eventWithAttr constructs a single abci.Event with a single attribute. 512 // The type of the event and the name of the attribute are obtained by 513 // splitting the event type on period (e.g., "foo.bar"). 514 func eventWithAttr(etype, value string) abci.Event { 515 parts := strings.SplitN(etype, ".", 2) 516 return abci.Event{ 517 Type: parts[0], 518 Attributes: []abci.EventAttribute{{ 519 Key: []byte(parts[1]), Value: []byte(value), 520 }}, 521 } 522 } 523 524 func TryUnmarshalEventData(data json.RawMessage) (EventData, error) { 525 var eventData EventData 526 err := jsontypes.Unmarshal(data, &eventData) 527 if err != nil { 528 return nil, err 529 } 530 return eventData, nil 531 }