diff --git a/event/event_cache.go b/event/event_cache.go index 2db266101e5b97e86bc0d09b919a6782f1f72ed5..fc73a197d395386292aae0f58315bbdc95ef59f3 100644 --- a/event/event_cache.go +++ b/event/event_cache.go @@ -4,8 +4,7 @@ import ( "fmt" "sync" "time" - - evts "github.com/tendermint/go-events" + "github.com/eris-ltd/eris-db/txs" ) var ( @@ -91,7 +90,7 @@ func (this *EventSubscriptions) Add(eventId string) (string, error) { } cache := newEventCache() errC := this.eventEmitter.Subscribe(subId, eventId, - func(evt evts.EventData) { + func(evt txs.EventData) { cache.mtx.Lock() defer cache.mtx.Unlock() cache.events = append(cache.events, evt) diff --git a/event/event_cache_test.go b/event/event_cache_test.go index 9240457184c53b0d410e6c3f07b3e93d524451e1..021c7e49abde4e2f9da79dbd8e50e7dff76dbd95 100644 --- a/event/event_cache_test.go +++ b/event/event_cache_test.go @@ -9,8 +9,8 @@ import ( "sync" + "github.com/eris-ltd/eris-db/txs" "github.com/stretchr/testify/assert" - evts "github.com/tendermint/go-events" ) var mockInterval = 10 * time.Millisecond @@ -18,7 +18,7 @@ var mockInterval = 10 * time.Millisecond type mockSub struct { subId string eventId string - f func(evts.EventData) + f func(txs.EventData) shutdown bool sdChan chan struct{} } @@ -29,7 +29,7 @@ type mockEventData struct { } // A mock event -func newMockSub(subId, eventId string, f func(evts.EventData)) mockSub { +func newMockSub(subId, eventId string, f func(txs.EventData)) mockSub { return mockSub{subId, eventId, f, false, make(chan struct{})} } @@ -42,7 +42,7 @@ func newMockEventEmitter() *mockEventEmitter { return &mockEventEmitter{make(map[string]mockSub), &sync.Mutex{}} } -func (this *mockEventEmitter) Subscribe(subId, eventId string, callback func(evts.EventData)) error { +func (this *mockEventEmitter) Subscribe(subId, eventId string, callback func(txs.EventData)) error { if _, ok := this.subs[subId]; ok { return nil } diff --git a/event/events.go b/event/events.go index b776c0debb87d11f54e3a39724d2ba09bdf0586c..fab369680988f7040b0b854407762299e63eb295 100644 --- a/event/events.go +++ b/event/events.go @@ -21,20 +21,29 @@ import ( "encoding/hex" "strings" - evts "github.com/tendermint/go-events" + "fmt" + + "github.com/eris-ltd/eris-db/txs" + log "github.com/eris-ltd/eris-logger" + go_events "github.com/tendermint/go-events" + tm_types "github.com/tendermint/tendermint/types" ) -// TODO improve -// TODO: [ben] yes please ^^^ -// [ben] To improve this we will switch out go-events with eris-db/event so -// that there is no need anymore for this poor wrapper. +// TODO: [Silas] this is a compatibility layer between our event types and +// TODO: go-events. Our ultimate plan is to replace go-events with our own pub-sub +// TODO: code that will better allow us to manage and multiplex events from different +// TODO: subsystems + +// Oh for a sum type +// We are using this as a marker interface for the +type anyEventData interface{} type EventEmitter interface { - Subscribe(subId, event string, callback func(evts.EventData)) error + Subscribe(subId, event string, callback func(txs.EventData)) error Unsubscribe(subId string) error } -func NewEvents(eventSwitch *evts.EventSwitch) *events { +func NewEvents(eventSwitch *go_events.EventSwitch) *events { return &events{eventSwitch} } @@ -47,12 +56,22 @@ func Multiplex(events ...EventEmitter) *multiplexedEvents { // The events struct has methods for working with events. type events struct { - eventSwitch *evts.EventSwitch + eventSwitch *go_events.EventSwitch } // Subscribe to an event. -func (this *events) Subscribe(subId, event string, callback func(evts.EventData)) error { - this.eventSwitch.AddListenerForEvent(subId, event, callback) +func (this *events) Subscribe(subId, event string, + callback func(txs.EventData)) error { + cb := func(evt go_events.EventData) { + eventData, err := mapToOurEventData(evt) + if err != nil { + log.WithError(err). + WithFields(log.Fields{"event": event}). + Error("Failed to map go-events EventData to our EventData") + } + callback(eventData) + } + this.eventSwitch.AddListenerForEvent(subId, event, cb) return nil } @@ -67,7 +86,8 @@ type multiplexedEvents struct { } // Subscribe to an event. -func (multiEvents *multiplexedEvents) Subscribe(subId, event string, callback func(evts.EventData)) error { +func (multiEvents *multiplexedEvents) Subscribe(subId, event string, + callback func(txs.EventData)) error { for _, eventEmitter := range multiEvents.eventEmitters { err := eventEmitter.Subscribe(subId, event, callback) if err != nil { @@ -118,5 +138,24 @@ func GenerateSubId() (string, error) { } rStr := hex.EncodeToString(b) return strings.ToUpper(rStr), nil +} +func mapToOurEventData(eventData anyEventData) (txs.EventData, error) { + // TODO: [Silas] avoid this with a better event pub-sub system of our own + // TODO: that maybe involves a registry of events + switch eventData := eventData.(type) { + case txs.EventData: + return eventData, nil + case tm_types.EventDataNewBlock: + return txs.EventDataNewBlock{ + Block: eventData.Block, + }, nil + case tm_types.EventDataNewBlockHeader: + return txs.EventDataNewBlockHeader{ + Header: eventData.Header, + }, nil + default: + return nil, fmt.Errorf("EventData not recognised as known EventData: %v", + eventData) + } } diff --git a/event/events_test.go b/event/events_test.go index 7fdf3e7bd245ed34c8fb96a11a7e3a33c612cde0..2927589e24f17c397326b97b62c27f2bbf49dd38 100644 --- a/event/events_test.go +++ b/event/events_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/assert" evts "github.com/tendermint/go-events" + "github.com/eris-ltd/eris-db/txs" ) func TestMultiplexedEvents(t *testing.T) { @@ -15,25 +16,25 @@ func TestMultiplexedEvents(t *testing.T) { emitter2 := newMockEventEmitter() emitter12 := Multiplex(emitter1, emitter2) - eventData1 := make(map[evts.EventData]int) - eventData2 := make(map[evts.EventData]int) - eventData12 := make(map[evts.EventData]int) + eventData1 := make(map[txs.EventData]int) + eventData2 := make(map[txs.EventData]int) + eventData12 := make(map[txs.EventData]int) mutex1 := &sync.Mutex{} mutex2 := &sync.Mutex{} mutex12 := &sync.Mutex{} - emitter12.Subscribe("Sub12", "Event12", func(eventData evts.EventData) { + emitter12.Subscribe("Sub12", "Event12", func(eventData txs.EventData) { mutex12.Lock() eventData12[eventData] = 1 mutex12.Unlock() }) - emitter1.Subscribe("Sub1", "Event1", func(eventData evts.EventData) { + emitter1.Subscribe("Sub1", "Event1", func(eventData txs.EventData) { mutex1.Lock() eventData1[eventData] = 1 mutex1.Unlock() }) - emitter2.Subscribe("Sub2", "Event2", func(eventData evts.EventData) { + emitter2.Subscribe("Sub2", "Event2", func(eventData txs.EventData) { mutex2.Lock() eventData2[eventData] = 1 mutex2.Unlock() @@ -41,7 +42,7 @@ func TestMultiplexedEvents(t *testing.T) { time.Sleep(mockInterval) - allEventData := make(map[evts.EventData]int) + allEventData := make(map[txs.EventData]int) for k, v := range eventData1 { allEventData[k] = v } @@ -49,11 +50,11 @@ func TestMultiplexedEvents(t *testing.T) { allEventData[k] = v } - assert.Equal(t, map[evts.EventData]int{mockEventData{"Sub1", "Event1"}: 1}, + assert.Equal(t, map[txs.EventData]int{mockEventData{"Sub1", "Event1"}: 1}, eventData1) - assert.Equal(t, map[evts.EventData]int{mockEventData{"Sub2", "Event2"}: 1}, + assert.Equal(t, map[txs.EventData]int{mockEventData{"Sub2", "Event2"}: 1}, eventData2) - assert.Equal(t, map[evts.EventData]int{mockEventData{"Sub12", "Event12"}: 1}, + assert.Equal(t, map[txs.EventData]int{mockEventData{"Sub12", "Event12"}: 1}, eventData12) assert.NotEmpty(t, allEventData, "Some events should have been published") diff --git a/manager/eris-mint/eris-mint.go b/manager/eris-mint/eris-mint.go index e5ba93082c4e2da52ff7c3875b5de1e65bd7418a..d15f75cdd766bfc1fb000de6b1f8e246b84922e3 100644 --- a/manager/eris-mint/eris-mint.go +++ b/manager/eris-mint/eris-mint.go @@ -138,8 +138,6 @@ func (app *ErisMint) AppendTx(txBytes []byte) (res tmsp.Result) { return tmsp.NewError(tmsp.CodeType_EncodingError, fmt.Sprintf("Encoding error: %v", err)) } - log.Info("AppendTx", "tx", *tx) - err = sm.ExecTx(app.cache, *tx, true, app.evc) if err != nil { return tmsp.NewError(tmsp.CodeType_InternalError, fmt.Sprintf("Internal error: %v", err)) diff --git a/manager/eris-mint/pipe.go b/manager/eris-mint/pipe.go index 06dde2de3fa058778bf70e134eaa7f590e2d5ae5..00d955de8a48779f5a584b0acbfab78254344c3a 100644 --- a/manager/eris-mint/pipe.go +++ b/manager/eris-mint/pipe.go @@ -236,10 +236,11 @@ func (pipe *erisMintPipe) Subscribe(listenerId, event string, rpcResponseWriter func(result rpc_tm_types.ErisDBResult)) (*rpc_tm_types.ResultSubscribe, error) { log.WithFields(log.Fields{"listenerId": listenerId, "event": event}). Info("Subscribing to event") + pipe.consensusAndManagerEvents().Subscribe(subscriptionId(listenerId, event), event, - func(eventData go_events.EventData) { + func(eventData txs.EventData) { result := rpc_tm_types.ErisDBResult(&rpc_tm_types.ResultEvent{event, - tm_types.TMEventData(eventData)}) + txs.EventData(eventData)}) // NOTE: EventSwitch callbacks must be nonblocking rpcResponseWriter(result) }) diff --git a/manager/eris-mint/transactor.go b/manager/eris-mint/transactor.go index e9882f77cbab3a9f10211a09d575ad78e7f14317..fd9201454549ffba46b7d77f1ddb393182ad8c68 100644 --- a/manager/eris-mint/transactor.go +++ b/manager/eris-mint/transactor.go @@ -207,12 +207,13 @@ func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, } wc := make(chan *txs.EventDataCall) subId := fmt.Sprintf("%X", rec.TxHash) - this.eventEmitter.Subscribe(subId, txs.EventStringAccCall(addr), func(evt tEvents.EventData) { - event := evt.(txs.EventDataCall) - if bytes.Equal(event.TxID, rec.TxHash) { - wc <- &event - } - }) + this.eventEmitter.Subscribe(subId, txs.EventStringAccCall(addr), + func(evt txs.EventData) { + event := evt.(txs.EventDataCall) + if bytes.Equal(event.TxID, rec.TxHash) { + wc <- &event + } + }) timer := time.NewTimer(300 * time.Second) toChan := timer.C diff --git a/rpc/tendermint/core/types/responses.go b/rpc/tendermint/core/types/responses.go index 77ab79af0b4a7063c7fb3c108b03cfde3de6d164..179e26dab7afac286f0aa9b890276f29cb5f8813 100644 --- a/rpc/tendermint/core/types/responses.go +++ b/rpc/tendermint/core/types/responses.go @@ -124,8 +124,8 @@ type ResultSignTx struct { } type ResultEvent struct { - Event string `json:"event"` - Data types.TMEventData `json:"data"` + Event string `json:"event"` + Data txs.EventData `json:"data"` } //---------------------------------------- diff --git a/rpc/tendermint/test/client_ws_test.go b/rpc/tendermint/test/client_ws_test.go index f31d400bf88e9aa7831b45a068e1209c057b94a6..d1fe45f9cab59b95857807ecfb525a3d4edff5b0 100644 --- a/rpc/tendermint/test/client_ws_test.go +++ b/rpc/tendermint/test/client_ws_test.go @@ -28,10 +28,11 @@ func TestWSNewBlock(t *testing.T) { unsubscribe(t, wsc, eid) wsc.Stop() }() - waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error { - fmt.Println("Check:", string(b.([]byte))) - return nil - }) + waitForEvent(t, wsc, eid, true, func() {}, + func(eid string, b interface{}) error { + fmt.Println("Check:", string(b.([]byte))) + return nil + }) } // receive a few new block messages in a row, with increasing height diff --git a/rpc/tendermint/test/common.go b/rpc/tendermint/test/common.go index 77be9cb188017e127a36c53b5b6e940e0813c56d..b0d2f07eb76a8a0ff5123306b2d6b5746005489d 100644 --- a/rpc/tendermint/test/common.go +++ b/rpc/tendermint/test/common.go @@ -29,10 +29,15 @@ func TestWrapper(runner func() int) int { return runner() } +// This main function exists as a little convenience mechanism for running the +// delve debugger which doesn't work well from go test yet. In due course it can +// be removed, but it's flux between pull requests should be considered +// inconsequential, so feel free to insert your own code if you want to use it +// as an application entry point for delve debugging. func DebugMain() { t := &testing.T{} TestWrapper(func() int { - testBroadcastTx(t, "HTTP") + testNameReg(t, "JSONRPC") return 0 }) } diff --git a/rpc/tendermint/test/shared.go b/rpc/tendermint/test/shared.go index adf972397ee8a13b4b272cedcb6ac1e34b94411d..2bcffc1f28d1cdf1024700be3216a020c8720437 100644 --- a/rpc/tendermint/test/shared.go +++ b/rpc/tendermint/test/shared.go @@ -102,9 +102,8 @@ func makeUsers(n int) []*acm.PrivAccount { return accounts } -// create a new node and sleep forever func newNode(ready chan error) { - // Run the RPC servers + // Run the 'tendermint' rpc server _, err := testCore.NewGatewayTendermint(config) ready <- err } diff --git a/rpc/tendermint/test/ws_helpers.go b/rpc/tendermint/test/ws_helpers.go index 9e6bc5ae41fc44896f76fbde97ac1e12f4359d33..cb631fd0d9f1dda7cc76db8a4d67a323759e1b0d 100644 --- a/rpc/tendermint/test/ws_helpers.go +++ b/rpc/tendermint/test/ws_helpers.go @@ -49,7 +49,8 @@ func unsubscribe(t *testing.T, wsc *client.WSClient, eventid string) { // wait for an event; do things that might trigger events, and check them when they are received // the check function takes an event id and the byte slice read off the ws -func waitForEvent(t *testing.T, wsc *client.WSClient, eventid string, dieOnTimeout bool, f func(), check func(string, interface{}) error) { +func waitForEvent(t *testing.T, wsc *client.WSClient, eventid string, + dieOnTimeout bool, f func(), check func(string, interface{}) error) { // go routine to wait for webscoket msg goodCh := make(chan interface{}) errCh := make(chan error) diff --git a/rpc/v0/wsService.go b/rpc/v0/wsService.go index 93e691dc20496e67ea0993a1d4513bbbbd0d0900..fdd48de0ed8f6a588fc3dd6e64f315328456cc8f 100644 --- a/rpc/v0/wsService.go +++ b/rpc/v0/wsService.go @@ -4,14 +4,13 @@ import ( "encoding/json" "fmt" - "github.com/tendermint/go-events" - log "github.com/eris-ltd/eris-logger" definitions "github.com/eris-ltd/eris-db/definitions" - event "github.com/eris-ltd/eris-db/event" + "github.com/eris-ltd/eris-db/event" rpc "github.com/eris-ltd/eris-db/rpc" server "github.com/eris-ltd/eris-db/server" + "github.com/eris-ltd/eris-db/txs" ) // Used for ErisDb. Implements WebSocketService. @@ -69,7 +68,8 @@ func (this *ErisDbWsService) Process(msg []byte, session *server.WSSession) { } // Convenience method for writing error responses. -func (this *ErisDbWsService) writeError(msg, id string, code int, session *server.WSSession) { +func (this *ErisDbWsService) writeError(msg, id string, code int, + session *server.WSSession) { response := rpc.NewRPCErrorResponse(id, code, msg) bts, err := this.codec.EncodeBytes(response) // If there's an error here all bets are off. @@ -80,7 +80,8 @@ func (this *ErisDbWsService) writeError(msg, id string, code int, session *serve } // Convenience method for writing responses. -func (this *ErisDbWsService) writeResponse(id string, result interface{}, session *server.WSSession) error { +func (this *ErisDbWsService) writeResponse(id string, result interface{}, + session *server.WSSession) error { response := rpc.NewRPCResponse(id, result) bts, err := this.codec.EncodeBytes(response) log.Debug("RESPONSE: %v\n", response) @@ -93,10 +94,12 @@ func (this *ErisDbWsService) writeResponse(id string, result interface{}, sessio // *************************************** Events ************************************ -func (this *ErisDbWsService) EventSubscribe(request *rpc.RPCRequest, requester interface{}) (interface{}, int, error) { +func (this *ErisDbWsService) EventSubscribe(request *rpc.RPCRequest, + requester interface{}) (interface{}, int, error) { session, ok := requester.(*server.WSSession) if !ok { - return 0, rpc.INTERNAL_ERROR, fmt.Errorf("Passing wrong object to websocket events") + return 0, rpc.INTERNAL_ERROR, + fmt.Errorf("Passing wrong object to websocket events") } param := &EventIdParam{} err := this.codec.DecodeBytes(param, request.Params) @@ -109,7 +112,7 @@ func (this *ErisDbWsService) EventSubscribe(request *rpc.RPCRequest, requester i return nil, rpc.INTERNAL_ERROR, errSID } - callback := func(ret events.EventData) { + callback := func(ret txs.EventData) { this.writeResponse(subId, ret, session) } errC := this.pipe.Events().Subscribe(subId, eventId, callback) diff --git a/test/mock/pipe.go b/test/mock/pipe.go index 4cec005042cda0373c528bcf53314d4c145c8881..9410d073d6b5259a7e0c3ab43a91c696d4abed0b 100644 --- a/test/mock/pipe.go +++ b/test/mock/pipe.go @@ -10,9 +10,8 @@ import ( manager_types "github.com/eris-ltd/eris-db/manager/types" td "github.com/eris-ltd/eris-db/test/testdata/testdata" - types "github.com/eris-ltd/eris-db/txs" + "github.com/eris-ltd/eris-db/txs" - evts "github.com/tendermint/go-events" mintTypes "github.com/tendermint/tendermint/types" ) @@ -182,7 +181,7 @@ type eventer struct { testData *td.TestData } -func (this *eventer) Subscribe(subId, event string, callback func(evts.EventData)) error { +func (this *eventer) Subscribe(subId, event string, callback func(txs.EventData)) error { return nil } @@ -250,37 +249,37 @@ func (this *transactor) CallCode(from, code, data []byte) (*core_types.Call, err return this.testData.CallCode.Output, nil } -func (this *transactor) BroadcastTx(tx types.Tx) (*types.Receipt, error) { +func (this *transactor) BroadcastTx(tx txs.Tx) (*txs.Receipt, error) { return nil, nil } -func (this *transactor) UnconfirmedTxs() (*types.UnconfirmedTxs, error) { +func (this *transactor) UnconfirmedTxs() (*txs.UnconfirmedTxs, error) { return this.testData.GetUnconfirmedTxs.Output, nil } -func (this *transactor) Transact(privKey, address, data []byte, gasLimit, fee int64) (*types.Receipt, error) { +func (this *transactor) Transact(privKey, address, data []byte, gasLimit, fee int64) (*txs.Receipt, error) { if address == nil || len(address) == 0 { return this.testData.TransactCreate.Output, nil } return this.testData.Transact.Output, nil } -func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, fee int64) (*types.EventDataCall, error) { +func (this *transactor) TransactAndHold(privKey, address, data []byte, gasLimit, fee int64) (*txs.EventDataCall, error) { return nil, nil } -func (this *transactor) Send(privKey, toAddress []byte, amount int64) (*types.Receipt, error) { +func (this *transactor) Send(privKey, toAddress []byte, amount int64) (*txs.Receipt, error) { return nil, nil } -func (this *transactor) SendAndHold(privKey, toAddress []byte, amount int64) (*types.Receipt, error) { +func (this *transactor) SendAndHold(privKey, toAddress []byte, amount int64) (*txs.Receipt, error) { return nil, nil } -func (this *transactor) TransactNameReg(privKey []byte, name, data string, amount, fee int64) (*types.Receipt, error) { +func (this *transactor) TransactNameReg(privKey []byte, name, data string, amount, fee int64) (*txs.Receipt, error) { return this.testData.TransactNameReg.Output, nil } -func (this *transactor) SignTx(tx types.Tx, privAccounts []*account.PrivAccount) (types.Tx, error) { +func (this *transactor) SignTx(tx txs.Tx, privAccounts []*account.PrivAccount) (txs.Tx, error) { return nil, nil } diff --git a/txs/events.go b/txs/events.go index 14185c3a0cb7591a100feae2023df146aea8921c..f9c7e0ecd8c0fa41ccf005d3371d146bbc1a47d1 100644 --- a/txs/events.go +++ b/txs/events.go @@ -7,7 +7,7 @@ import ( . "github.com/tendermint/go-common" "github.com/tendermint/go-wire" - "github.com/tendermint/tendermint/types" // Block + tm_types "github.com/tendermint/tendermint/types" // Block ) // Functions to generate eventId strings @@ -43,9 +43,11 @@ const ( EventDataTypeTx = byte(0x03) EventDataTypeCall = byte(0x04) EventDataTypeLog = byte(0x05) + EventDataTypeNewBlockHeader = byte(0x06) EventDataTypeRoundState = byte(0x11) EventDataTypeVote = byte(0x12) + ) type EventData interface { @@ -54,6 +56,7 @@ type EventData interface { var _ = wire.RegisterInterface( struct{ EventData }{}, + wire.ConcreteType{EventDataNewBlockHeader{}, EventDataTypeNewBlockHeader}, wire.ConcreteType{EventDataNewBlock{}, EventDataTypeNewBlock}, // wire.ConcreteType{EventDataFork{}, EventDataTypeFork }, wire.ConcreteType{EventDataTx{}, EventDataTypeTx}, @@ -67,7 +70,11 @@ var _ = wire.RegisterInterface( // but some (an input to a call tx or a receive) are more exotic type EventDataNewBlock struct { - Block *types.Block `json:"block"` + Block *tm_types.Block `json:"block"` +} + +type EventDataNewBlockHeader struct { + Header *tm_types.Header `json:"header"` } // All txs fire EventDataTx, but only CallTx might have Return or Exception @@ -107,27 +114,28 @@ type EventDataLog struct { type EventDataRoundState struct { CurrentTime time.Time `json:"current_time"` - Height int `json:"height"` - Round int `json:"round"` - Step string `json:"step"` - StartTime time.Time `json:"start_time"` - CommitTime time.Time `json:"commit_time"` - Proposal *types.Proposal `json:"proposal"` - ProposalBlock *types.Block `json:"proposal_block"` - LockedRound int `json:"locked_round"` - LockedBlock *types.Block `json:"locked_block"` - POLRound int `json:"pol_round"` + Height int `json:"height"` + Round int `json:"round"` + Step string `json:"step"` + StartTime time.Time `json:"start_time"` + CommitTime time.Time `json:"commit_time"` + Proposal *tm_types.Proposal `json:"proposal"` + ProposalBlock *tm_types.Block `json:"proposal_block"` + LockedRound int `json:"locked_round"` + LockedBlock *tm_types.Block `json:"locked_block"` + POLRound int `json:"pol_round"` } type EventDataVote struct { Index int Address []byte - Vote *types.Vote + Vote *tm_types.Vote } -func (_ EventDataNewBlock) AssertIsEventData() {} -func (_ EventDataTx) AssertIsEventData() {} -func (_ EventDataCall) AssertIsEventData() {} -func (_ EventDataLog) AssertIsEventData() {} -func (_ EventDataRoundState) AssertIsEventData() {} -func (_ EventDataVote) AssertIsEventData() {} +func (_ EventDataNewBlock) AssertIsEventData() {} +func (_ EventDataNewBlockHeader) AssertIsEventData() {} +func (_ EventDataTx) AssertIsEventData() {} +func (_ EventDataCall) AssertIsEventData() {} +func (_ EventDataLog) AssertIsEventData() {} +func (_ EventDataRoundState) AssertIsEventData() {} +func (_ EventDataVote) AssertIsEventData() {}