-
Notifications
You must be signed in to change notification settings - Fork 211
/
events.go
269 lines (247 loc) · 6.71 KB
/
events.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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
package events
import (
"time"
pb "github.com/spacemeshos/api/release/go/spacemesh/v1"
"google.golang.org/protobuf/types/known/durationpb"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/spacemeshos/go-spacemesh/codec"
"github.com/spacemeshos/go-spacemesh/common/types"
"github.com/spacemeshos/go-spacemesh/log"
)
type UserEvent struct {
Event *pb.Event
}
func EmitBeacon(epoch types.EpochID, beacon types.Beacon) {
const help = "Node computed randomness beacon, it will be used to determine eligibility to participate in the consensus."
emitUserEvent(
help,
false,
&pb.Event_Beacon{
Beacon: &pb.EventBeacon{
Epoch: epoch.Uint32(),
Beacon: beacon[:],
},
},
)
}
func EmitInitStart(smesher types.NodeID, commitment types.ATXID) {
const help = "Node started post data initialization. Note that init is noop if node restarted when init was ready."
emitUserEvent(
help,
false,
&pb.Event_InitStart{
InitStart: &pb.EventInitStart{
Smesher: smesher[:],
Commitment: commitment[:],
},
},
)
}
func EmitInitFailure(smesher types.NodeID, commitment types.ATXID, err error) {
const help = "Node failed post data initialization."
emitUserEvent(
help,
true,
&pb.Event_InitFailed{
InitFailed: &pb.EventInitFailed{
Smesher: smesher[:],
Commitment: commitment[:],
Error: err.Error(),
},
},
)
}
func EmitInitComplete() {
const help = "Node completed post data initialization."
emitUserEvent(
help,
false,
&pb.Event_InitComplete{
InitComplete: &pb.EventInitComplete{},
},
)
}
func EmitPoetWaitRound(current, publish types.EpochID, wait time.Duration) {
const help = "Node needs to wait for poet registration window in current epoch to open. " +
"Once opened it will submit challenge and wait till poet round ends in publish epoch."
emitUserEvent(
help,
false,
&pb.Event_PoetWaitRound{PoetWaitRound: &pb.EventPoetWaitRound{
Current: current.Uint32(),
Publish: publish.Uint32(),
Wait: durationpb.New(wait),
}},
)
}
type EventPoetWaitEnd struct {
Publish types.EpochID `json:"publish"`
Target types.EpochID `json:"target"`
Wait time.Duration `json:"wait"`
}
func EmitPoetWaitProof(publish, target types.EpochID, wait time.Duration) {
const help = "Node needs to wait for poet to complete in publish epoch. " +
"Once completed, node fetches proof from poet and runs post on that proof. " +
"After that publish an ATX that will be eligible for rewards in target epoch."
emitUserEvent(
help,
false,
&pb.Event_PoetWaitProof{
PoetWaitProof: &pb.EventPoetWaitProof{
Publish: publish.Uint32(),
Target: target.Uint32(),
Wait: durationpb.New(wait),
},
},
)
}
func EmitPostStart(challenge []byte) {
const help = "Node started post execution for the challenge from poet."
emitUserEvent(
help,
false,
&pb.Event_PostStart{PostStart: &pb.EventPostStart{Challenge: challenge}},
)
}
func EmitPostComplete(challenge []byte) {
const help = "Node finished post execution for challenge."
emitUserEvent(
help,
false,
&pb.Event_PostComplete{PostComplete: &pb.EventPostComplete{Challenge: challenge}},
)
}
func EmitPostFailure() {
const help = "Node failed post execution."
emitUserEvent(
help,
true,
&pb.Event_PostComplete{PostComplete: &pb.EventPostComplete{}},
)
}
func EmitInvalidPostProof() {
const help = "Node generated invalid POST proof. Please verify your POST data."
emitUserEvent(
help,
true,
&pb.Event_PostComplete{PostComplete: &pb.EventPostComplete{}},
)
}
func EmitAtxPublished(
current, target types.EpochID,
id types.ATXID,
wait time.Duration,
) {
const help = "Published activation for the current epoch. " +
"Node needs to wait till the start of the target epoch in order to be eligible for rewards."
emitUserEvent(
help,
false,
&pb.Event_AtxPublished{
AtxPublished: &pb.EventAtxPubished{
Current: current.Uint32(),
Target: target.Uint32(),
Id: id[:],
Wait: durationpb.New(wait),
},
},
)
}
func EmitEligibilities(
epoch types.EpochID,
beacon types.Beacon,
atx types.ATXID,
activeSetSize uint32,
eligibilities map[types.LayerID][]types.VotingEligibility,
) {
const help = "Computed eligibilities for the epoch. " +
"Rewards will be received after publishing proposals at specified layers. " +
"Total amount of rewards in SMH will be based on other participants in the layer."
emitUserEvent(
help,
false,
&pb.Event_Eligibilities{
Eligibilities: &pb.EventEligibilities{
Epoch: epoch.Uint32(),
Beacon: beacon[:],
Atx: atx[:],
ActiveSetSize: activeSetSize,
Eligibilities: castEligibilities(eligibilities),
},
},
)
}
func castEligibilities(proofs map[types.LayerID][]types.VotingEligibility) []*pb.ProposalEligibility {
rst := make([]*pb.ProposalEligibility, 0, len(proofs))
for lid, eligs := range proofs {
rst = append(rst, &pb.ProposalEligibility{
Layer: lid.Uint32(),
Count: uint32(len(eligs)),
})
}
return rst
}
func EmitProposal(layer types.LayerID, proposal types.ProposalID) {
const help = "Published proposal. Rewards will be received, once proposal is included into the block."
emitUserEvent(
help,
false,
&pb.Event_Proposal{
Proposal: &pb.EventProposal{
Layer: layer.Uint32(),
Proposal: proposal[:],
},
},
)
}
func EmitOwnMalfeasanceProof(id types.NodeID, mp *types.MalfeasanceProof) {
const help = "Committed malicious behavior. Identity will be canceled."
emitUserEvent(
help,
false,
&pb.Event_Malfeasance{
Malfeasance: &pb.EventMalfeasance{
Proof: ToMalfeasancePB(id, mp, false),
},
},
)
}
func emitUserEvent(help string, failure bool, details pb.IsEventDetails) {
mu.RLock()
defer mu.RUnlock()
if reporter != nil {
if err := reporter.emitUserEvent(UserEvent{Event: &pb.Event{
Timestamp: timestamppb.New(time.Now()),
Help: help,
Failure: failure,
Details: details,
}}); err != nil {
log.With().Error("failed to emit event", log.Err(err))
}
}
}
func ToMalfeasancePB(smesher types.NodeID, mp *types.MalfeasanceProof, includeProof bool) *pb.MalfeasanceProof {
if mp == nil {
return &pb.MalfeasanceProof{}
}
kind := pb.MalfeasanceProof_MALFEASANCE_UNSPECIFIED
switch mp.Proof.Type {
case types.MultipleATXs:
kind = pb.MalfeasanceProof_MALFEASANCE_ATX
case types.MultipleBallots:
kind = pb.MalfeasanceProof_MALFEASANCE_BALLOT
case types.HareEquivocation:
kind = pb.MalfeasanceProof_MALFEASANCE_HARE
}
result := &pb.MalfeasanceProof{
SmesherId: &pb.SmesherId{Id: smesher.Bytes()},
Layer: &pb.LayerNumber{Number: mp.Layer.Uint32()},
Kind: kind,
DebugInfo: types.MalfeasanceInfo(smesher, mp),
}
if includeProof {
data, _ := codec.Encode(mp)
result.Proof = data
}
return result
}