@@ -241,14 +241,50 @@ func (vscc *ValidatorOneValidSignature) checkInstantiationPolicy(chainName strin
241
241
return nil
242
242
}
243
243
244
- // validateDeployRWSetAndCollection performs validation of the rwset
244
+ func validateNewCollectionConfigs (newCollectionConfigs []* common.CollectionConfig ) error {
245
+ newCollectionsMap := make (map [string ]bool , len (newCollectionConfigs ))
246
+ // Process each collection config from a set of collection configs
247
+ for _ , newCollectionConfig := range newCollectionConfigs {
248
+
249
+ newCollection := newCollectionConfig .GetStaticCollectionConfig ()
250
+ if newCollection == nil {
251
+ return fmt .Errorf ("unknown collection configuration type" )
252
+ }
253
+
254
+ // Ensure that there are no duplicate collection names
255
+ collectionName := newCollection .GetName ()
256
+ if _ , ok := newCollectionsMap [collectionName ]; ! ok {
257
+ newCollectionsMap [collectionName ] = true
258
+ } else {
259
+ return fmt .Errorf ("collection-name: %s -- found duplicate collection configuration" , collectionName )
260
+ }
261
+
262
+ // Validate gossip related parameters present in the collection config
263
+ maximumPeerCount := newCollection .GetMaximumPeerCount ()
264
+ requiredPeerCount := newCollection .GetRequiredPeerCount ()
265
+ if maximumPeerCount < requiredPeerCount {
266
+ return fmt .Errorf ("collection-name: %s -- maximum peer count (%d) cannot be greater than the required peer count (%d)" ,
267
+ collectionName , maximumPeerCount , requiredPeerCount )
268
+ }
269
+ if requiredPeerCount < 0 {
270
+ return fmt .Errorf ("collection-name: %s -- requiredPeerCount (%d) cannot be lesser than zero (%d)" ,
271
+ collectionName , maximumPeerCount , requiredPeerCount )
272
+
273
+ }
274
+ }
275
+ return nil
276
+ }
277
+
278
+ // validateRWSetAndCollection performs validation of the rwset
245
279
// of an LSCC deploy operation and then it validates any collection
246
280
// configuration
247
- func (vscc * ValidatorOneValidSignature ) validateDeployRWSetAndCollection (
281
+ func (vscc * ValidatorOneValidSignature ) validateRWSetAndCollection (
248
282
lsccrwset * kvrwset.KVRWSet ,
249
283
cdRWSet * ccprovider.ChaincodeData ,
250
284
lsccArgs [][]byte ,
251
- chid , ccid string ,
285
+ lsccFunc string ,
286
+ ac channelconfig.ApplicationCapabilities ,
287
+ channelName string ,
252
288
) error {
253
289
/********************************************/
254
290
/* security check 0.a - validation of rwset */
@@ -261,9 +297,9 @@ func (vscc *ValidatorOneValidSignature) validateDeployRWSetAndCollection(
261
297
/**********************************************************/
262
298
/* security check 0.b - validation of the collection data */
263
299
/**********************************************************/
264
- var collectionsConfigArgs []byte
300
+ var collectionsConfigArg []byte
265
301
if len (lsccArgs ) > 5 {
266
- collectionsConfigArgs = lsccArgs [5 ]
302
+ collectionsConfigArg = lsccArgs [5 ]
267
303
}
268
304
269
305
var collectionsConfigLedger []byte
@@ -277,32 +313,48 @@ func (vscc *ValidatorOneValidSignature) validateDeployRWSetAndCollection(
277
313
collectionsConfigLedger = lsccrwset .Writes [1 ].Value
278
314
}
279
315
280
- if ! bytes .Equal (collectionsConfigArgs , collectionsConfigLedger ) {
281
- return errors .Errorf ("collection configuration mismatch for chaincode %s:%s" ,
282
- cdRWSet .Name , cdRWSet .Version )
316
+ if ! bytes .Equal (collectionsConfigArg , collectionsConfigLedger ) {
317
+ return errors .Errorf ("collection configuration mismatch for chaincode %s:%s arg: %s writeset: %s " ,
318
+ cdRWSet .Name , cdRWSet .Version , collectionsConfigArg , collectionsConfigLedger )
283
319
}
284
320
285
- ccp , err := vscc .collectionStore .RetrieveCollectionConfigPackage (common.CollectionCriteria {Channel : chid , Namespace : ccid })
286
- if err != nil {
287
- // fail if we get any error other than NoSuchCollectionError
288
- // because it means something went wrong while looking up the
289
- // older collection
290
- if _ , ok := err .(privdata.NoSuchCollectionError ); ! ok {
291
- return errors .WithMessage (err , fmt .Sprintf ("unable to check whether collection existed earlier for chaincode %s:%s" ,
292
- cdRWSet .Name , cdRWSet .Version ))
321
+ // The following condition check addded in v1.1 may not be needed as it is not possible to have the chaincodeName~collection key in
322
+ // the lscc namespace before a chaincode deploy. To avoid forks in v1.2, the following condition is retained.
323
+ if lsccFunc == lscc .DEPLOY {
324
+ ccp , err := vscc .collectionStore .RetrieveCollectionConfigPackage (common.CollectionCriteria {Channel : channelName , Namespace : cdRWSet .Name })
325
+ if err != nil {
326
+ // fail if we get any error other than NoSuchCollectionError
327
+ // because it means something went wrong while looking up the
328
+ // older collection
329
+ if _ , ok := err .(privdata.NoSuchCollectionError ); ! ok {
330
+ return errors .WithMessage (err , fmt .Sprintf ("unable to check whether collection existed earlier for chaincode %s:%s" ,
331
+ cdRWSet .Name , cdRWSet .Version ))
332
+ }
333
+ }
334
+ if ccp != nil {
335
+ return errors .Errorf ("collection data should not exist for chaincode %s:%s" , cdRWSet .Name , cdRWSet .Version )
293
336
}
294
337
}
295
- if ccp != nil {
296
- return errors .Errorf ("collection data should not exist for chaincode %s:%s" , cdRWSet .Name , cdRWSet .Version )
297
- }
298
338
299
- if collectionsConfigArgs != nil {
300
- collections := & common.CollectionConfigPackage {}
301
- err := proto .Unmarshal (collectionsConfigArgs , collections )
339
+ // TODO: Once the new chaincode lifecycle is available (FAB-8724), the following validation
340
+ // and other validation performed in ValidateLSCCInvocation can be moved to LSCC itself.
341
+ newCollectionConfigPackage := & common.CollectionConfigPackage {}
342
+
343
+ if collectionsConfigArg != nil {
344
+ err := proto .Unmarshal (collectionsConfigArg , newCollectionConfigPackage )
302
345
if err != nil {
303
346
return errors .Errorf ("invalid collection configuration supplied for chaincode %s:%s" ,
304
347
cdRWSet .Name , cdRWSet .Version )
305
348
}
349
+ } else {
350
+ return nil
351
+ }
352
+
353
+ if ac .V1_2Validation () {
354
+ newCollectionConfigs := newCollectionConfigPackage .GetConfig ()
355
+ if err := validateNewCollectionConfigs (newCollectionConfigs ); err != nil {
356
+ return err
357
+ }
306
358
}
307
359
308
360
// TODO: FAB-6526 - to add validation of the collections object
@@ -410,7 +462,7 @@ func (vscc *ValidatorOneValidSignature) ValidateLSCCInvocation(
410
462
if len (lsccrwset .Writes ) < 1 {
411
463
return errors .New ("LSCC must issue at least one single putState upon deploy/upgrade" )
412
464
}
413
- // the first key name must be the chaincode id
465
+ // the first key name must be the chaincode id provided in the deployment spec
414
466
if lsccrwset .Writes [0 ].Key != cdsArgs .ChaincodeSpec .ChaincodeId .Name {
415
467
return fmt .Errorf ("Expected key %s, found %s" , cdsArgs .ChaincodeSpec .ChaincodeId .Name , lsccrwset .Writes [0 ].Key )
416
468
}
@@ -420,11 +472,11 @@ func (vscc *ValidatorOneValidSignature) ValidateLSCCInvocation(
420
472
if err != nil {
421
473
return fmt .Errorf ("Unmarhsalling of ChaincodeData failed, error %s" , err )
422
474
}
423
- // the name must match
475
+ // the chaincode name in the lsccwriteset must match the chaincode name in the deployment spec
424
476
if cdRWSet .Name != cdsArgs .ChaincodeSpec .ChaincodeId .Name {
425
477
return fmt .Errorf ("Expected cc name %s, found %s" , cdsArgs .ChaincodeSpec .ChaincodeId .Name , cdRWSet .Name )
426
478
}
427
- // the version must match
479
+ // the chaincode version in the lsccwriteset must match the chaincode version in the deployment spec
428
480
if cdRWSet .Version != cdsArgs .ChaincodeSpec .ChaincodeId .Version {
429
481
return fmt .Errorf ("Expected cc version %s, found %s" , cdsArgs .ChaincodeSpec .ChaincodeId .Version , cdRWSet .Version )
430
482
}
@@ -444,7 +496,7 @@ func (vscc *ValidatorOneValidSignature) ValidateLSCCInvocation(
444
496
/****************************************************************************/
445
497
if ac .PrivateChannelData () {
446
498
// do extra validation for collections
447
- err = vscc .validateDeployRWSetAndCollection (lsccrwset , cdRWSet , lsccArgs , chid , cdsArgs . ChaincodeSpec . ChaincodeId . Name )
499
+ err = vscc .validateRWSetAndCollection (lsccrwset , cdRWSet , lsccArgs , lsccFunc , ac , chid )
448
500
if err != nil {
449
501
return err
450
502
}
0 commit comments