@@ -15,6 +15,7 @@ import (
15
15
"github.com/onflow/flow-go/module/metrics"
16
16
"github.com/onflow/flow-go/module/signature"
17
17
"github.com/onflow/flow-go/module/trace"
18
+ "github.com/onflow/flow-go/state/cluster"
18
19
"github.com/onflow/flow-go/state/protocol"
19
20
mockprotocol "github.com/onflow/flow-go/state/protocol/mock"
20
21
mockstorage "github.com/onflow/flow-go/storage/mock"
@@ -37,6 +38,9 @@ type IngestionCoreSuite struct {
37
38
38
39
finalIdentities flow.IdentityList // identities at finalized state
39
40
refIdentities flow.IdentityList // identities at reference block state
41
+ epochCounter uint64 // epoch for the cluster originating the guarantee
42
+ clusterMembers flow.IdentityList // members of the cluster originating the guarantee
43
+ clusterID flow.ChainID // chain ID of the cluster originating the guarantee
40
44
41
45
final * mockprotocol.Snapshot // finalized state snapshot
42
46
ref * mockprotocol.Snapshot // state snapshot w.r.t. reference block
@@ -66,7 +70,9 @@ func (suite *IngestionCoreSuite) SetupTest() {
66
70
suite .execID = exec .NodeID
67
71
suite .verifID = verif .NodeID
68
72
69
- clusters := flow.IdentityList {coll }
73
+ suite .epochCounter = 1
74
+ suite .clusterMembers = flow.IdentityList {coll }
75
+ suite .clusterID = cluster .CanonicalClusterID (suite .epochCounter , suite .clusterMembers .NodeIDs ())
70
76
71
77
identities := flow.IdentityList {access , con , coll , exec , verif }
72
78
suite .finalIdentities = identities .Copy ()
@@ -109,8 +115,20 @@ func (suite *IngestionCoreSuite) SetupTest() {
109
115
)
110
116
ref .On ("Epochs" ).Return (suite .query )
111
117
suite .query .On ("Current" ).Return (suite .epoch )
112
- cluster .On ("Members" ).Return (clusters )
113
- suite .epoch .On ("ClusterByChainID" , head .ChainID ).Return (cluster , nil )
118
+ cluster .On ("Members" ).Return (suite .clusterMembers )
119
+ suite .epoch .On ("ClusterByChainID" , mock .Anything ).Return (
120
+ func (chainID flow.ChainID ) protocol.Cluster {
121
+ if chainID == suite .clusterID {
122
+ return cluster
123
+ }
124
+ return nil
125
+ },
126
+ func (chainID flow.ChainID ) error {
127
+ if chainID == suite .clusterID {
128
+ return nil
129
+ }
130
+ return protocol .ErrClusterNotFound
131
+ })
114
132
115
133
state .On ("AtBlockID" , mock .Anything ).Return (ref )
116
134
ref .On ("Identity" , mock .Anything ).Return (
@@ -234,7 +252,23 @@ func (suite *IngestionCoreSuite) TestOnGuaranteeExpired() {
234
252
err := suite .core .OnGuarantee (suite .collID , guarantee )
235
253
suite .Assert ().Error (err , "should error with expired collection" )
236
254
suite .Assert ().True (engine .IsOutdatedInputError (err ))
255
+ }
256
+
257
+ // TestOnGuaranteeReferenceBlockFromWrongEpoch validates that guarantees which contain a ChainID
258
+ // that is inconsistent with the reference block (ie. the ChainID either refers to a non-existent
259
+ // cluster, or a cluster for a different epoch) should be considered invalid inputs.
260
+ func (suite * IngestionCoreSuite ) TestOnGuaranteeReferenceBlockFromWrongEpoch () {
261
+ // create a guarantee from a cluster in a different epoch
262
+ guarantee := suite .validGuarantee ()
263
+ guarantee .ChainID = cluster .CanonicalClusterID (suite .epochCounter + 1 , suite .clusterMembers .NodeIDs ())
237
264
265
+ // the guarantee is not part of the memory pool
266
+ suite .pool .On ("Has" , guarantee .ID ()).Return (false )
267
+
268
+ // submit the guarantee as if it was sent by a collection node
269
+ err := suite .core .OnGuarantee (suite .collID , guarantee )
270
+ suite .Assert ().Error (err , "should error with expired collection" )
271
+ suite .Assert ().True (engine .IsInvalidInputError (err ))
238
272
}
239
273
240
274
// TestOnGuaranteeInvalidGuarantor verifiers that collections with any _unknown_
@@ -306,7 +340,7 @@ func (suite *IngestionCoreSuite) TestOnGuaranteeUnknownOrigin() {
306
340
// validGuarantee returns a valid collection guarantee based on the suite state.
307
341
func (suite * IngestionCoreSuite ) validGuarantee () * flow.CollectionGuarantee {
308
342
guarantee := unittest .CollectionGuaranteeFixture ()
309
- guarantee .ChainID = suite .head . ChainID
343
+ guarantee .ChainID = suite .clusterID
310
344
311
345
signerIndices , err := signature .EncodeSignersToIndices (
312
346
[]flow.Identifier {suite .collID }, []flow.Identifier {suite .collID })
0 commit comments