Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chaincode persistence uses period separator #492

Merged
merged 1 commit into from
Jan 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions core/chaincode/persistence/chaincode_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,9 @@ type ChaincodePackageParser struct {
MetadataProvider MetadataProvider
}

var (
// LabelRegexp is the regular expression controlling
// the allowed characters for the package label
LabelRegexp = regexp.MustCompile(`^[[:alnum:]][[:alnum:]_.+-]*$`)
)
// LabelRegexp is the regular expression controlling the allowed characters
// for the package label.
var LabelRegexp = regexp.MustCompile(`^[[:alnum:]][[:alnum:]_.+-]*$`)

func validateLabel(label string) error {
if !LabelRegexp.MatchString(label) {
Expand Down
4 changes: 3 additions & 1 deletion core/chaincode/persistence/label_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,21 @@ func TestLabels(t *testing.T) {
{label: "a#", success: false},
{label: "a$", success: false},
{label: "a%", success: false},
{label: "a-", success: true},
{label: "a++b", success: true},
{label: "a+b", success: true},
{label: "a+bb", success: true},
{label: "a-", success: true},
{label: "a--b", success: true},
{label: "a-b", success: true},
{label: "a-bb", success: true},
{label: "a.b", success: true},
{label: "a::b", success: false},
{label: "a:b", success: false},
{label: "a__b", success: true},
{label: "a_b", success: true},
{label: "a_bb", success: true},
{label: "aa", success: true},
{label: "v1.0.0", success: true},
}

for _, tt := range tests {
Expand Down
7 changes: 4 additions & 3 deletions core/chaincode/persistence/persistence.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"os"
"path/filepath"
"regexp"
"strings"

"github.com/hyperledger/fabric/common/chaincode"
"github.com/hyperledger/fabric/common/flogging"
Expand Down Expand Up @@ -230,14 +231,14 @@ func (s *Store) GetChaincodeInstallPath() string {
}

func packageID(label string, hash []byte) string {
return fmt.Sprintf("%s~%x", label, hash)
return fmt.Sprintf("%s:%x", label, hash)
}

func CCFileName(packageID string) string {
return packageID + ".tar.gz"
return strings.Replace(packageID, ":", ".", 1) + ".tar.gz"
}

var packageFileMatcher = regexp.MustCompile("^(.+)~([0-9abcdef]+)[.]tar[.]gz$")
var packageFileMatcher = regexp.MustCompile("^(.+)[.]([0-9a-f]{64})[.]tar[.]gz$")

func installedChaincodeFromFilename(fileName string) (chaincode.InstalledChaincode, bool) {
matches := packageFileMatcher.FindStringSubmatch(fileName)
Expand Down
59 changes: 38 additions & 21 deletions core/chaincode/persistence/persistence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ import (
"path/filepath"

"github.com/hyperledger/fabric/common/chaincode"
"github.com/hyperledger/fabric/common/util"
"github.com/hyperledger/fabric/core/chaincode/persistence"
"github.com/hyperledger/fabric/core/chaincode/persistence/mock"
. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
"github.com/pkg/errors"
)
Expand Down Expand Up @@ -227,11 +229,11 @@ var _ = Describe("Persistence", func() {
It("saves a new code package successfully", func() {
packageID, err := store.Save("testcc", pkgBytes)
Expect(err).NotTo(HaveOccurred())
Expect(packageID).To(Equal("testcc~3fec0187440286d404241e871b44725310b11aaf43d100b053eae712fcabc66d"))
Expect(packageID).To(Equal("testcc:3fec0187440286d404241e871b44725310b11aaf43d100b053eae712fcabc66d"))
Expect(mockReadWriter.WriteFileCallCount()).To(Equal(1))
pkgDataFilePath, pkgDataFileName, pkgData := mockReadWriter.WriteFileArgsForCall(0)
Expect(pkgDataFilePath).To(Equal(""))
Expect(pkgDataFileName).To(Equal("testcc~3fec0187440286d404241e871b44725310b11aaf43d100b053eae712fcabc66d.tar.gz"))
Expect(pkgDataFileName).To(Equal("testcc.3fec0187440286d404241e871b44725310b11aaf43d100b053eae712fcabc66d.tar.gz"))
Expect(pkgData).To(Equal([]byte("testpkg")))
})

Expand All @@ -243,7 +245,7 @@ var _ = Describe("Persistence", func() {
It("does nothing and returns the packageID", func() {
packageID, err := store.Save("testcc", pkgBytes)
Expect(err).NotTo(HaveOccurred())
Expect(packageID).To(Equal("testcc~3fec0187440286d404241e871b44725310b11aaf43d100b053eae712fcabc66d"))
Expect(packageID).To(Equal("testcc:3fec0187440286d404241e871b44725310b11aaf43d100b053eae712fcabc66d"))
Expect(mockReadWriter.WriteFileCallCount()).To(Equal(0))
})
})
Expand All @@ -256,7 +258,7 @@ var _ = Describe("Persistence", func() {
It("returns an error", func() {
packageID, err := store.Save("testcc", pkgBytes)
Expect(packageID).To(Equal(""))
Expect(err).To(MatchError(ContainSubstring("error writing chaincode install package to testcc~3fec0187440286d404241e871b44725310b11aaf43d100b053eae712fcabc66d.tar.gz: soccer")))
Expect(err).To(MatchError(ContainSubstring("error writing chaincode install package to testcc.3fec0187440286d404241e871b44725310b11aaf43d100b053eae712fcabc66d.tar.gz: soccer")))
})
})
})
Expand Down Expand Up @@ -358,14 +360,17 @@ var _ = Describe("Persistence", func() {
var (
mockReadWriter *mock.IOReadWriter
store *persistence.Store
hash1, hash2 []byte
)

BeforeEach(func() {
hash1 = util.ComputeSHA256([]byte("hash1"))
hash2 = util.ComputeSHA256([]byte("hash2"))
mockReadWriter = &mock.IOReadWriter{}
mockFileInfo := &mock.OSFileInfo{}
mockFileInfo.NameReturns(fmt.Sprintf("%s~%x.tar.gz", "label1", []byte("hash1")))
mockFileInfo.NameReturns(fmt.Sprintf("%s.%x.tar.gz", "label1", hash1))
mockFileInfo2 := &mock.OSFileInfo{}
mockFileInfo2.NameReturns(fmt.Sprintf("%s~%x.tar.gz", "label2", []byte("hash2")))
mockFileInfo2.NameReturns(fmt.Sprintf("%s.%x.tar.gz", "label2", hash2))
mockReadWriter.ReadDirReturns([]os.FileInfo{mockFileInfo, mockFileInfo2}, nil)
store = &persistence.Store{
ReadWriter: mockReadWriter,
Expand All @@ -377,27 +382,31 @@ var _ = Describe("Persistence", func() {
Expect(err).NotTo(HaveOccurred())
Expect(installedChaincodes).To(HaveLen(2))
Expect(installedChaincodes[0]).To(Equal(chaincode.InstalledChaincode{
Hash: []byte("hash1"),
Hash: hash1,
Label: "label1",
PackageID: "label1~6861736831",
PackageID: fmt.Sprintf("label1:%x", hash1),
}))
Expect(installedChaincodes[1]).To(Equal(chaincode.InstalledChaincode{
Hash: []byte("hash2"),
Hash: hash2,
Label: "label2",
PackageID: "label2~6861736832",
PackageID: fmt.Sprintf("label2:%x", hash2),
}))
})

Context("when extraneous files are present", func() {
var hash1, hash2 []byte

BeforeEach(func() {
hash1 = util.ComputeSHA256([]byte("hash1"))
hash2 = util.ComputeSHA256([]byte("hash2"))
mockFileInfo := &mock.OSFileInfo{}
mockFileInfo.NameReturns(fmt.Sprintf("%s~%x.tar.gz", "label1", []byte("hash1")))
mockFileInfo.NameReturns(fmt.Sprintf("%s.%x.tar.gz", "label1", hash1))
mockFileInfo2 := &mock.OSFileInfo{}
mockFileInfo2.NameReturns(fmt.Sprintf("%s~%x.tar.gz", "label2", []byte("hash2")))
mockFileInfo2.NameReturns(fmt.Sprintf("%s.%x.tar.gz", "label2", hash2))
mockFileInfo3 := &mock.OSFileInfo{}
mockFileInfo3.NameReturns(fmt.Sprintf("%s~%x.tar.gz", "", "Musha rain dum a doo, dum a da"))
mockFileInfo3.NameReturns(fmt.Sprintf("%s.%x.tar.gz", "", "Musha rain dum a doo, dum a da"))
mockFileInfo4 := &mock.OSFileInfo{}
mockFileInfo4.NameReturns(fmt.Sprintf("%s~%x.tar.gz", "", "barfity~barf.tar.gz"))
mockFileInfo4.NameReturns(fmt.Sprintf("%s.%x.tar.gz", "", "barfity:barf.tar.gz"))
mockReadWriter.ReadDirReturns([]os.FileInfo{mockFileInfo, mockFileInfo2, mockFileInfo3}, nil)
})

Expand All @@ -406,14 +415,14 @@ var _ = Describe("Persistence", func() {
Expect(err).NotTo(HaveOccurred())
Expect(installedChaincodes).To(HaveLen(2))
Expect(installedChaincodes[0]).To(Equal(chaincode.InstalledChaincode{
Hash: []byte("hash1"),
Hash: hash1,
Label: "label1",
PackageID: "label1~6861736831",
PackageID: fmt.Sprintf("label1:%x", hash1),
}))
Expect(installedChaincodes[1]).To(Equal(chaincode.InstalledChaincode{
Hash: []byte("hash2"),
Hash: hash2,
Label: "label2",
PackageID: "label2~6861736832",
PackageID: fmt.Sprintf("label2:%x", hash2),
}))
})
})
Expand All @@ -432,9 +441,7 @@ var _ = Describe("Persistence", func() {
})

Describe("GetChaincodeInstallPath", func() {
var (
store *persistence.Store
)
var store *persistence.Store

BeforeEach(func() {
store = &persistence.Store{
Expand All @@ -447,4 +454,14 @@ var _ = Describe("Persistence", func() {
Expect(path).To(Equal("testPath"))
})
})

DescribeTable("CCFileName",
func(packageID, expectedName string) {
Expect(persistence.CCFileName(packageID)).To(Equal(expectedName))
},
Entry("label with dot and without hash", "aaa.bbb", "aaa.bbb.tar.gz"),
Entry("label and hash with colon delimeter", "aaa:bbb", "aaa.bbb.tar.gz"),
Entry("missing label with colon delimeter", ":bbb", ".bbb.tar.gz"),
Entry("missing hash with colon delimeter", "aaa:", "aaa..tar.gz"),
)
})
2 changes: 1 addition & 1 deletion integration/nwo/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func (c *Chaincode) SetPackageIDFromPackageFile() {
fileBytes, err := ioutil.ReadFile(c.PackageFile)
Expect(err).NotTo(HaveOccurred())
hashStr := fmt.Sprintf("%x", util.ComputeSHA256(fileBytes))
c.PackageID = c.Label + "~" + hashStr
c.PackageID = c.Label + ":" + hashStr
}

// DeployChaincode is a helper that will install chaincode to all peers that
Expand Down