-
Notifications
You must be signed in to change notification settings - Fork 175
/
chunkFaults.go
173 lines (144 loc) · 5.88 KB
/
chunkFaults.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
package chunks
import (
"encoding/hex"
"fmt"
"github.com/onflow/flow-go/model/flow"
)
// ChunkFault holds information about a fault that is found while
// verifying a chunk
type ChunkFault interface {
ChunkIndex() uint64
ExecutionResultID() flow.Identifier
String() string
}
// CFMissingRegisterTouch is returned when a register touch is missing (read or update)
type CFMissingRegisterTouch struct {
regsterIDs []string
chunkIndex uint64
execResID flow.Identifier
txID flow.Identifier // very first transaction inside the chunk that required this register
}
func (cf CFMissingRegisterTouch) String() string {
hexStrings := make([]string, len(cf.regsterIDs))
for i, s := range cf.regsterIDs {
hexStrings[i] = hex.EncodeToString([]byte(s))
}
return fmt.Sprintf("at least one register touch was missing inside the chunk data package that was needed while running transactions of chunk %d of result %s (tx hash of one of them: %s), hex-encoded register ids: %s", cf.chunkIndex, cf.execResID.String(), cf.txID.String(), hexStrings)
}
// ChunkIndex returns chunk index of the faulty chunk
func (cf CFMissingRegisterTouch) ChunkIndex() uint64 {
return cf.chunkIndex
}
// ExecutionResultID returns the execution result identifier including the faulty chunk
func (cf CFMissingRegisterTouch) ExecutionResultID() flow.Identifier {
return cf.execResID
}
// NewCFMissingRegisterTouch creates a new instance of Chunk Fault (MissingRegisterTouch)
func NewCFMissingRegisterTouch(regsterIDs []string, chInx uint64, execResID flow.Identifier, txID flow.Identifier) *CFMissingRegisterTouch {
return &CFMissingRegisterTouch{regsterIDs: regsterIDs,
chunkIndex: chInx,
execResID: execResID,
txID: txID}
}
// CFNonMatchingFinalState is returned when the computed final state commitment
// (applying chunk register updates to the partial trie) doesn't match the one provided by the chunk
type CFNonMatchingFinalState struct {
expected flow.StateCommitment
computed flow.StateCommitment
chunkIndex uint64
execResID flow.Identifier
}
func (cf CFNonMatchingFinalState) String() string {
return fmt.Sprintf("final state commitment doesn't match, expected [%x] but computed [%x]", cf.expected, cf.computed)
}
// ChunkIndex returns chunk index of the faulty chunk
func (cf CFNonMatchingFinalState) ChunkIndex() uint64 {
return cf.chunkIndex
}
// ExecutionResultID returns the execution result identifier including the faulty chunk
func (cf CFNonMatchingFinalState) ExecutionResultID() flow.Identifier {
return cf.execResID
}
// NewCFNonMatchingFinalState creates a new instance of Chunk Fault (NonMatchingFinalState)
func NewCFNonMatchingFinalState(expected flow.StateCommitment, computed flow.StateCommitment, chInx uint64, execResID flow.Identifier) *CFNonMatchingFinalState {
return &CFNonMatchingFinalState{expected: expected,
computed: computed,
chunkIndex: chInx,
execResID: execResID}
}
// CFInvalidEventsCollection is returned when computed events collection hash is different from the chunk's one
type CFInvalidEventsCollection struct {
expected flow.Identifier
computed flow.Identifier
chunkIndex uint64
resultID flow.Identifier
}
func NewCFInvalidEventsCollection(expected flow.Identifier, computed flow.Identifier, chInx uint64, execResID flow.Identifier) *CFInvalidEventsCollection {
return &CFInvalidEventsCollection{
expected: expected,
computed: computed,
chunkIndex: chInx,
resultID: execResID,
}
}
func (c *CFInvalidEventsCollection) ChunkIndex() uint64 {
return c.chunkIndex
}
func (c *CFInvalidEventsCollection) ExecutionResultID() flow.Identifier {
return c.resultID
}
func (c *CFInvalidEventsCollection) String() string {
return fmt.Sprintf("events collection hash differs, got %x expected %x for chunk %d with result ID %s", c.computed, c.expected, c.chunkIndex, c.resultID)
}
// CFInvalidServiceEventsEmitted is returned when service events are different from the chunk's one
type CFInvalidServiceEventsEmitted struct {
expected flow.ServiceEventList
computed flow.ServiceEventList
chunkIndex uint64
resultID flow.Identifier
}
func CFInvalidServiceSystemEventsEmitted(expected flow.ServiceEventList, computed flow.ServiceEventList, chInx uint64, execResID flow.Identifier) *CFInvalidServiceEventsEmitted {
return &CFInvalidServiceEventsEmitted{
expected: expected,
computed: computed,
chunkIndex: chInx,
resultID: execResID,
}
}
func (c *CFInvalidServiceEventsEmitted) ChunkIndex() uint64 {
return c.chunkIndex
}
func (c *CFInvalidServiceEventsEmitted) ExecutionResultID() flow.Identifier {
return c.resultID
}
func (c *CFInvalidServiceEventsEmitted) String() string {
return fmt.Sprintf("service events differs, got [%s] expected [%s] for chunk %d with result ID %s", c.computed, c.expected, c.chunkIndex, c.resultID)
}
// CFInvalidVerifiableChunk is returned when a verifiable chunk is invalid
// this includes cases that code fails to construct a partial trie,
// collection hashes doesn't match
// TODO break this into more detailed ones as we progress
type CFInvalidVerifiableChunk struct {
reason string
details error
chunkIndex uint64
execResID flow.Identifier
}
func (cf CFInvalidVerifiableChunk) String() string {
return fmt.Sprint("invalid verifiable chunk due to ", cf.reason, cf.details.Error())
}
// ChunkIndex returns chunk index of the faulty chunk
func (cf CFInvalidVerifiableChunk) ChunkIndex() uint64 {
return cf.chunkIndex
}
// ExecutionResultID returns the execution result identifier including the faulty chunk
func (cf CFInvalidVerifiableChunk) ExecutionResultID() flow.Identifier {
return cf.execResID
}
// NewCFInvalidVerifiableChunk creates a new instance of Chunk Fault (InvalidVerifiableChunk)
func NewCFInvalidVerifiableChunk(reason string, err error, chInx uint64, execResID flow.Identifier) *CFInvalidVerifiableChunk {
return &CFInvalidVerifiableChunk{reason: reason,
details: err,
chunkIndex: chInx,
execResID: execResID}
}