-
Notifications
You must be signed in to change notification settings - Fork 664
/
engine.go
503 lines (456 loc) · 13.7 KB
/
engine.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
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
// Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package common
import (
"context"
"time"
"github.com/ava-labs/avalanchego/api/health"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/snow"
"github.com/ava-labs/avalanchego/snow/validators"
"github.com/ava-labs/avalanchego/utils/set"
)
// Engine describes the standard interface of a consensus engine.
//
// All nodeIDs are assumed to be authenticated.
//
// A consensus engine may recover after returning an error, but it isn't
// required.
type Engine interface {
Handler
// Return the context of the chain this engine is working on
Context() *snow.ConsensusContext
// Start engine operations from given request ID
Start(ctx context.Context, startReqID uint32) error
// Returns nil if the engine is healthy.
// Periodically called and reported through the health API
health.Checker
}
type Handler interface {
AllGetsServer
StateSummaryFrontierHandler
AcceptedStateSummaryHandler
AcceptedFrontierHandler
AcceptedHandler
AncestorsHandler
PutHandler
QueryHandler
ChitsHandler
AppHandler
InternalHandler
}
type AllGetsServer interface {
GetStateSummaryFrontierHandler
GetAcceptedStateSummaryHandler
GetAcceptedFrontierHandler
GetAcceptedHandler
GetAncestorsHandler
GetHandler
}
type GetStateSummaryFrontierHandler interface {
// Notify this engine of a request for a StateSummaryFrontier message with
// the same requestID and the engine's most recently accepted state summary.
//
// This function can be called by any node at any time.
GetStateSummaryFrontier(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
) error
}
type StateSummaryFrontierHandler interface {
// Notify this engine of the response to a previously sent
// GetStateSummaryFrontier message with the same requestID.
//
// It is not guaranteed that the summary bytes are from a valid state
// summary.
StateSummaryFrontier(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
summary []byte,
) error
// Notify this engine that a GetStateSummaryFrontier request it issued has
// failed.
//
// This function will be called if a GetStateSummaryFrontier message with
// nodeID and requestID was previously sent by this engine and will not
// receive a response.
GetStateSummaryFrontierFailed(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
) error
}
type GetAcceptedStateSummaryHandler interface {
// Notify this engine of a request for an AcceptedStateSummary message with
// the same requestID and the state summary IDs at the requested heights.
// If this node doesn't have access to a state summary ID at a requested
// height, that height should be ignored.
//
// This function can be called by any node at any time.
GetAcceptedStateSummary(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
heights set.Set[uint64],
) error
}
type AcceptedStateSummaryHandler interface {
// Notify this engine of the response to a previously sent
// GetAcceptedStateSummary message with the same requestID.
//
// It is not guaranteed that the summaryIDs have heights corresponding to
// the heights in the request.
AcceptedStateSummary(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
summaryIDs set.Set[ids.ID],
) error
// Notify this engine that a GetAcceptedStateSummary request it issued has
// failed.
//
// This function will be called if a GetAcceptedStateSummary message with
// nodeID and requestID was previously sent by this engine and will not
// receive a response.
GetAcceptedStateSummaryFailed(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
) error
}
type GetAcceptedFrontierHandler interface {
// Notify this engine of a request for an AcceptedFrontier message with the
// same requestID and the ID of the most recently accepted container.
//
// This function can be called by any node at any time.
GetAcceptedFrontier(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
) error
}
type AcceptedFrontierHandler interface {
// Notify this engine of the response to a previously sent
// GetAcceptedFrontier message with the same requestID.
AcceptedFrontier(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
containerID ids.ID,
) error
// Notify this engine that a GetAcceptedFrontier request it issued has
// failed.
//
// This function will be called if a GetAcceptedFrontier message with
// nodeID and requestID was previously sent by this engine and will not
// receive a response.
GetAcceptedFrontierFailed(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
) error
}
type GetAcceptedHandler interface {
// Notify this engine of a request for an Accepted message with the same
// requestID and the subset of containerIDs that this node has accepted.
//
// This function can be called by any node at any time.
GetAccepted(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
containerIDs set.Set[ids.ID],
) error
}
type AcceptedHandler interface {
// Notify this engine of the response to a previously sent GetAccepted
// message with the same requestID.
//
// It is not guaranteed that the containerIDs are a subset of the
// containerIDs provided in the request.
Accepted(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
containerIDs set.Set[ids.ID],
) error
// Notify this engine that a GetAccepted request it issued has failed.
//
// This function will be called if a GetAccepted message with nodeID and
// requestID was previously sent by this engine and will not receive a
// response.
GetAcceptedFailed(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
) error
}
type GetAncestorsHandler interface {
// Notify this engine of a request for an Ancestors message with the same
// requestID, containerID, and some of its ancestors on a best effort basis.
//
// This function can be called by any node at any time.
GetAncestors(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
containerID ids.ID,
) error
}
type AncestorsHandler interface {
// Notify this engine of the response to a previously sent GetAncestors
// message with the same requestID.
//
// It is expected, but not guaranteed, that the first element in containers
// should be the container referenced in the request and that the rest of
// the containers should be referenced by a prior container in the list.
Ancestors(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
containers [][]byte,
) error
// Notify this engine that a GetAncestors request it issued has failed.
//
// This function will be called if a GetAncestors message with nodeID and
// requestID was previously sent by this engine and will not receive a
// response.
GetAncestorsFailed(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
) error
}
type GetHandler interface {
// Notify this engine of a request for a Put message with the same requestID
// and the container whose ID is containerID.
//
// This function can be called by any node at any time.
Get(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
containerID ids.ID,
) error
}
type PutHandler interface {
// Notify this engine of either the response to a previously sent Get
// message with the same requestID or an unsolicited container if the
// requestID is MaxUint32.
//
// It is not guaranteed that container can be parsed or issued.
Put(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
container []byte,
) error
// Notify this engine that a Get request it issued has failed.
//
// This function will be called if a Get message with nodeID and requestID
// was previously sent by this engine and will not receive a response.
GetFailed(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
) error
}
type QueryHandler interface {
// Notify this engine of a request for a Chits message with the same
// requestID.
//
// If the provided containerID is not processing, the engine is expected to
// respond with the node's current preferences before attempting to issue
// it.
//
// This function can be called by any node at any time.
PullQuery(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
containerID ids.ID,
requestedHeight uint64,
) error
// Notify this engine of a request for a Chits message with the same
// requestID.
//
// If the provided container is not processing, the engine is expected to
// respond with the node's current preferences before attempting to issue
// it.
//
// It is not guaranteed that container can be parsed or issued.
//
// This function can be called by any node at any time.
PushQuery(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
container []byte,
requestedHeight uint64,
) error
}
type ChitsHandler interface {
// Notify this engine of the response to a previously sent PullQuery or
// PushQuery message with the same requestID.
//
// It is expected, but not guaranteed, that preferredID transitively
// references preferredIDAtHeight and acceptedID.
Chits(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
preferredID ids.ID,
preferredIDAtHeight ids.ID,
acceptedID ids.ID,
) error
// Notify this engine that a Query request it issued has failed.
//
// This function will be called if a PullQuery or PushQuery message with
// nodeID and requestID was previously sent by this engine and will not
// receive a response.
QueryFailed(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
) error
}
type NetworkAppHandler interface {
AppRequestHandler
AppResponseHandler
AppGossipHandler
}
type AppRequestHandler interface {
// Notify this engine of a request for an AppResponse with the same
// requestID.
//
// The meaning of request, and what should be sent in response to it, is
// application (VM) specific.
//
// It is not guaranteed that request is well-formed or valid.
//
// This function can be called by any node at any time.
AppRequest(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
deadline time.Time,
request []byte,
) error
}
type AppResponseHandler interface {
// Notify this engine of the response to a previously sent AppRequest with
// the same requestID.
//
// The meaning of response is application (VM) specifc.
//
// It is not guaranteed that response is well-formed or valid.
AppResponse(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
response []byte,
) error
// Notify this engine that an AppRequest it issued has failed.
//
// This function will be called if an AppRequest message with nodeID and
// requestID was previously sent by this engine and will not receive a
// response.
AppRequestFailed(
ctx context.Context,
nodeID ids.NodeID,
requestID uint32,
appErr *AppError,
) error
}
type AppGossipHandler interface {
// Notify this engine of a gossip message from nodeID.
//
// The meaning of msg is application (VM) specific, and the VM defines how
// to react to this message.
//
// This message is not expected in response to any event, and it does not
// need to be responded to.
AppGossip(
ctx context.Context,
nodeID ids.NodeID,
msg []byte,
) error
}
type CrossChainAppHandler interface {
CrossChainAppRequestHandler
CrossChainAppResponseHandler
}
type CrossChainAppRequestHandler interface {
// Notify this engine of a request for a CrossChainAppResponse with the same
// requestID.
//
// The meaning of request, and what should be sent in response to it, is
// application (VM) specific.
//
// Guarantees surrounding the request are specific to the implementation of
// the requesting VM. For example, the request may or may not be guaranteed
// to be well-formed/valid depending on the implementation of the requesting
// VM.
CrossChainAppRequest(
ctx context.Context,
chainID ids.ID,
requestID uint32,
deadline time.Time,
request []byte,
) error
}
type CrossChainAppResponseHandler interface {
// Notify this engine of the response to a previously sent
// CrossChainAppRequest with the same requestID.
//
// The meaning of response is application (VM) specifc.
//
// Guarantees surrounding the response are specific to the implementation of
// the responding VM. For example, the response may or may not be guaranteed
// to be well-formed/valid depending on the implementation of the requesting
// VM.
CrossChainAppResponse(
ctx context.Context,
chainID ids.ID,
requestID uint32,
response []byte,
) error
// Notify this engine that a CrossChainAppRequest it issued has failed.
//
// This function will be called if a CrossChainAppRequest message with
// nodeID and requestID was previously sent by this engine and will not
// receive a response.
CrossChainAppRequestFailed(
ctx context.Context,
chainID ids.ID,
requestID uint32,
appErr *AppError,
) error
}
type AppHandler interface {
NetworkAppHandler
CrossChainAppHandler
}
type InternalHandler interface {
// Notify this engine of peer changes.
validators.Connector
// Notify this engine that a registered timeout has fired.
Timeout(context.Context) error
// Gossip to the network a container on the accepted frontier
Gossip(context.Context) error
// Halt this engine.
//
// This function will be called before the environment starts exiting. This
// function is special, in that it does not expect the chain's context lock
// to be held before calling this function. This function also does not
// require the engine to have been started.
Halt(context.Context)
// Shutdown this engine.
//
// This function will be called when the environment is exiting.
Shutdown(context.Context) error
// Notify this engine of a message from the virtual machine.
Notify(context.Context, Message) error
}