mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-24 10:11:48 +00:00
Merge pull request #788 from tendermint/feature/548-indexing-tags
new pubsub package
This commit is contained in:
46
types/event_buffer.go
Normal file
46
types/event_buffer.go
Normal file
@ -0,0 +1,46 @@
|
||||
package types
|
||||
|
||||
// Interface assertions
|
||||
var _ TxEventPublisher = (*TxEventBuffer)(nil)
|
||||
|
||||
// TxEventBuffer is a buffer of events, which uses a slice to temporarily store
|
||||
// events.
|
||||
type TxEventBuffer struct {
|
||||
next TxEventPublisher
|
||||
capacity int
|
||||
events []EventDataTx
|
||||
}
|
||||
|
||||
// NewTxEventBuffer accepts a TxEventPublisher and returns a new buffer with the given
|
||||
// capacity.
|
||||
func NewTxEventBuffer(next TxEventPublisher, capacity int) *TxEventBuffer {
|
||||
return &TxEventBuffer{
|
||||
next: next,
|
||||
capacity: capacity,
|
||||
events: make([]EventDataTx, 0, capacity),
|
||||
}
|
||||
}
|
||||
|
||||
// Len returns the number of events cached.
|
||||
func (b TxEventBuffer) Len() int {
|
||||
return len(b.events)
|
||||
}
|
||||
|
||||
// PublishEventTx buffers an event to be fired upon finality.
|
||||
func (b *TxEventBuffer) PublishEventTx(e EventDataTx) error {
|
||||
b.events = append(b.events, e)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Flush publishes events by running next.PublishWithTags on all cached events.
|
||||
// Blocks. Clears cached events.
|
||||
func (b *TxEventBuffer) Flush() error {
|
||||
for _, e := range b.events {
|
||||
err := b.next.PublishEventTx(e)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
b.events = make([]EventDataTx, 0, b.capacity)
|
||||
return nil
|
||||
}
|
21
types/event_buffer_test.go
Normal file
21
types/event_buffer_test.go
Normal file
@ -0,0 +1,21 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type eventBusMock struct{}
|
||||
|
||||
func (eventBusMock) PublishEventTx(e EventDataTx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestEventBuffer(t *testing.T) {
|
||||
b := NewTxEventBuffer(eventBusMock{}, 1)
|
||||
b.PublishEventTx(EventDataTx{})
|
||||
assert.Equal(t, 1, b.Len())
|
||||
b.Flush()
|
||||
assert.Equal(t, 0, b.Len())
|
||||
}
|
129
types/event_bus.go
Normal file
129
types/event_bus.go
Normal file
@ -0,0 +1,129 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/log"
|
||||
tmpubsub "github.com/tendermint/tmlibs/pubsub"
|
||||
)
|
||||
|
||||
const defaultCapacity = 1000
|
||||
|
||||
// EventBus is a common bus for all events going through the system. All calls
|
||||
// are proxied to underlying pubsub server. All events must be published using
|
||||
// EventBus to ensure correct data types.
|
||||
type EventBus struct {
|
||||
cmn.BaseService
|
||||
pubsub *tmpubsub.Server
|
||||
}
|
||||
|
||||
// NewEventBus returns a new event bus.
|
||||
func NewEventBus() *EventBus {
|
||||
return NewEventBusWithBufferCapacity(defaultCapacity)
|
||||
}
|
||||
|
||||
// NewEventBusWithBufferCapacity returns a new event bus with the given buffer capacity.
|
||||
func NewEventBusWithBufferCapacity(cap int) *EventBus {
|
||||
// capacity could be exposed later if needed
|
||||
pubsub := tmpubsub.NewServer(tmpubsub.BufferCapacity(cap))
|
||||
b := &EventBus{pubsub: pubsub}
|
||||
b.BaseService = *cmn.NewBaseService(nil, "EventBus", b)
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *EventBus) SetLogger(l log.Logger) {
|
||||
b.BaseService.SetLogger(l)
|
||||
b.pubsub.SetLogger(l.With("module", "pubsub"))
|
||||
}
|
||||
|
||||
func (b *EventBus) OnStart() error {
|
||||
return b.pubsub.OnStart()
|
||||
}
|
||||
|
||||
func (b *EventBus) OnStop() {
|
||||
b.pubsub.OnStop()
|
||||
}
|
||||
|
||||
func (b *EventBus) Subscribe(ctx context.Context, subscriber string, query tmpubsub.Query, out chan<- interface{}) error {
|
||||
return b.pubsub.Subscribe(ctx, subscriber, query, out)
|
||||
}
|
||||
|
||||
func (b *EventBus) Unsubscribe(ctx context.Context, subscriber string, query tmpubsub.Query) error {
|
||||
return b.pubsub.Unsubscribe(ctx, subscriber, query)
|
||||
}
|
||||
|
||||
func (b *EventBus) UnsubscribeAll(ctx context.Context, subscriber string) error {
|
||||
return b.pubsub.UnsubscribeAll(ctx, subscriber)
|
||||
}
|
||||
|
||||
func (b *EventBus) Publish(eventType string, eventData TMEventData) error {
|
||||
// no explicit deadline for publishing events
|
||||
ctx := context.Background()
|
||||
b.pubsub.PublishWithTags(ctx, eventData, map[string]interface{}{EventTypeKey: eventType})
|
||||
return nil
|
||||
}
|
||||
|
||||
//--- block, tx, and vote events
|
||||
|
||||
func (b *EventBus) PublishEventNewBlock(block EventDataNewBlock) error {
|
||||
return b.Publish(EventNewBlock, TMEventData{block})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventNewBlockHeader(header EventDataNewBlockHeader) error {
|
||||
return b.Publish(EventNewBlockHeader, TMEventData{header})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventVote(vote EventDataVote) error {
|
||||
return b.Publish(EventVote, TMEventData{vote})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventTx(tx EventDataTx) error {
|
||||
// no explicit deadline for publishing events
|
||||
ctx := context.Background()
|
||||
b.pubsub.PublishWithTags(ctx, TMEventData{tx}, map[string]interface{}{EventTypeKey: EventTx, TxHashKey: fmt.Sprintf("%X", tx.Tx.Hash())})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventProposalHeartbeat(ph EventDataProposalHeartbeat) error {
|
||||
return b.Publish(EventProposalHeartbeat, TMEventData{ph})
|
||||
}
|
||||
|
||||
//--- EventDataRoundState events
|
||||
|
||||
func (b *EventBus) PublishEventNewRoundStep(rs EventDataRoundState) error {
|
||||
return b.Publish(EventNewRoundStep, TMEventData{rs})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventTimeoutPropose(rs EventDataRoundState) error {
|
||||
return b.Publish(EventTimeoutPropose, TMEventData{rs})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventTimeoutWait(rs EventDataRoundState) error {
|
||||
return b.Publish(EventTimeoutWait, TMEventData{rs})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventNewRound(rs EventDataRoundState) error {
|
||||
return b.Publish(EventNewRound, TMEventData{rs})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventCompleteProposal(rs EventDataRoundState) error {
|
||||
return b.Publish(EventCompleteProposal, TMEventData{rs})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventPolka(rs EventDataRoundState) error {
|
||||
return b.Publish(EventPolka, TMEventData{rs})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventUnlock(rs EventDataRoundState) error {
|
||||
return b.Publish(EventUnlock, TMEventData{rs})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventRelock(rs EventDataRoundState) error {
|
||||
return b.Publish(EventRelock, TMEventData{rs})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventLock(rs EventDataRoundState) error {
|
||||
return b.Publish(EventLock, TMEventData{rs})
|
||||
}
|
122
types/event_bus_test.go
Normal file
122
types/event_bus_test.go
Normal file
@ -0,0 +1,122 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
tmpubsub "github.com/tendermint/tmlibs/pubsub"
|
||||
)
|
||||
|
||||
func BenchmarkEventBus(b *testing.B) {
|
||||
benchmarks := []struct {
|
||||
name string
|
||||
numClients int
|
||||
randQueries bool
|
||||
randEvents bool
|
||||
}{
|
||||
{"10Clients1Query1Event", 10, false, false},
|
||||
{"100Clients", 100, false, false},
|
||||
{"1000Clients", 1000, false, false},
|
||||
|
||||
{"10ClientsRandQueries1Event", 10, true, false},
|
||||
{"100Clients", 100, true, false},
|
||||
{"1000Clients", 1000, true, false},
|
||||
|
||||
{"10ClientsRandQueriesRandEvents", 10, true, true},
|
||||
{"100Clients", 100, true, true},
|
||||
{"1000Clients", 1000, true, true},
|
||||
|
||||
{"10Clients1QueryRandEvents", 10, false, true},
|
||||
{"100Clients", 100, false, true},
|
||||
{"1000Clients", 1000, false, true},
|
||||
}
|
||||
|
||||
for _, bm := range benchmarks {
|
||||
b.Run(bm.name, func(b *testing.B) {
|
||||
benchmarkEventBus(bm.numClients, bm.randQueries, bm.randEvents, b)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func benchmarkEventBus(numClients int, randQueries bool, randEvents bool, b *testing.B) {
|
||||
// for random* functions
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
eventBus := NewEventBusWithBufferCapacity(0) // set buffer capacity to 0 so we are not testing cache
|
||||
eventBus.Start()
|
||||
defer eventBus.Stop()
|
||||
|
||||
ctx := context.Background()
|
||||
q := EventQueryNewBlock
|
||||
|
||||
for i := 0; i < numClients; i++ {
|
||||
ch := make(chan interface{})
|
||||
go func() {
|
||||
for range ch {
|
||||
}
|
||||
}()
|
||||
if randQueries {
|
||||
q = randQuery()
|
||||
}
|
||||
eventBus.Subscribe(ctx, fmt.Sprintf("client-%d", i), q, ch)
|
||||
}
|
||||
|
||||
eventType := EventNewBlock
|
||||
|
||||
b.ReportAllocs()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
if randEvents {
|
||||
eventType = randEvent()
|
||||
}
|
||||
|
||||
eventBus.Publish(eventType, TMEventData{"Gamora"})
|
||||
}
|
||||
}
|
||||
|
||||
var events = []string{EventBond,
|
||||
EventUnbond,
|
||||
EventRebond,
|
||||
EventDupeout,
|
||||
EventFork,
|
||||
EventNewBlock,
|
||||
EventNewBlockHeader,
|
||||
EventNewRound,
|
||||
EventNewRoundStep,
|
||||
EventTimeoutPropose,
|
||||
EventCompleteProposal,
|
||||
EventPolka,
|
||||
EventUnlock,
|
||||
EventLock,
|
||||
EventRelock,
|
||||
EventTimeoutWait,
|
||||
EventVote}
|
||||
|
||||
func randEvent() string {
|
||||
return events[rand.Intn(len(events))]
|
||||
}
|
||||
|
||||
var queries = []tmpubsub.Query{EventQueryBond,
|
||||
EventQueryUnbond,
|
||||
EventQueryRebond,
|
||||
EventQueryDupeout,
|
||||
EventQueryFork,
|
||||
EventQueryNewBlock,
|
||||
EventQueryNewBlockHeader,
|
||||
EventQueryNewRound,
|
||||
EventQueryNewRoundStep,
|
||||
EventQueryTimeoutPropose,
|
||||
EventQueryCompleteProposal,
|
||||
EventQueryPolka,
|
||||
EventQueryUnlock,
|
||||
EventQueryLock,
|
||||
EventQueryRelock,
|
||||
EventQueryTimeoutWait,
|
||||
EventQueryVote}
|
||||
|
||||
func randQuery() tmpubsub.Query {
|
||||
return queries[rand.Intn(len(queries))]
|
||||
}
|
225
types/events.go
225
types/events.go
@ -1,55 +1,53 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
// for registering TMEventData as events.EventData
|
||||
"fmt"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/events"
|
||||
tmpubsub "github.com/tendermint/tmlibs/pubsub"
|
||||
tmquery "github.com/tendermint/tmlibs/pubsub/query"
|
||||
)
|
||||
|
||||
// Functions to generate eventId strings
|
||||
// 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"
|
||||
)
|
||||
|
||||
// Reserved
|
||||
func EventStringBond() string { return "Bond" }
|
||||
func EventStringUnbond() string { return "Unbond" }
|
||||
func EventStringRebond() string { return "Rebond" }
|
||||
func EventStringDupeout() string { return "Dupeout" }
|
||||
func EventStringFork() string { return "Fork" }
|
||||
func EventStringTx(tx Tx) string { return cmn.Fmt("Tx:%X", tx.Hash()) }
|
||||
|
||||
func EventStringNewBlock() string { return "NewBlock" }
|
||||
func EventStringNewBlockHeader() string { return "NewBlockHeader" }
|
||||
func EventStringNewRound() string { return "NewRound" }
|
||||
func EventStringNewRoundStep() string { return "NewRoundStep" }
|
||||
func EventStringTimeoutPropose() string { return "TimeoutPropose" }
|
||||
func EventStringCompleteProposal() string { return "CompleteProposal" }
|
||||
func EventStringPolka() string { return "Polka" }
|
||||
func EventStringUnlock() string { return "Unlock" }
|
||||
func EventStringLock() string { return "Lock" }
|
||||
func EventStringRelock() string { return "Relock" }
|
||||
func EventStringTimeoutWait() string { return "TimeoutWait" }
|
||||
func EventStringVote() string { return "Vote" }
|
||||
|
||||
func EventStringProposalHeartbeat() string { return "ProposalHeartbeat" }
|
||||
|
||||
//----------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// ENCODING / DECODING
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var (
|
||||
EventDataNameNewBlock = "new_block"
|
||||
EventDataNameNewBlockHeader = "new_block_header"
|
||||
EventDataNameTx = "tx"
|
||||
EventDataNameRoundState = "round_state"
|
||||
EventDataNameVote = "vote"
|
||||
|
||||
EventDataNameProposalHeartbeat = "proposer_heartbeat"
|
||||
EventDataNameNewBlock = "new_block"
|
||||
EventDataNameNewBlockHeader = "new_block_header"
|
||||
EventDataNameTx = "tx"
|
||||
EventDataNameRoundState = "round_state"
|
||||
EventDataNameVote = "vote"
|
||||
EventDataNameProposalHeartbeat = "proposal_heartbeat"
|
||||
)
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
// implements events.EventData
|
||||
type TMEventDataInner interface {
|
||||
events.EventData
|
||||
// empty interface
|
||||
}
|
||||
|
||||
type TMEventData struct {
|
||||
@ -81,14 +79,12 @@ func (tmr TMEventData) Empty() bool {
|
||||
}
|
||||
|
||||
const (
|
||||
EventDataTypeNewBlock = byte(0x01)
|
||||
EventDataTypeFork = byte(0x02)
|
||||
EventDataTypeTx = byte(0x03)
|
||||
EventDataTypeNewBlockHeader = byte(0x04)
|
||||
|
||||
EventDataTypeRoundState = byte(0x11)
|
||||
EventDataTypeVote = byte(0x12)
|
||||
|
||||
EventDataTypeNewBlock = byte(0x01)
|
||||
EventDataTypeFork = byte(0x02)
|
||||
EventDataTypeTx = byte(0x03)
|
||||
EventDataTypeNewBlockHeader = byte(0x04)
|
||||
EventDataTypeRoundState = byte(0x11)
|
||||
EventDataTypeVote = byte(0x12)
|
||||
EventDataTypeProposalHeartbeat = byte(0x20)
|
||||
)
|
||||
|
||||
@ -140,112 +136,47 @@ type EventDataVote struct {
|
||||
Vote *Vote
|
||||
}
|
||||
|
||||
func (_ EventDataNewBlock) AssertIsTMEventData() {}
|
||||
func (_ EventDataNewBlockHeader) AssertIsTMEventData() {}
|
||||
func (_ EventDataTx) AssertIsTMEventData() {}
|
||||
func (_ EventDataRoundState) AssertIsTMEventData() {}
|
||||
func (_ EventDataVote) AssertIsTMEventData() {}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// PUBSUB
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func (_ EventDataProposalHeartbeat) AssertIsTMEventData() {}
|
||||
const (
|
||||
// EventTypeKey is a reserved key, used to specify event type in tags.
|
||||
EventTypeKey = "tm.events.type"
|
||||
// TxHashKey is a reserved key, used to specify transaction's hash.
|
||||
// see EventBus#PublishEventTx
|
||||
TxHashKey = "tx.hash"
|
||||
)
|
||||
|
||||
//----------------------------------------
|
||||
// Wrappers for type safety
|
||||
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)
|
||||
)
|
||||
|
||||
type Fireable interface {
|
||||
events.Fireable
|
||||
func EventQueryTx(tx Tx) tmpubsub.Query {
|
||||
return tmquery.MustParse(fmt.Sprintf("%s='%s' AND %s='%X'", EventTypeKey, EventTx, TxHashKey, tx.Hash()))
|
||||
}
|
||||
|
||||
type Eventable interface {
|
||||
SetEventSwitch(EventSwitch)
|
||||
func queryForEvent(eventType string) tmpubsub.Query {
|
||||
return tmquery.MustParse(fmt.Sprintf("%s='%s'", EventTypeKey, eventType))
|
||||
}
|
||||
|
||||
type EventSwitch interface {
|
||||
events.EventSwitch
|
||||
}
|
||||
|
||||
type EventCache interface {
|
||||
Fireable
|
||||
Flush()
|
||||
}
|
||||
|
||||
func NewEventSwitch() EventSwitch {
|
||||
return events.NewEventSwitch()
|
||||
}
|
||||
|
||||
func NewEventCache(evsw EventSwitch) EventCache {
|
||||
return events.NewEventCache(evsw)
|
||||
}
|
||||
|
||||
// All events should be based on this FireEvent to ensure they are TMEventData
|
||||
func fireEvent(fireable events.Fireable, event string, data TMEventData) {
|
||||
if fireable != nil {
|
||||
fireable.FireEvent(event, data)
|
||||
}
|
||||
}
|
||||
|
||||
func AddListenerForEvent(evsw EventSwitch, id, event string, cb func(data TMEventData)) {
|
||||
evsw.AddListenerForEvent(id, event, func(data events.EventData) {
|
||||
cb(data.(TMEventData))
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
//--- block, tx, and vote events
|
||||
|
||||
func FireEventNewBlock(fireable events.Fireable, block EventDataNewBlock) {
|
||||
fireEvent(fireable, EventStringNewBlock(), TMEventData{block})
|
||||
}
|
||||
|
||||
func FireEventNewBlockHeader(fireable events.Fireable, header EventDataNewBlockHeader) {
|
||||
fireEvent(fireable, EventStringNewBlockHeader(), TMEventData{header})
|
||||
}
|
||||
|
||||
func FireEventVote(fireable events.Fireable, vote EventDataVote) {
|
||||
fireEvent(fireable, EventStringVote(), TMEventData{vote})
|
||||
}
|
||||
|
||||
func FireEventTx(fireable events.Fireable, tx EventDataTx) {
|
||||
fireEvent(fireable, EventStringTx(tx.Tx), TMEventData{tx})
|
||||
}
|
||||
|
||||
//--- EventDataRoundState events
|
||||
|
||||
func FireEventNewRoundStep(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringNewRoundStep(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventTimeoutPropose(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringTimeoutPropose(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventTimeoutWait(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringTimeoutWait(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventNewRound(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringNewRound(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventCompleteProposal(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringCompleteProposal(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventPolka(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringPolka(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventUnlock(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringUnlock(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventRelock(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringRelock(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventLock(fireable events.Fireable, rs EventDataRoundState) {
|
||||
fireEvent(fireable, EventStringLock(), TMEventData{rs})
|
||||
}
|
||||
|
||||
func FireEventProposalHeartbeat(fireable events.Fireable, rs EventDataProposalHeartbeat) {
|
||||
fireEvent(fireable, EventStringProposalHeartbeat(), TMEventData{rs})
|
||||
type TxEventPublisher interface {
|
||||
PublishEventTx(EventDataTx) error
|
||||
}
|
||||
|
77
types/nop_event_bus.go
Normal file
77
types/nop_event_bus.go
Normal file
@ -0,0 +1,77 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
tmpubsub "github.com/tendermint/tmlibs/pubsub"
|
||||
)
|
||||
|
||||
type NopEventBus struct{}
|
||||
|
||||
func (NopEventBus) Subscribe(ctx context.Context, subscriber string, query tmpubsub.Query, out chan<- interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) Unsubscribe(ctx context.Context, subscriber string, query tmpubsub.Query) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) UnsubscribeAll(ctx context.Context, subscriber string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//--- block, tx, and vote events
|
||||
|
||||
func (NopEventBus) PublishEventNewBlock(block EventDataNewBlock) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventNewBlockHeader(header EventDataNewBlockHeader) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventVote(vote EventDataVote) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventTx(tx EventDataTx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//--- EventDataRoundState events
|
||||
|
||||
func (NopEventBus) PublishEventNewRoundStep(rs EventDataRoundState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventTimeoutPropose(rs EventDataRoundState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventTimeoutWait(rs EventDataRoundState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventNewRound(rs EventDataRoundState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventCompleteProposal(rs EventDataRoundState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventPolka(rs EventDataRoundState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventUnlock(rs EventDataRoundState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventRelock(rs EventDataRoundState) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NopEventBus) PublishEventLock(rs EventDataRoundState) error {
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user