-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FAB-6664] Add chaincodes group parsing
The previous CR in this series added the proto definitions for the new chaincode lifecycle config structures. This CR actually implements the parsing of these structures in the resources config. It defines new interfaces which may be leveraged by the endorsing/validating pieces of the chaincode. Change-Id: Ic2668594a07f53f24f7bcc285f8fb74864772f6c Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
- Loading branch information
Jason Yellick
committed
Nov 2, 2017
1 parent
c3bfd6d
commit ecabe49
Showing
11 changed files
with
525 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
Copyright IBM Corp. 2017 All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package resourcesconfig | ||
|
||
import ( | ||
"testing" | ||
|
||
cb "github.com/hyperledger/fabric/protos/common" | ||
pb "github.com/hyperledger/fabric/protos/peer" | ||
"github.com/hyperledger/fabric/protos/utils" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
const ( | ||
sampleAPI1Name = "Foo" | ||
sampleAPI1PolicyRef = "foo" | ||
|
||
sampleAPI2Name = "Bar" | ||
sampleAPI2PolicyRef = "/Channel/foo" | ||
) | ||
|
||
var sampleAPIsGroup = &cb.ConfigGroup{ | ||
Values: map[string]*cb.ConfigValue{ | ||
sampleAPI1Name: &cb.ConfigValue{ | ||
Value: utils.MarshalOrPanic(&pb.APIResource{ | ||
PolicyRef: sampleAPI1PolicyRef, | ||
}), | ||
}, | ||
sampleAPI2Name: &cb.ConfigValue{ | ||
Value: utils.MarshalOrPanic(&pb.APIResource{ | ||
PolicyRef: sampleAPI2PolicyRef, | ||
}), | ||
}, | ||
}, | ||
} | ||
|
||
func TestGreenAPIsPath(t *testing.T) { | ||
ag, err := newAPIsGroup(sampleAPIsGroup) | ||
assert.NotNil(t, ag) | ||
assert.NoError(t, err) | ||
|
||
t.Run("PresentAPIs", func(t *testing.T) { | ||
assert.Equal(t, "/Resources/APIs/"+sampleAPI1PolicyRef, ag.PolicyRefForAPI(sampleAPI1Name)) | ||
assert.Equal(t, sampleAPI2PolicyRef, ag.PolicyRefForAPI(sampleAPI2Name)) | ||
}) | ||
|
||
t.Run("MissingAPIs", func(t *testing.T) { | ||
assert.Empty(t, ag.PolicyRefForAPI("missing")) | ||
}) | ||
} | ||
|
||
func TestBadSubgroupsAPIsGroup(t *testing.T) { | ||
ccg, err := newAPIsGroup(&cb.ConfigGroup{ | ||
Groups: map[string]*cb.ConfigGroup{ | ||
"subGroup": &cb.ConfigGroup{}, | ||
}, | ||
}) | ||
|
||
assert.Nil(t, ccg) | ||
assert.Error(t, err) | ||
assert.Regexp(t, "apis group does not support sub-groups", err.Error()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/* | ||
Copyright IBM Corp. 2017 All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package resourcesconfig | ||
|
||
import ( | ||
"github.com/hyperledger/fabric/common/channelconfig" | ||
cb "github.com/hyperledger/fabric/protos/common" | ||
pb "github.com/hyperledger/fabric/protos/peer" | ||
|
||
"github.com/pkg/errors" | ||
) | ||
|
||
type chaincodeProtos struct { | ||
ChaincodeIdentifier *pb.ChaincodeIdentifier | ||
ChaincodeValidation *pb.ChaincodeValidation | ||
ChaincodeEndorsement *pb.ChaincodeEndorsement | ||
} | ||
|
||
// ChaincodeGroup represents the ConfigGroup named Chaincodes off the resources group | ||
type ChaincodeGroup struct { | ||
name string | ||
protos *chaincodeProtos | ||
} | ||
|
||
// Name returns the name of this chaincode (the name it was put in the ChaincodeRegistry with). | ||
func (cg *ChaincodeGroup) Name() string { | ||
return cg.name | ||
} | ||
|
||
// Hash returns the hash of the chaincode. | ||
func (cg *ChaincodeGroup) Hash() []byte { | ||
return cg.protos.ChaincodeIdentifier.Hash | ||
} | ||
|
||
// Version returns the version of the chaincode. | ||
func (cg *ChaincodeGroup) Version() string { | ||
return cg.protos.ChaincodeIdentifier.Version | ||
} | ||
|
||
// Validation returns how to validate transactions for this chaincode. | ||
// The string returned is the name of the validation method (usually 'vscc') | ||
// and the bytes returned are the argument to the validation (in the case of | ||
// 'vscc', this is a marshaled pb.VSCCArgs message). | ||
func (cg *ChaincodeGroup) Validation() (string, []byte) { | ||
return cg.protos.ChaincodeValidation.Name, cg.protos.ChaincodeValidation.Argument | ||
} | ||
|
||
// Endorsement returns how to endorse proposals for this chaincode. | ||
// The string returns is the name of the endorsement method (usually 'escc'). | ||
func (cg *ChaincodeGroup) Endorsement() string { | ||
return cg.protos.ChaincodeEndorsement.Name | ||
} | ||
|
||
func newChaincodeGroup(name string, group *cb.ConfigGroup) (*ChaincodeGroup, error) { | ||
if len(group.Groups) > 0 { | ||
return nil, errors.New("chaincode group does not support sub-groups") | ||
} | ||
|
||
protos := &chaincodeProtos{} | ||
if err := channelconfig.DeserializeProtoValuesFromGroup(group, protos); err != nil { | ||
logger.Panicf("Programming error in structure definition: %s", err) | ||
} | ||
|
||
return &ChaincodeGroup{ | ||
name: name, | ||
protos: protos, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/* | ||
Copyright IBM Corp. 2017 All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package resourcesconfig | ||
|
||
import ( | ||
"testing" | ||
|
||
cb "github.com/hyperledger/fabric/protos/common" | ||
pb "github.com/hyperledger/fabric/protos/peer" | ||
"github.com/hyperledger/fabric/protos/utils" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
const ( | ||
sampleChaincodeVersion = "foo" | ||
sampleChaincodeValidationName = "foobar" | ||
sampleChaincodeEndorsementName = "barfoo" | ||
) | ||
|
||
var ( | ||
sampleChaincodeHash = []byte("bar") | ||
sampleChaincodeValidationArg = []byte("foobararg") | ||
) | ||
|
||
var sampleChaincodeGroup = &cb.ConfigGroup{ | ||
Values: map[string]*cb.ConfigValue{ | ||
"ChaincodeIdentifier": &cb.ConfigValue{ | ||
Value: utils.MarshalOrPanic(&pb.ChaincodeIdentifier{ | ||
Version: sampleChaincodeVersion, | ||
Hash: sampleChaincodeHash, | ||
}), | ||
}, | ||
"ChaincodeValidation": &cb.ConfigValue{ | ||
Value: utils.MarshalOrPanic(&pb.ChaincodeValidation{ | ||
Name: sampleChaincodeValidationName, | ||
Argument: sampleChaincodeValidationArg, | ||
}), | ||
}, | ||
"ChaincodeEndorsement": &cb.ConfigValue{ | ||
Value: utils.MarshalOrPanic(&pb.ChaincodeEndorsement{ | ||
Name: sampleChaincodeEndorsementName, | ||
}), | ||
}, | ||
}, | ||
} | ||
|
||
func TestGreenChaincodePath(t *testing.T) { | ||
ccg, err := newChaincodeGroup(sampleChaincodeName, sampleChaincodeGroup) | ||
assert.NotNil(t, ccg) | ||
assert.NoError(t, err) | ||
|
||
assert.Equal(t, sampleChaincodeName, ccg.Name()) | ||
assert.Equal(t, sampleChaincodeVersion, ccg.Version()) | ||
assert.Equal(t, sampleChaincodeHash, ccg.Hash()) | ||
|
||
validationName, validationArg := ccg.Validation() | ||
assert.Equal(t, sampleChaincodeValidationName, validationName) | ||
assert.Equal(t, sampleChaincodeValidationArg, validationArg) | ||
|
||
assert.Equal(t, sampleChaincodeEndorsementName, ccg.Endorsement()) | ||
} | ||
|
||
func TestBadSubgroupsChaincodeGroup(t *testing.T) { | ||
ccg, err := newChaincodeGroup("bar", &cb.ConfigGroup{ | ||
Groups: map[string]*cb.ConfigGroup{ | ||
"subGroup": &cb.ConfigGroup{}, | ||
}, | ||
}) | ||
|
||
assert.Nil(t, ccg) | ||
assert.Error(t, err) | ||
assert.Regexp(t, "chaincode group does not support sub-groups", err.Error()) | ||
} |
Oops, something went wrong.