Newer
Older
package event
import (
"fmt"
exe_events "github.com/hyperledger/burrow/execution/events"
evm_events "github.com/hyperledger/burrow/execution/evm/events"
"github.com/tendermint/go-wire/data"
tm_types "github.com/tendermint/tendermint/types"
)
// Oh for a real sum type
// AnyEventData provides a single type for our multiplexed event categories of EVM events and Tendermint events
type AnyEventData struct {
TMEventData *tm_types.TMEventData `json:",omitempty"`
BurrowEventData *EventData `json:",omitempty"`
Err *string `json:",omitempty"`
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
}
type EventData struct {
EventDataInner `json:"unwrap"`
}
type EventDataInner interface {
}
func (ed EventData) Unwrap() EventDataInner {
return ed.EventDataInner
}
func (ed EventData) MarshalJSON() ([]byte, error) {
return mapper.ToJSON(ed.EventDataInner)
}
func (ed *EventData) UnmarshalJSON(data []byte) (err error) {
parsed, err := mapper.FromJSON(data)
if err == nil && parsed != nil {
ed.EventDataInner = parsed.(EventDataInner)
}
return err
}
var mapper = data.NewMapper(EventData{}).
RegisterImplementation(exe_events.EventDataTx{}, "event_data_tx", biota()).
RegisterImplementation(evm_events.EventDataCall{}, "event_data_call", biota()).
RegisterImplementation(evm_events.EventDataLog{}, "event_data_log", biota())
// Get whichever element of the AnyEventData sum type that is not nil
func (aed AnyEventData) Get() interface{} {
if aed.TMEventData != nil {
return aed.TMEventData.Unwrap()
}
if aed.BurrowEventData != nil {
return aed.BurrowEventData.Unwrap()
}
if aed.Err != nil {
return *aed.Err
}
return nil
}
// If this AnyEventData wraps an EventDataNewBlock then return a pointer to that value, else return nil
func (aed AnyEventData) EventDataNewBlock() *tm_types.EventDataNewBlock {
if aed.TMEventData != nil {
eventData, _ := aed.TMEventData.Unwrap().(tm_types.EventDataNewBlock)
return &eventData
}
return nil
}
// If this AnyEventData wraps an EventDataLog then return a pointer to that value, else return nil
func (aed AnyEventData) EventDataLog() *evm_events.EventDataLog {
if aed.BurrowEventData != nil {
eventData, _ := aed.BurrowEventData.Unwrap().(evm_events.EventDataLog)
return &eventData
}
return nil
}
// If this AnyEventData wraps an EventDataCall then return a pointer to that value, else return nil
func (aed AnyEventData) EventDataCall() *evm_events.EventDataCall {
if aed.BurrowEventData != nil {
eventData, _ := aed.BurrowEventData.Unwrap().(evm_events.EventDataCall)
return &eventData
}
return nil
}
// If this AnyEventData wraps an EventDataTx then return a pointer to that value, else return nil
func (aed AnyEventData) EventDataTx() *exe_events.EventDataTx {
if aed.BurrowEventData != nil {
eventData, _ := aed.BurrowEventData.Unwrap().(exe_events.EventDataTx)
return &eventData
}
return nil
}
func (aed AnyEventData) Error() string {
if aed.Err == nil {
return ""
}
return *aed.Err
}
// Map any supported event data element to our AnyEventData sum type
func MapToAnyEventData(eventData interface{}) AnyEventData {
switch ed := eventData.(type) {
case AnyEventData:
return ed
case tm_types.TMEventData:
return AnyEventData{TMEventData: &ed}
case EventData:
return AnyEventData{BurrowEventData: &ed}
case EventDataInner:
return AnyEventData{BurrowEventData: &EventData{
EventDataInner: ed,
}}
default:
errStr := fmt.Sprintf("could not map event data of type %T to AnyEventData", eventData)
return AnyEventData{Err: &errStr}
}
}
// Type byte helper
var nextByte byte = 1
func biota() (b byte) {
b = nextByte
nextByte++
return
}