Skip to content

Commit

Permalink
Impl: fix hyperledger#37
Browse files Browse the repository at this point in the history
Signed-off-by: Sam Yuan <yy19902439@126.com>
  • Loading branch information
SamYuan1990 committed Oct 31, 2022
1 parent 95c92b4 commit e7dfdb0
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 6 deletions.
9 changes: 3 additions & 6 deletions .github/workflows/golange2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,9 @@ jobs:
- run: mkdir -p ../organizations && cp -r ../../fabric-samples/test-network/organizations/* ../organizations/ && ls ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
working-directory: go/e2e
name: prepare msp for test
# todo remove with golang
- run: go test -v ./...
working-directory: go/e2e
name: e2e
# skip as join channel tbd
#- run: echo y | ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go/ -ccl go
# working-directory: fabric-samples/test-network
# name: install chaincode-go
# end of todo scope
- run: go test -v ./...
working-directory: go/e2e
name: start chaincode docker
126 changes: 126 additions & 0 deletions go/chaincode/packageID.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package chaincode

import (
"archive/tar"
"bytes"
"compress/gzip"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"regexp"

"github.com/hyperledger/fabric/common/util"
"github.com/pkg/errors"
)

const (
// MetadataFile is the expected location of the metadata json document
// in the top level of the chaincode package.
MetadataFile = "metadata.json"

// CodePackageFile is the expected location of the code package in the
// top level of the chaincode package
CodePackageFile = "code.tar.gz"
)

var LabelRegexp = regexp.MustCompile(`^[[:alnum:]][[:alnum:]_.+-]*$`)

func PackageID(PackageFile string) (string, error) {
pkgBytes, err := ioutil.ReadFile(PackageFile)
if err != nil {
return "", errors.WithMessagef(err, "failed to read chaincode package at '%s'", PackageFile)
}
metadata, _, err := ParseChaincodePackage(pkgBytes)
if err != nil {
return "", errors.WithMessage(err, "could not parse as a chaincode install package")
}
packageID := GetPackageID(metadata.Label, pkgBytes)
return packageID, nil
}

// PackageID returns the package ID with the label and hash of the chaincode install package
func GetPackageID(label string, ccInstallPkg []byte) string {
hash := util.ComputeSHA256(ccInstallPkg)
return fmt.Sprintf("%s:%x", label, hash)
}

// ChaincodePackageMetadata contains the information necessary to understand
// the embedded code package.
type ChaincodePackageMetadata struct {
Type string `json:"type"`
Path string `json:"path"`
Label string `json:"label"`
}

// ParseChaincodePackage parses a set of bytes as a chaincode package
// and returns the parsed package as a metadata struct and a code package
func ParseChaincodePackage(source []byte) (*ChaincodePackageMetadata, []byte, error) {
gzReader, err := gzip.NewReader(bytes.NewBuffer(source))
if err != nil {
return &ChaincodePackageMetadata{}, nil, errors.Wrapf(err, "error reading as gzip stream")
}

tarReader := tar.NewReader(gzReader)

var codePackage []byte
var ccPackageMetadata *ChaincodePackageMetadata
for {
header, err := tarReader.Next()
if err == io.EOF {
break
}

if err != nil {
return ccPackageMetadata, nil, errors.Wrapf(err, "error inspecting next tar header")
}

if header.Typeflag != tar.TypeReg {
return ccPackageMetadata, nil, errors.Errorf("tar entry %s is not a regular file, type %v", header.Name, header.Typeflag)
}

fileBytes, err := ioutil.ReadAll(tarReader)
if err != nil {
return ccPackageMetadata, nil, errors.Wrapf(err, "could not read %s from tar", header.Name)
}

switch header.Name {

case MetadataFile:
ccPackageMetadata = &ChaincodePackageMetadata{}
err := json.Unmarshal(fileBytes, ccPackageMetadata)
if err != nil {
return ccPackageMetadata, nil, errors.Wrapf(err, "could not unmarshal %s as json", MetadataFile)
}

case CodePackageFile:
codePackage = fileBytes
default:
fmt.Println("Encountered unexpected file '%s' in top level of chaincode package", header.Name)
}
}

if codePackage == nil {
return ccPackageMetadata, nil, errors.Errorf("did not find a code package inside the package")
}

if ccPackageMetadata == nil {
return ccPackageMetadata, nil, errors.Errorf("did not find any package metadata (missing %s)", MetadataFile)
}

if err := ValidateLabel(ccPackageMetadata.Label); err != nil {
return ccPackageMetadata, nil, err
}

return ccPackageMetadata, codePackage, nil
}

// ValidateLabel return an error if the provided label contains any invalid
// characters, as determined by LabelRegexp.
func ValidateLabel(label string) error {
if !LabelRegexp.MatchString(label) {
return errors.Errorf("invalid label '%s'. Label must be non-empty, can only consist of alphanumerics, symbols from '.+-_', and can only begin with alphanumerics", label)
}

return nil
}
3 changes: 3 additions & 0 deletions go/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ var _ = Describe("e2e", func() {
//err = chaincode.InstallChainCode("", "./basicj.tar.gz", "basic-asset", "1.0", *org2MSP, connection2)
Expect(err).NotTo(HaveOccurred())

PackageID, err := chaincode.PackageID(tmpDir + "/basic-asset.tar.gz")
Expect(err).NotTo(HaveOccurred())
fmt.Println(PackageID)
//cc define
CCDefine := chaincode.CCDefine{
ChannelID: "mychannel",
Expand Down

0 comments on commit e7dfdb0

Please sign in to comment.