@@ -18,9 +18,8 @@ package lccc
18
18
19
19
import (
20
20
"fmt"
21
+ "regexp"
21
22
"sort"
22
- "strconv"
23
- "strings"
24
23
25
24
"github.com/golang/protobuf/proto"
26
25
"github.com/hyperledger/fabric/common/cauthdsl"
@@ -74,8 +73,8 @@ const (
74
73
//GETINSTALLEDCHAINCODES gets the installed chaincodes on a peer
75
74
GETINSTALLEDCHAINCODES = "getinstalledchaincodes"
76
75
77
- //characters used in chaincodenamespace
78
- specialChars = "/:[]${} "
76
+ allowedCharsChaincodeName = "[A-Za-z0-9_-]+"
77
+ allowedCharsVersion = "[A-Za-z0-9_.-]+ "
79
78
)
80
79
81
80
//---------- the LCCC -----------------
@@ -164,37 +163,44 @@ func (f InvalidChainNameErr) Error() string {
164
163
type InvalidChaincodeNameErr string
165
164
166
165
func (f InvalidChaincodeNameErr ) Error () string {
167
- return fmt .Sprintf ("invalid chain code name %s" , string (f ))
166
+ return fmt .Sprintf ("invalid chaincode name %s" , string (f ))
168
167
}
169
168
170
- //MarshallErr error marshaling/unmarshalling
171
- type MarshallErr string
169
+ //EmptyChaincodeNameErr trying to upgrade to same version of Chaincode
170
+ type EmptyChaincodeNameErr string
172
171
173
- func (m MarshallErr ) Error () string {
174
- return fmt .Sprintf ( "error while marshalling %s" , string ( m ) )
172
+ func (f EmptyChaincodeNameErr ) Error () string {
173
+ return fmt .Sprint ( "chaincode name not provided" )
175
174
}
176
175
177
- //IdenticalVersionErr trying to upgrade to same version of Chaincode
178
- type IdenticalVersionErr string
179
-
180
- func (f IdenticalVersionErr ) Error () string {
181
- return fmt .Sprintf ("chain code with the same version exists %s" , string (f ))
182
- }
183
-
184
- //InvalidVersionErr trying to upgrade to same version of Chaincode
176
+ //InvalidVersionErr invalid version error
185
177
type InvalidVersionErr string
186
178
187
179
func (f InvalidVersionErr ) Error () string {
188
- return fmt .Sprintf ("invalid version %s" , string (f ))
180
+ return fmt .Sprintf ("invalid chaincode version %s" , string (f ))
189
181
}
190
182
191
- //EmptyVersionErr trying to upgrade to same version of Chaincode
183
+ //EmptyVersionErr empty version error
192
184
type EmptyVersionErr string
193
185
194
186
func (f EmptyVersionErr ) Error () string {
195
187
return fmt .Sprintf ("version not provided for chaincode %s" , string (f ))
196
188
}
197
189
190
+ //MarshallErr error marshaling/unmarshalling
191
+ type MarshallErr string
192
+
193
+ func (m MarshallErr ) Error () string {
194
+ return fmt .Sprintf ("error while marshalling %s" , string (m ))
195
+ }
196
+
197
+ //IdenticalVersionErr trying to upgrade to same version of Chaincode
198
+ type IdenticalVersionErr string
199
+
200
+ func (f IdenticalVersionErr ) Error () string {
201
+ return fmt .Sprintf ("chaincode with the same version exists %s" , string (f ))
202
+ }
203
+
198
204
//-------------- helper functions ------------------
199
205
//create the chaincode on the given chain
200
206
func (lccc * LifeCycleSysCC ) createChaincode (stub shim.ChaincodeStubInterface , chainname string , ccname string , version string , cccode []byte , policy []byte , escc []byte , vscc []byte ) (* ccprovider.ChaincodeData , error ) {
@@ -338,35 +344,60 @@ func (lccc *LifeCycleSysCC) isValidChainName(chainname string) bool {
338
344
return true
339
345
}
340
346
341
- //check validity of chaincode name
342
- func (lccc * LifeCycleSysCC ) isValidChaincodeName (chaincodename string ) bool {
343
- //TODO we probably need more checks
344
- if chaincodename == "" {
345
- return false
347
+ // isValidChaincodeName checks the validity of chaincode name. Chaincode names
348
+ // should never be blank and should only consist of alphanumerics, '_', and '-'
349
+ func (lccc * LifeCycleSysCC ) isValidChaincodeName (chaincodeName string ) error {
350
+ if chaincodeName == "" {
351
+ return EmptyChaincodeNameErr ("" )
352
+ }
353
+
354
+ if ! isValidCCNameOrVersion (chaincodeName , allowedCharsChaincodeName ) {
355
+ return InvalidChaincodeNameErr (chaincodeName )
356
+ }
357
+
358
+ return nil
359
+ }
360
+
361
+ // isValidChaincodeVersion checks the validity of chaincode version. Versions
362
+ // should never be blank and should only consist of alphanumerics, '_', '-',
363
+ // and '.'
364
+ func (lccc * LifeCycleSysCC ) isValidChaincodeVersion (chaincodeName string , version string ) error {
365
+ if version == "" {
366
+ return EmptyVersionErr (chaincodeName )
367
+ }
368
+
369
+ if ! isValidCCNameOrVersion (version , allowedCharsVersion ) {
370
+ return InvalidVersionErr (version )
346
371
}
347
372
348
- //do not allow special characters in chaincode name
349
- if strings .ContainsAny (chaincodename , specialChars ) {
373
+ return nil
374
+ }
375
+
376
+ func isValidCCNameOrVersion (ccNameOrVersion string , regExp string ) bool {
377
+ re , _ := regexp .Compile (regExp )
378
+
379
+ matched := re .FindString (ccNameOrVersion )
380
+ if len (matched ) != len (ccNameOrVersion ) {
350
381
return false
351
382
}
352
383
353
384
return true
354
385
}
355
386
356
- //this implements "install" Invoke transaction
387
+ // executeInstall implements the "install" Invoke transaction
357
388
func (lccc * LifeCycleSysCC ) executeInstall (stub shim.ChaincodeStubInterface , depSpec []byte ) error {
358
389
cds , err := utils .GetChaincodeDeploymentSpec (depSpec )
359
390
360
391
if err != nil {
361
392
return err
362
393
}
363
394
364
- if ! lccc .isValidChaincodeName (cds .ChaincodeSpec .ChaincodeId .Name ) {
365
- return InvalidChaincodeNameErr ( cds . ChaincodeSpec . ChaincodeId . Name )
395
+ if err = lccc .isValidChaincodeName (cds .ChaincodeSpec .ChaincodeId .Name ); err != nil {
396
+ return err
366
397
}
367
398
368
- if cds .ChaincodeSpec .ChaincodeId .Version == "" {
369
- return EmptyVersionErr ( cds . ChaincodeSpec . ChaincodeId . Name )
399
+ if err = lccc . isValidChaincodeVersion ( cds .ChaincodeSpec .ChaincodeId .Name , cds . ChaincodeSpec . ChaincodeId . Version ); err != nil {
400
+ return err
370
401
}
371
402
372
403
if err = ccprovider .PutChaincodeIntoFS (cds ); err != nil {
@@ -376,16 +407,20 @@ func (lccc *LifeCycleSysCC) executeInstall(stub shim.ChaincodeStubInterface, dep
376
407
return err
377
408
}
378
409
379
- //this implements "deploy " Invoke transaction
410
+ // executeDeploy implements the "instantiate " Invoke transaction
380
411
func (lccc * LifeCycleSysCC ) executeDeploy (stub shim.ChaincodeStubInterface , chainname string , depSpec []byte , policy []byte , escc []byte , vscc []byte ) error {
381
412
cds , err := utils .GetChaincodeDeploymentSpec (depSpec )
382
413
383
414
if err != nil {
384
415
return err
385
416
}
386
417
387
- if ! lccc .isValidChaincodeName (cds .ChaincodeSpec .ChaincodeId .Name ) {
388
- return InvalidChaincodeNameErr (cds .ChaincodeSpec .ChaincodeId .Name )
418
+ if err = lccc .isValidChaincodeName (cds .ChaincodeSpec .ChaincodeId .Name ); err != nil {
419
+ return err
420
+ }
421
+
422
+ if err = lccc .isValidChaincodeVersion (cds .ChaincodeSpec .ChaincodeId .Name , cds .ChaincodeSpec .ChaincodeId .Version ); err != nil {
423
+ return err
389
424
}
390
425
391
426
if err = lccc .acl (stub , chainname , cds ); err != nil {
@@ -397,40 +432,12 @@ func (lccc *LifeCycleSysCC) executeDeploy(stub shim.ChaincodeStubInterface, chai
397
432
return ExistsErr (cds .ChaincodeSpec .ChaincodeId .Name )
398
433
}
399
434
400
- if cds .ChaincodeSpec .ChaincodeId .Version == "" {
401
- return EmptyVersionErr (cds .ChaincodeSpec .ChaincodeId .Name )
402
- }
403
-
404
435
_ , err = lccc .createChaincode (stub , chainname , cds .ChaincodeSpec .ChaincodeId .Name , cds .ChaincodeSpec .ChaincodeId .Version , depSpec , policy , escc , vscc )
405
436
406
437
return err
407
438
}
408
439
409
- func (lccc * LifeCycleSysCC ) getUpgradeVersion (cd * ccprovider.ChaincodeData , cds * pb.ChaincodeDeploymentSpec ) (string , error ) {
410
- if cd .Version == cds .ChaincodeSpec .ChaincodeId .Version {
411
- return "" , IdenticalVersionErr (cds .ChaincodeSpec .ChaincodeId .Name )
412
- }
413
-
414
- if cds .ChaincodeSpec .ChaincodeId .Version != "" {
415
- return cds .ChaincodeSpec .ChaincodeId .Version , nil
416
- }
417
-
418
- //user did not specifcy Version. the previous version better be a number
419
- v , err := strconv .ParseInt (cd .Version , 10 , 32 )
420
-
421
- //This should never happen as long we don't expose version as version is computed internally
422
- //so panic till we find a need to relax
423
- if err != nil {
424
- return "" , InvalidVersionErr (cd .Version )
425
- }
426
-
427
- // replace the ChaincodeDeploymentSpec using the next version
428
- newVersion := fmt .Sprintf ("%d" , (v + 1 ))
429
-
430
- return newVersion , nil
431
- }
432
-
433
- //this implements "upgrade" Invoke transaction
440
+ // executeUpgrade implements the "upgrade" Invoke transaction.
434
441
func (lccc * LifeCycleSysCC ) executeUpgrade (stub shim.ChaincodeStubInterface , chainName string , depSpec []byte , policy []byte , escc []byte , vscc []byte ) ([]byte , error ) {
435
442
cds , err := utils .GetChaincodeDeploymentSpec (depSpec )
436
443
if err != nil {
@@ -442,8 +449,12 @@ func (lccc *LifeCycleSysCC) executeUpgrade(stub shim.ChaincodeStubInterface, cha
442
449
}
443
450
444
451
chaincodeName := cds .ChaincodeSpec .ChaincodeId .Name
445
- if ! lccc .isValidChaincodeName (chaincodeName ) {
446
- return nil , InvalidChaincodeNameErr (chaincodeName )
452
+ if err = lccc .isValidChaincodeName (chaincodeName ); err != nil {
453
+ return nil , err
454
+ }
455
+
456
+ if err = lccc .isValidChaincodeVersion (chaincodeName , cds .ChaincodeSpec .ChaincodeId .Version ); err != nil {
457
+ return nil , err
447
458
}
448
459
449
460
// check for existence of chaincode
@@ -452,11 +463,12 @@ func (lccc *LifeCycleSysCC) executeUpgrade(stub shim.ChaincodeStubInterface, cha
452
463
return nil , NotFoundErr (chainName )
453
464
}
454
465
455
- ver , err := lccc .getUpgradeVersion (cd , cds )
456
- if err != nil {
457
- return nil , err
466
+ if cd .Version == cds .ChaincodeSpec .ChaincodeId .Version {
467
+ return nil , IdenticalVersionErr (cds .ChaincodeSpec .ChaincodeId .Name )
458
468
}
459
469
470
+ ver := cds .ChaincodeSpec .ChaincodeId .Version
471
+
460
472
newCD , err := lccc .upgradeChaincode (stub , chainName , chaincodeName , ver , depSpec , policy , escc , vscc )
461
473
if err != nil {
462
474
return nil , err
0 commit comments