-
Notifications
You must be signed in to change notification settings - Fork 672
/
engine.go
313 lines (281 loc) · 12.1 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
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package common
import (
"github.com/ava-labs/avalanchego/health"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/avalanchego/snow"
)
// Engine describes the standard interface of a consensus engine
type Engine interface {
Handler
// Return the context of the chain this engine is working on
Context() *snow.Context
// Returns true iff the chain is done bootstrapping
IsBootstrapped() bool
// Returns nil if the engine is healthy.
// Periodically called and reported through the health API
health.Checkable
// GetVM returns this engine's VM
GetVM() VM
}
// Handler defines the functions that are acted on the node
type Handler interface {
ExternalHandler
InternalHandler
}
// ExternalHandler defines how a consensus engine reacts to messages and
// requests from other validators
type ExternalHandler interface {
FrontierHandler
AcceptedHandler
FetchHandler
QueryHandler
}
// FrontierHandler defines how a consensus engine reacts to frontier messages
// from other validators. Returned errors should be treated as fatal and require
// the chain to shutdown.
type FrontierHandler interface {
// Notify this engine of a request for the accepted frontier of vertices.
//
// The accepted frontier is the set of accepted vertices that do not have
// any accepted descendants.
//
// This function can be called by any validator. It is not safe to assume
// this message is utilizing a unique requestID. However, the validatorID is
// assumed to be authenticated.
//
// This engine should respond with an AcceptedFrontier message with the same
// requestID, and the engine's current accepted frontier.
GetAcceptedFrontier(validatorID ids.ShortID, requestID uint32) error
// Notify this engine of an accepted frontier.
//
// This function can be called by any validator. It is not safe to assume
// this message is in response to a GetAcceptedFrontier message, is
// utilizing a unique requestID, or that the containerIDs from a valid
// frontier. However, the validatorID is assumed to be authenticated.
AcceptedFrontier(
validatorID ids.ShortID,
requestID uint32,
containerIDs []ids.ID,
) error
// Notify this engine that a get accepted frontier request it issued has
// failed.
//
// This function will be called if the engine sent a GetAcceptedFrontier
// message that is not anticipated to be responded to. This could be because
// the recipient of the message is unknown or if the message request has
// timed out.
//
// The validatorID, and requestID, are assumed to be the same as those sent
// in the GetAcceptedFrontier message.
GetAcceptedFrontierFailed(validatorID ids.ShortID, requestID uint32) error
}
// AcceptedHandler defines how a consensus engine reacts to messages pertaining
// to accepted containers from other validators. Functions only return fatal
// errors if they occur.
type AcceptedHandler interface {
// Notify this engine of a request to filter non-accepted vertices.
//
// This function can be called by any validator. It is not safe to assume
// this message is utilizing a unique requestID. However, the validatorID is
// assumed to be authenticated.
//
// This engine should respond with an Accepted message with the same
// requestID, and the subset of the containerIDs that this node has decided
// are accepted.
GetAccepted(
validatorID ids.ShortID,
requestID uint32,
containerIDs []ids.ID,
) error
// Notify this engine of a set of accepted vertices.
//
// This function can be called by any validator. It is not safe to assume
// this message is in response to a GetAccepted message, is utilizing a
// unique requestID, or that the containerIDs are a subset of the
// containerIDs from a GetAccepted message. However, the validatorID is
// assumed to be authenticated.
Accepted(
validatorID ids.ShortID,
requestID uint32,
containerIDs []ids.ID,
) error
// Notify this engine that a get accepted request it issued has failed.
//
// This function will be called if the engine sent a GetAccepted message
// that is not anticipated to be responded to. This could be because the
// recipient of the message is unknown or if the message request has timed
// out.
//
// The validatorID, and requestID, are assumed to be the same as those sent
// in the GetAccepted message.
GetAcceptedFailed(validatorID ids.ShortID, requestID uint32) error
}
// FetchHandler defines how a consensus engine reacts to retrieval messages from
// other validators. Functions only return fatal errors if they occur.
type FetchHandler interface {
// Notify this engine of a request for a container.
//
// This function can be called by any validator. It is not safe to assume
// this message is utilizing a unique requestID. It is also not safe to
// assume the requested containerID exists. However, the validatorID is
// assumed to be authenticated.
//
// There should never be a situation where a virtuous node sends a Get
// request to another virtuous node that does not have the requested
// container. Unless that container was pruned from the active set.
//
// This engine should respond with a Put message with the same requestID if
// the container was locally available. Otherwise, the message can be safely
// dropped.
Get(validatorID ids.ShortID, requestID uint32, containerID ids.ID) error
// Notify this engine of a request for a container and its ancestors.
// The request is from validator [validatorID]. The requested container is [containerID].
//
// This function can be called by any validator. It is not safe to assume
// this message is utilizing a unique requestID. It is also not safe to
// assume the requested containerID exists. However, the validatorID is
// assumed to be authenticated.
//
// This engine should respond with a MultiPut message with the same requestID,
// which contains [containerID] as well as its ancestors. See MultiPut's documentation.
//
// If this engine doesn't have some ancestors, it should reply with its best effort attempt at getting them.
// If this engine doesn't have [containerID] it can ignore this message.
GetAncestors(validatorID ids.ShortID, requestID uint32, containerID ids.ID) error
// Notify this engine of a container.
//
// This function can be called by any validator. It is not safe to assume
// this message is utilizing a unique requestID or even that the containerID
// matches the ID of the container bytes. However, the validatorID is
// assumed to be authenticated.
//
// This engine needs to request and receive missing ancestors of the
// container before adding the container to consensus. Once all ancestor
// containers are added, pushes the container into the consensus.
Put(
validatorID ids.ShortID,
requestID uint32,
containerID ids.ID,
container []byte,
) error
// Notify this engine of multiple containers.
// Each element of [containers] is the byte representation of a container.
//
// This should only be called during bootstrapping, and in response to a GetAncestors message to
// [validatorID] with request ID [requestID]. This call should contain the container requested in
// that message, along with ancestors.
// The containers should be in BFS order (ie the first container must be the container
// requested in the GetAncestors message and further back ancestors are later in [containers]
//
// It is not safe to assume this message is in response to a GetAncestor message, that this
// message has a unique requestID or that any of the containers in [containers] are valid.
// However, the validatorID is assumed to be authenticated.
MultiPut(
validatorID ids.ShortID,
requestID uint32,
containers [][]byte,
) error
// Notify this engine that a get request it issued has failed.
//
// This function will be called if the engine sent a Get message that is not
// anticipated to be responded to. This could be because the recipient of
// the message is unknown or if the message request has timed out.
//
// The validatorID and requestID are assumed to be the same as those sent in
// the Get message.
GetFailed(validatorID ids.ShortID, requestID uint32) error
// Notify this engine that a GetAncestors request it issued has failed.
//
// This function will be called if the engine sent a GetAncestors message that is not
// anticipated to be responded to. This could be because the recipient of
// the message is unknown or if the message request has timed out.
//
// The validatorID and requestID are assumed to be the same as those sent in
// the GetAncestors message.
GetAncestorsFailed(validatorID ids.ShortID, requestID uint32) error
}
// QueryHandler defines how a consensus engine reacts to query messages from
// other validators. Functions only return fatal errors if they occur.
type QueryHandler interface {
// Notify this engine of a request for our preferences.
//
// This function can be called by any validator. It is not safe to assume
// this message is utilizing a unique requestID. However, the validatorID is
// assumed to be authenticated.
//
// If the container or its ancestry is incomplete, this engine is expected
// to request the missing containers from the validator. Once the ancestry
// is complete, this engine should send this validator the current
// preferences in a Chits message. The Chits message should have the same
// requestID that was passed in here.
PullQuery(
validatorID ids.ShortID,
requestID uint32,
containerID ids.ID,
) error
// Notify this engine of a request for our preferences.
//
// This function can be called by any validator. It is not safe to assume
// this message is utilizing a unique requestID or even that the containerID
// matches the ID of the container bytes. However, the validatorID is
// assumed to be authenticated.
//
// This function is meant to behave the same way as PullQuery, except the
// container is optimistically provided to potentially remove the need for
// a series of Get/Put messages.
//
// If the ancestry of the container is incomplete, this engine is expected
// to request the ancestry from the validator. Once the ancestry is
// complete, this engine should send this validator the current preferences
// in a Chits message. The Chits message should have the same requestID that
// was passed in here.
PushQuery(
validatorID ids.ShortID,
requestID uint32,
containerID ids.ID,
container []byte,
) error
// Notify this engine of the specified validators preferences.
//
// This function can be called by any validator. It is not safe to assume
// this message is in response to a PullQuery or a PushQuery message.
// However, the validatorID is assumed to be authenticated.
Chits(validatorID ids.ShortID, requestID uint32, containerIDs []ids.ID) error
// Notify this engine that a query it issued has failed.
//
// This function will be called if the engine sent a PullQuery or PushQuery
// message that is not anticipated to be responded to. This could be because
// the recipient of the message is unknown or if the message request has
// timed out.
//
// The validatorID and the requestID are assumed to be the same as those
// sent in the Query message.
QueryFailed(validatorID ids.ShortID, requestID uint32) error
}
// InternalHandler defines how this consensus engine reacts to messages from
// other components of this validator. Functions only return fatal errors if
// they occur.
type InternalHandler interface {
// Notify this engine that a registered timeout has fired.
Timeout() error
// Gossip to the network a container on the accepted frontier
Gossip() error
// Halt this engine.
//
// This function will be called before the environment starts exiting. This
// function is slightly special, in that it does not expect the chain's
// context lock to be held before calling this function.
Halt()
// Shutdown this engine.
//
// This function will be called when the environment is exiting.
Shutdown() error
// Notify this engine of a message from the virtual machine.
Notify(Message) error
// Notify this engine of a new peer.
Connected(validatorID ids.ShortID) error
// Notify this engine of a removed peer.
Disconnected(validatorID ids.ShortID) error
}