Skip to content

Commit

Permalink
[FAB-4590] Auto-vendor all deps properly
Browse files Browse the repository at this point in the history
It was noted that the auto-vendoring mechanism introduced
in CR 6991 was failing to vendor dependencies properly.

Investigating, it was root-caused that we were only auto-
vendoring transitive dependencies, not direct imports.

This patch corrects this by merging the direct imports
into our dependency tree.  Fix was verified by adding
the unit-test, verifying that it fails, and subsequently
verifying that it passes after the fix was applied.

Credit to Rahul Hegde <rhegde@cls-bank.com> for finding the
issue and proposing the proper fix that inspired this patch.

Fixes FAB-4590

Change-Id: Ie0631ac1033c3f427ea42c43eccf76a0f7390320
Signed-off-by: Greg Haskins <gregory.haskins@gmail.com>
  • Loading branch information
ghaskins committed Jun 13, 2017
1 parent f5dbbaf commit 44c341c
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 4 deletions.
19 changes: 15 additions & 4 deletions core/chaincode/platforms/golang/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,18 +239,29 @@ func (goPlatform *Platform) GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte
})

// --------------------------------------------------------------------------------------
// Assemble the fully resolved list of transitive dependencies from the imports that remain
// Assemble the fully resolved list of direct and transitive dependencies based on the
// imports that remain after filtering
// --------------------------------------------------------------------------------------
deps := make(map[string]bool)

for _, pkg := range imports {
_deps, err := listDeps(env, pkg)
// ------------------------------------------------------------------------------
// Resolve direct import's transitives
// ------------------------------------------------------------------------------
transitives, err := listDeps(env, pkg)
if err != nil {
return nil, fmt.Errorf("Error obtaining dependencies for %s: %s", pkg, err)
}

// Merge with our top list
for _, dep := range _deps {
// ------------------------------------------------------------------------------
// Merge all results with our top list
// ------------------------------------------------------------------------------

// Merge direct dependency...
deps[pkg] = true

// .. and then all transitives
for _, dep := range transitives {
deps[dep] = true
}
}
Expand Down
1 change: 1 addition & 0 deletions core/chaincode/platforms/golang/platform_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ func TestGenerateDockerBuild(t *testing.T) {
specs = append(specs, spec{CCName: "NoCode", Path: "path/to/nowhere", File: "/bin/warez", Mode: 0100400, SuccessExpected: false})
specs = append(specs, spec{CCName: "invalidhttp", Path: "https://not/a/valid/path", File: "/src/github.com/hyperledger/fabric/examples/chaincode/go/map/map.go", Mode: 0100400, SuccessExpected: false, RealGen: true})
specs = append(specs, spec{CCName: "map", Path: "github.com/hyperledger/fabric/examples/chaincode/go/map", File: "/src/github.com/hyperledger/fabric/examples/chaincode/go/map/map.go", Mode: 0100400, SuccessExpected: true, RealGen: true})
specs = append(specs, spec{CCName: "AutoVendor", Path: "github.com/hyperledger/fabric/test/chaincodes/AutoVendor/chaincode", File: "/src/github.com/hyperledger/fabric/test/chaincodes/AutoVendor/chaincode/main.go", Mode: 0100400, SuccessExpected: true, RealGen: true})
specs = append(specs, spec{CCName: "mapBadPath", Path: "github.com/hyperledger/fabric/examples/chaincode/go/map", File: "/src/github.com/hyperledger/fabric/examples/bad/path/to/map.go", Mode: 0100400, SuccessExpected: false})
specs = append(specs, spec{CCName: "mapBadMode", Path: "github.com/hyperledger/fabric/examples/chaincode/go/map", File: "/src/github.com/hyperledger/fabric/examples/chaincode/go/map/map.go", Mode: 0100555, SuccessExpected: false})

Expand Down
43 changes: 43 additions & 0 deletions test/chaincodes/AutoVendor/chaincode/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright Greg Haskins All Rights Reserved
*
* SPDX-License-Identifier: Apache-2.0
*
* The purpose of this test code is to prove that the system properly packages
* up dependencies. We therefore synthesize the scenario where a chaincode
* imports non-standard dependencies both directly and indirectly and then
* expect a unit-test to verify that the package includes everything needed
* and ultimately builds properly.
*
*/

package main

import (
"fmt"

"github.com/hyperledger/fabric/core/chaincode/shim"
pb "github.com/hyperledger/fabric/protos/peer"
"github.com/hyperledger/fabric/test/chaincodes/AutoVendor/directdep"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Error("NOT IMPL")
}

func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
return shim.Error("NOT IMPL")
}

func main() {
directdep.PointlessFunction()

err := shim.Start(new(SimpleChaincode))
if err != nil {
fmt.Printf("Error starting Simple chaincode: %s", err)
}
}
17 changes: 17 additions & 0 deletions test/chaincodes/AutoVendor/directdep/core.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright Greg Haskins All Rights Reserved
*
* SPDX-License-Identifier: Apache-2.0
*
* See github.com/hyperledger/fabric/test/chaincodes/AutoVendor/chaincode/main.go for details
*/
package directdep

import (
"github.com/hyperledger/fabric/test/chaincodes/AutoVendor/indirectdep"
)

func PointlessFunction() {
// delegate to our indirect dependency
indirectdep.PointlessFunction()
}
14 changes: 14 additions & 0 deletions test/chaincodes/AutoVendor/indirectdep/core.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright Greg Haskins All Rights Reserved
*
* SPDX-License-Identifier: Apache-2.0
*
* See github.com/hyperledger/fabric/test/chaincodes/AutoVendor/chaincode/main.go for details
*/
package indirectdep

import "fmt"

func PointlessFunction() {
fmt.Printf("Successfully invoked pointless function\n")
}

0 comments on commit 44c341c

Please sign in to comment.