From d2d5bef6b741b86769ce0ac24bb907c5412dcd3a Mon Sep 17 00:00:00 2001 From: Will Lahti Date: Wed, 11 Jul 2018 14:10:47 -0400 Subject: [PATCH] FAB-11112 Functions to convert CDS to cc install pkg This CR adds utility functions to convert ChaincodeDeploymentSpecs and SignedChaincodeDeploymentSpecs to the new ChaincodeInstallPackage proto. Change-Id: I0f7dbaf5f0078e05d0c24087a9d23744d55d0bce Signed-off-by: Will Lahti --- protos/utils/chaincodeutils.go | 60 +++++++++++++ protos/utils/chaincodeutils_test.go | 129 ++++++++++++++++++++++++++++ protos/utils/utils_suite_test.go | 19 ++++ 3 files changed, 208 insertions(+) create mode 100644 protos/utils/chaincodeutils.go create mode 100644 protos/utils/chaincodeutils_test.go create mode 100644 protos/utils/utils_suite_test.go diff --git a/protos/utils/chaincodeutils.go b/protos/utils/chaincodeutils.go new file mode 100644 index 00000000000..f7d0bd3fab8 --- /dev/null +++ b/protos/utils/chaincodeutils.go @@ -0,0 +1,60 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package utils + +import ( + "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric/protos/peer" + "github.com/pkg/errors" +) + +// ConvertCDSToChaincodeInstallPackage converts a ChaincodeDeploymentSpec into +// a ChaincodeInstallPackage and also returns the name and version from the +// ChaincodeDeploymentSpec +func ConvertCDSToChaincodeInstallPackage(cds *peer.ChaincodeDeploymentSpec) (name, version string, cip *peer.ChaincodeInstallPackage, err error) { + if cds.ChaincodeSpec == nil { + return "", "", nil, errors.New("nil ChaincodeSpec") + } + + if cds.ChaincodeSpec.ChaincodeId == nil { + return "", "", nil, errors.New("nil ChaincodeId") + } + + name = cds.ChaincodeSpec.ChaincodeId.Name + version = cds.ChaincodeSpec.ChaincodeId.Version + + cip = &peer.ChaincodeInstallPackage{ + CodePackage: cds.CodePackage, + Path: cds.ChaincodeSpec.ChaincodeId.Path, + Type: cds.ChaincodeSpec.Type.String(), + } + + return name, version, cip, nil +} + +// ConvertSignedCDSToChaincodeInstallPackage converts a +// SignedChaincodeDeploymentSpec into a ChaincodeInstallPackage and also +// returns the name and version from the SignedChaincodeDeploymentSpec +func ConvertSignedCDSToChaincodeInstallPackage(scds *peer.SignedChaincodeDeploymentSpec) (name, version string, cip *peer.ChaincodeInstallPackage, err error) { + cds, err := UnmarshalChaincodeDeploymentSpec(scds.ChaincodeDeploymentSpec) + if err != nil { + return "", "", nil, err + } + return ConvertCDSToChaincodeInstallPackage(cds) +} + +// UnmarshalChaincodeDeploymentSpec unmarshals a ChaincodeDeploymentSpec from +// the provided bytes +func UnmarshalChaincodeDeploymentSpec(cdsBytes []byte) (*peer.ChaincodeDeploymentSpec, error) { + cds := &peer.ChaincodeDeploymentSpec{} + err := proto.Unmarshal(cdsBytes, cds) + if err != nil { + return nil, errors.Wrap(err, "error unmarshaling ChaincodeDeploymentSpec") + } + + return cds, nil +} diff --git a/protos/utils/chaincodeutils_test.go b/protos/utils/chaincodeutils_test.go new file mode 100644 index 00000000000..33bf6206224 --- /dev/null +++ b/protos/utils/chaincodeutils_test.go @@ -0,0 +1,129 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package utils_test + +import ( + "github.com/golang/protobuf/proto" + "github.com/hyperledger/fabric/protos/peer" + "github.com/hyperledger/fabric/protos/utils" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("ChaincodeUtils", func() { + var _ = Describe("ConvertCDSToChaincodeInstallPackage", func() { + var cds *peer.ChaincodeDeploymentSpec + + BeforeEach(func() { + cds = createChaincodeDeploymentSpec("testcc", "version1", "codepath", "GOLANG", []byte("codefortest")) + }) + + It("converts a ChaincodeDeploymentSpec to a ChaincodeInstallPackage", func() { + name, version, cip, err := utils.ConvertCDSToChaincodeInstallPackage(cds) + + Expect(err).To(BeNil()) + Expect(name).To(Equal("testcc")) + Expect(version).To(Equal("version1")) + Expect(cip.CodePackage).To(Equal([]byte("codefortest"))) + Expect(cip.Path).To(Equal("codepath")) + Expect(cip.Type).To(Equal("GOLANG")) + }) + + Context("when the ChaincodeSpec is nil", func() { + BeforeEach(func() { + cds.ChaincodeSpec = nil + }) + + It("returns an error", func() { + name, version, cip, err := utils.ConvertCDSToChaincodeInstallPackage(cds) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("nil ChaincodeSpec")) + Expect(name).To(Equal("")) + Expect(version).To(Equal("")) + Expect(cip).To(BeNil()) + }) + }) + + Context("when the ChaincodeId is nil", func() { + BeforeEach(func() { + cds.ChaincodeSpec.ChaincodeId = nil + }) + + It("returns an error", func() { + name, version, cip, err := utils.ConvertCDSToChaincodeInstallPackage(cds) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal("nil ChaincodeId")) + Expect(name).To(Equal("")) + Expect(version).To(Equal("")) + Expect(cip).To(BeNil()) + }) + }) + }) + + var _ = Describe("ConvertSignedCDSToChaincodeInstallPackage", func() { + var scds *peer.SignedChaincodeDeploymentSpec + + BeforeEach(func() { + cds := createChaincodeDeploymentSpec("testcc", "version1", "codepath", "GOLANG", []byte("codefortest")) + cdsBytes, err := proto.Marshal(cds) + Expect(err).NotTo(HaveOccurred()) + + scds = &peer.SignedChaincodeDeploymentSpec{ + ChaincodeDeploymentSpec: cdsBytes, + } + }) + + It("converts a ChaincodeDeploymentSpec to a ChaincodeInstallPackage", func() { + name, version, cip, err := utils.ConvertSignedCDSToChaincodeInstallPackage(scds) + + Expect(err).To(BeNil()) + Expect(name).To(Equal("testcc")) + Expect(version).To(Equal("version1")) + Expect(cip.CodePackage).To(Equal([]byte("codefortest"))) + Expect(cip.Path).To(Equal("codepath")) + Expect(cip.Type).To(Equal("GOLANG")) + }) + + Context("when the ChaincodeDeploymentSpec bytes fail to unmarshal", func() { + BeforeEach(func() { + scds.ChaincodeDeploymentSpec = []byte("garbage") + }) + + It("returns an error", func() { + name, version, cip, err := utils.ConvertSignedCDSToChaincodeInstallPackage(scds) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("error unmarshaling ChaincodeDeploymentSpec")) + Expect(name).To(Equal("")) + Expect(version).To(Equal("")) + Expect(cip).To(BeNil()) + }) + }) + }) +}) + +func createChaincodeDeploymentSpec(name, version, path, ccType string, codePackage []byte) *peer.ChaincodeDeploymentSpec { + spec := createChaincodeSpec(name, version, path, ccType) + cds := &peer.ChaincodeDeploymentSpec{ + ChaincodeSpec: spec, + CodePackage: codePackage, + } + + return cds +} + +func createChaincodeSpec(name, version, path, ccType string) *peer.ChaincodeSpec { + spec := &peer.ChaincodeSpec{ + Type: peer.ChaincodeSpec_Type(peer.ChaincodeSpec_Type_value[ccType]), + ChaincodeId: &peer.ChaincodeID{ + Path: path, + Name: name, + Version: version, + }, + } + + return spec +} diff --git a/protos/utils/utils_suite_test.go b/protos/utils/utils_suite_test.go new file mode 100644 index 00000000000..1fcb9ca7ea0 --- /dev/null +++ b/protos/utils/utils_suite_test.go @@ -0,0 +1,19 @@ +/* +Copyright IBM Corp. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package utils_test + +import ( + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func TestUtils(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Utils Suite") +}