-
Notifications
You must be signed in to change notification settings - Fork 18
/
event.go
225 lines (186 loc) · 5.21 KB
/
event.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
package types
import (
"bytes"
"context"
"encoding/json"
"fmt"
"strings"
)
type WSClient interface {
SubscribeNewBlock(builder *EventQueryBuilder, handler EventNewBlockHandler) (Subscription, Error)
SubscribeTx(builder *EventQueryBuilder, handler EventTxHandler) (Subscription, Error)
SubscribeNewBlockHeader(handler EventNewBlockHeaderHandler) (Subscription, Error)
SubscribeValidatorSetUpdates(handler EventValidatorSetUpdatesHandler) (Subscription, Error)
Unsubscribe(subscription Subscription) Error
}
type TmClient interface {
ABCIClient
SignClient
WSClient
StatusClient
NetworkClient
}
type EventKey string
type EventValue string
type Subscription struct {
Ctx context.Context `json:"-"`
Query string `json:"query"`
ID string `json:"id"`
}
type EventHandler func(data EventData)
// EventData for SubscribeAny
type EventData interface{}
// EventDataTx for SubscribeTx
type EventDataTx struct {
Hash string `json:"hash"`
Height int64 `json:"height"`
Index uint32 `json:"index"`
Tx Tx `json:"tx"`
Result TxResult `json:"result"`
}
func (tx EventDataTx) MarshalJson() []byte {
bz, _ := json.Marshal(tx)
return bz
}
type TxResult struct {
Code uint32 `json:"code"`
Log string `json:"log"`
GasWanted int64 `json:"gas_wanted"`
GasUsed int64 `json:"gas_used"`
Events StringEvents `json:"events"`
}
type Attributes []Attribute
func (a Attributes) GetValues(key string) (values []string) {
for _, attr := range a {
if attr.Key == key {
values = append(values, attr.Value)
}
}
return
}
func (a Attributes) GetValue(key string) string {
for _, attr := range a {
if attr.Key == key {
return attr.Value
}
}
return ""
}
func (a Attributes) String() string {
var attrs = make([]string, len(a))
for i, attr := range a {
attrs[i] = fmt.Sprintf("%s=%s", attr.Key, attr.Value)
}
return strings.Join(attrs, ",")
}
type EventTxHandler func(EventDataTx)
//EventDataNewBlock for SubscribeNewBlock
type EventDataNewBlock struct {
Block Block `json:"block"`
ResultBeginBlock ResultBeginBlock `json:"result_begin_block"`
ResultEndBlock ResultEndBlock `json:"result_end_block"`
}
type ValidatorUpdate struct {
PubKey PubKey `json:"pub_key"`
Power int64 `json:"power"`
}
type PubKey struct {
Type string `json:"type"`
Value string `json:"value"`
}
type EventNewBlockHandler func(EventDataNewBlock)
//EventDataNewBlockHeader for SubscribeNewBlockHeader
type EventDataNewBlockHeader struct {
Header Header `json:"header"`
ResultBeginBlock ResultBeginBlock `json:"result_begin_block"`
ResultEndBlock ResultEndBlock `json:"result_end_block"`
}
type EventNewBlockHeaderHandler func(EventDataNewBlockHeader)
//EventDataValidatorSetUpdates for SubscribeValidatorSetUpdates
type Validator struct {
Bech32Address string `json:"bech32_address"`
Bech32PubKey string `json:"bech32_pubkey"`
Address string `json:"address"`
PubKey PubKey `json:"pub_key"`
VotingPower int64 `json:"voting_power"`
ProposerPriority int64 `json:"proposer_priority"`
}
type EventDataValidatorSetUpdates struct {
ValidatorUpdates []Validator `json:"validator_updates"`
}
type EventValidatorSetUpdatesHandler func(EventDataValidatorSetUpdates)
//EventQueryBuilder for build query string
type condition struct {
key EventKey
value EventValue
op string
}
// Cond return a condition object with a key
func Cond(key EventKey) *condition {
return &condition{
key: key,
}
}
// NewCond return a condition object with a complete event type and attrKey
func NewCond(typ, attrKey string) *condition {
return &condition{
key: EventKey(fmt.Sprintf("%s.%s", typ, attrKey)),
}
}
func (c *condition) LTE(v EventValue) *condition {
return c.fill(v, "<=")
}
func (c *condition) GTE(v EventValue) *condition {
return c.fill(v, ">=")
}
func (c *condition) LE(v EventValue) *condition {
return c.fill(v, "<")
}
func (c *condition) GE(v EventValue) *condition {
return c.fill(v, ">")
}
func (c *condition) EQ(v EventValue) *condition {
return c.fill(v, "=")
}
//func (c *condition) Contains(v EventValue) *condition {
// return c.fill(v, "CONTAINS")
//}
func (c *condition) fill(v EventValue, op string) *condition {
c.value = v
c.op = op
return c
}
func (c *condition) String() string {
if len(c.key) == 0 || len(c.value) == 0 || len(c.op) == 0 {
return ""
}
return fmt.Sprintf("%s %s '%s'", c.key, c.op, c.value)
}
//EventQueryBuilder is responsible for constructing listening conditions
type EventQueryBuilder struct {
conditions []string
}
func NewEventQueryBuilder() *EventQueryBuilder {
return &EventQueryBuilder{
conditions: []string{},
}
}
//AddCondition is responsible for adding listening conditions
func (eqb *EventQueryBuilder) AddCondition(c *condition) *EventQueryBuilder {
if c == nil {
return nil
}
eqb.conditions = append(eqb.conditions, c.String())
return eqb
}
//Build is responsible for constructing the listening condition into a listening instruction identified by tendermint
func (eqb *EventQueryBuilder) Build() string {
var buf bytes.Buffer
for _, condition := range eqb.conditions {
if buf.Len() > 0 {
buf.WriteString(" AND ")
}
buf.WriteString(condition)
}
return buf.String()
}