diff --git a/core/chaincode/chaincode_support.go b/core/chaincode/chaincode_support.go index aec99fa94b3..39959766b6a 100644 --- a/core/chaincode/chaincode_support.go +++ b/core/chaincode/chaincode_support.go @@ -12,6 +12,7 @@ import ( "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric/common/util" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/common/sysccprovider" "github.com/hyperledger/fabric/core/container/ccintf" @@ -55,6 +56,7 @@ func NewChaincodeSupport( aclProvider ACLProvider, processor Processor, sccp sysccprovider.SystemChaincodeProvider, + platformRegistry *platforms.Registry, ) *ChaincodeSupport { cs := &ChaincodeSupport{ UserRunsCC: userRunsCC, @@ -71,10 +73,11 @@ func NewChaincodeSupport( } cs.Runtime = &ContainerRuntime{ - CertGenerator: certGenerator, - Processor: processor, - CACert: caCert, - PeerAddress: peerAddress, + CertGenerator: certGenerator, + Processor: processor, + CACert: caCert, + PeerAddress: peerAddress, + PlatformRegistry: platformRegistry, CommonEnv: []string{ "CORE_CHAINCODE_LOGGING_LEVEL=" + config.LogLevel, "CORE_CHAINCODE_LOGGING_SHIM=" + config.ShimLogLevel, diff --git a/core/chaincode/chaincode_support_test.go b/core/chaincode/chaincode_support_test.go index 039e9b18ec5..53512902566 100644 --- a/core/chaincode/chaincode_support_test.go +++ b/core/chaincode/chaincode_support_test.go @@ -31,6 +31,8 @@ import ( "github.com/hyperledger/fabric/core/aclmgmt/resources" "github.com/hyperledger/fabric/core/chaincode/accesscontrol" "github.com/hyperledger/fabric/core/chaincode/mock" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/config" @@ -170,6 +172,7 @@ func initMockPeer(chainIDs ...string) (*ChaincodeSupport, error) { config := GlobalConfig() config.StartupTimeout = 10 * time.Second config.ExecuteTimeout = 1 * time.Second + pr := platforms.NewRegistry(&golang.Platform{}) chaincodeSupport := NewChaincodeSupport( config, "0.0.0.0:7052", @@ -185,13 +188,14 @@ func initMockPeer(chainIDs ...string) (*ChaincodeSupport, error) { }, ), sccp, + pr, ) // Mock policy checker policy.RegisterPolicyCheckerFactory(&mockPolicyCheckerFactory{}) ccp := &CCProviderImpl{cs: chaincodeSupport} - for _, cc := range scc.CreateSysCCs(ccp, sccp, mockAclProvider) { + for _, cc := range scc.CreateSysCCs(ccp, sccp, mockAclProvider, pr) { sccp.RegisterSysCC(cc) } diff --git a/core/chaincode/container_runtime.go b/core/chaincode/container_runtime.go index 904b09513eb..ea0b17e7cfb 100644 --- a/core/chaincode/container_runtime.go +++ b/core/chaincode/container_runtime.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/hyperledger/fabric/core/chaincode/accesscontrol" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/container" "github.com/hyperledger/fabric/core/container/ccintf" @@ -37,11 +38,12 @@ type CertGenerator interface { // ContainerRuntime is responsible for managing containerized chaincode. type ContainerRuntime struct { - CertGenerator CertGenerator - Processor Processor - CACert []byte - CommonEnv []string - PeerAddress string + CertGenerator CertGenerator + Processor Processor + CACert []byte + CommonEnv []string + PeerAddress string + PlatformRegistry *platforms.Registry } // Start launches chaincode in a runtime environment. @@ -59,7 +61,8 @@ func (c *ContainerRuntime) Start(ctxt context.Context, cccid *ccprovider.CCConte scr := container.StartContainerReq{ Builder: &container.PlatformBuilder{ - DeploymentSpec: cds, + DeploymentSpec: cds, + PlatformRegistry: c.PlatformRegistry, }, Args: lc.Args, Env: lc.Envs, diff --git a/core/chaincode/exectransaction_test.go b/core/chaincode/exectransaction_test.go index 3701986b456..cd1c8405fba 100644 --- a/core/chaincode/exectransaction_test.go +++ b/core/chaincode/exectransaction_test.go @@ -34,6 +34,8 @@ import ( "github.com/hyperledger/fabric/core/aclmgmt" aclmocks "github.com/hyperledger/fabric/core/aclmgmt/mocks" "github.com/hyperledger/fabric/core/chaincode/accesscontrol" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/config" @@ -125,6 +127,7 @@ func initPeer(chainIDs ...string) (net.Listener, *ChaincodeSupport, func(), erro certGenerator := accesscontrol.NewAuthenticator(ca) config := GlobalConfig() config.StartupTimeout = 3 * time.Minute + pr := platforms.NewRegistry(&golang.Platform{}) chaincodeSupport := NewChaincodeSupport( config, peerAddress, @@ -140,6 +143,7 @@ func initPeer(chainIDs ...string) (net.Listener, *ChaincodeSupport, func(), erro }, ), sccp, + pr, ) pb.RegisterChaincodeSupportServer(grpcServer, chaincodeSupport) @@ -147,7 +151,7 @@ func initPeer(chainIDs ...string) (net.Listener, *ChaincodeSupport, func(), erro policy.RegisterPolicyCheckerFactory(&mockPolicyCheckerFactory{}) ccp := &CCProviderImpl{cs: chaincodeSupport} - for _, cc := range scc.CreateSysCCs(ccp, sccp, mockAclProvider) { + for _, cc := range scc.CreateSysCCs(ccp, sccp, mockAclProvider, pr) { sccp.RegisterSysCC(cc) } @@ -352,7 +356,7 @@ func endTxSimulation(chainID string, ccid *pb.ChaincodeID, txsim ledger.TxSimula // Build a chaincode. func getDeploymentSpec(_ context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) { fmt.Printf("getting deployment spec for chaincode spec: %v\n", spec) - codePackageBytes, err := container.GetChaincodePackageBytes(spec) + codePackageBytes, err := container.GetChaincodePackageBytes(platforms.NewRegistry(&golang.Platform{}), spec) if err != nil { return nil, err } diff --git a/core/chaincode/platforms/car/platform.go b/core/chaincode/platforms/car/platform.go index e319e69551f..fd5489388a2 100644 --- a/core/chaincode/platforms/car/platform.go +++ b/core/chaincode/platforms/car/platform.go @@ -35,6 +35,11 @@ import ( type Platform struct { } +// Name returns the name of this platform +func (carPlatform *Platform) Name() string { + return pb.ChaincodeSpec_CAR.String() +} + // ValidateSpec validates the chaincode specification for CAR types to satisfy // the platform interface. This chaincode type currently doesn't // require anything specific so we just implicitly approve any spec diff --git a/core/chaincode/platforms/car/vm_helper_test.go b/core/chaincode/platforms/car/vm_helper_test.go index baf2cb6c6f5..21be4f40010 100644 --- a/core/chaincode/platforms/car/vm_helper_test.go +++ b/core/chaincode/platforms/car/vm_helper_test.go @@ -12,6 +12,7 @@ import ( "github.com/fsouza/go-dockerclient" "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/car" "github.com/hyperledger/fabric/core/container" cutil "github.com/hyperledger/fabric/core/container/util" pb "github.com/hyperledger/fabric/protos/peer" @@ -34,13 +35,13 @@ func NewVM() (*VM, error) { // BuildChaincodeContainer builds the container for the supplied chaincode specification func (vm *VM) BuildChaincodeContainer(spec *pb.ChaincodeSpec) error { - codePackage, err := container.GetChaincodePackageBytes(spec) + codePackage, err := container.GetChaincodePackageBytes(platforms.NewRegistry(&car.Platform{}), spec) if err != nil { return fmt.Errorf("Error getting chaincode package bytes: %s", err) } cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackage} - dockerSpec, err := platforms.NewRegistry().GenerateDockerBuild(cds) + dockerSpec, err := platforms.NewRegistry(&car.Platform{}).GenerateDockerBuild(cds) if err != nil { return fmt.Errorf("Error getting chaincode docker image: %s", err) } diff --git a/core/chaincode/platforms/golang/platform.go b/core/chaincode/platforms/golang/platform.go index 9333d3890f9..7758bb17b94 100644 --- a/core/chaincode/platforms/golang/platform.go +++ b/core/chaincode/platforms/golang/platform.go @@ -98,6 +98,11 @@ func filter(vs []string, f func(string) bool) []string { return vsf } +// Name returns the name of this platform +func (goPlatform *Platform) Name() string { + return pb.ChaincodeSpec_GOLANG.String() +} + // ValidateSpec validates Go chaincodes func (goPlatform *Platform) ValidateSpec(spec *pb.ChaincodeSpec) error { path, err := url.Parse(spec.ChaincodeId.Path) diff --git a/core/chaincode/platforms/java/platform.go b/core/chaincode/platforms/java/platform.go index c10b4c80df8..590703cb4f5 100644 --- a/core/chaincode/platforms/java/platform.go +++ b/core/chaincode/platforms/java/platform.go @@ -23,6 +23,11 @@ import ( type Platform struct { } +// Name returns the name of this platform +func (javaPlatform *Platform) Name() string { + return pb.ChaincodeSpec_JAVA.String() +} + //ValidateSpec validates the java chaincode specs func (javaPlatform *Platform) ValidateSpec(spec *pb.ChaincodeSpec) error { path, err := url.Parse(spec.ChaincodeId.Path) diff --git a/core/chaincode/platforms/mock/platform.go b/core/chaincode/platforms/mock/platform.go index 0cc805449b8..6136dd52609 100644 --- a/core/chaincode/platforms/mock/platform.go +++ b/core/chaincode/platforms/mock/platform.go @@ -10,6 +10,15 @@ import ( ) type Platform struct { + NameStub func() string + nameMutex sync.RWMutex + nameArgsForCall []struct{} + nameReturns struct { + result1 string + } + nameReturnsOnCall map[int]struct { + result1 string + } ValidateSpecStub func(spec *pb.ChaincodeSpec) error validateSpecMutex sync.RWMutex validateSpecArgsForCall []struct { @@ -85,6 +94,46 @@ type Platform struct { invocationsMutex sync.RWMutex } +func (fake *Platform) Name() string { + fake.nameMutex.Lock() + ret, specificReturn := fake.nameReturnsOnCall[len(fake.nameArgsForCall)] + fake.nameArgsForCall = append(fake.nameArgsForCall, struct{}{}) + fake.recordInvocation("Name", []interface{}{}) + fake.nameMutex.Unlock() + if fake.NameStub != nil { + return fake.NameStub() + } + if specificReturn { + return ret.result1 + } + return fake.nameReturns.result1 +} + +func (fake *Platform) NameCallCount() int { + fake.nameMutex.RLock() + defer fake.nameMutex.RUnlock() + return len(fake.nameArgsForCall) +} + +func (fake *Platform) NameReturns(result1 string) { + fake.NameStub = nil + fake.nameReturns = struct { + result1 string + }{result1} +} + +func (fake *Platform) NameReturnsOnCall(i int, result1 string) { + fake.NameStub = nil + if fake.nameReturnsOnCall == nil { + fake.nameReturnsOnCall = make(map[int]struct { + result1 string + }) + } + fake.nameReturnsOnCall[i] = struct { + result1 string + }{result1} +} + func (fake *Platform) ValidateSpec(spec *pb.ChaincodeSpec) error { fake.validateSpecMutex.Lock() ret, specificReturn := fake.validateSpecReturnsOnCall[len(fake.validateSpecArgsForCall)] @@ -383,6 +432,8 @@ func (fake *Platform) GetMetadataProviderReturnsOnCall(i int, result1 ccmetadata func (fake *Platform) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() + fake.nameMutex.RLock() + defer fake.nameMutex.RUnlock() fake.validateSpecMutex.RLock() defer fake.validateSpecMutex.RUnlock() fake.validateDeploymentSpecMutex.RLock() diff --git a/core/chaincode/platforms/node/platform.go b/core/chaincode/platforms/node/platform.go index b16f453a1ae..9692342a031 100644 --- a/core/chaincode/platforms/node/platform.go +++ b/core/chaincode/platforms/node/platform.go @@ -43,6 +43,11 @@ func pathExists(path string) (bool, error) { return true, err } +// Name returns the name of this platform +func (nodePlatform *Platform) Name() string { + return pb.ChaincodeSpec_NODE.String() +} + // ValidateSpec validates Go chaincodes func (nodePlatform *Platform) ValidateSpec(spec *pb.ChaincodeSpec) error { path, err := url.Parse(spec.ChaincodeId.Path) diff --git a/core/chaincode/platforms/platforms.go b/core/chaincode/platforms/platforms.go index 42344318f03..9bcfc8e70b8 100644 --- a/core/chaincode/platforms/platforms.go +++ b/core/chaincode/platforms/platforms.go @@ -16,11 +16,7 @@ import ( "github.com/hyperledger/fabric/common/flogging" "github.com/hyperledger/fabric/common/metadata" - "github.com/hyperledger/fabric/core/chaincode/platforms/car" "github.com/hyperledger/fabric/core/chaincode/platforms/ccmetadata" - "github.com/hyperledger/fabric/core/chaincode/platforms/golang" - "github.com/hyperledger/fabric/core/chaincode/platforms/java" - "github.com/hyperledger/fabric/core/chaincode/platforms/node" cutil "github.com/hyperledger/fabric/core/container/util" pb "github.com/hyperledger/fabric/protos/peer" ) @@ -28,6 +24,7 @@ import ( // Interface for validating the specification and and writing the package for // the given platform type Platform interface { + Name() string ValidateSpec(spec *pb.ChaincodeSpec) error ValidateDeploymentSpec(spec *pb.ChaincodeDeploymentSpec) error GetDeploymentPayload(spec *pb.ChaincodeSpec) ([]byte, error) @@ -53,15 +50,16 @@ type Registry struct { var logger = flogging.MustGetLogger("chaincode-platform") -// TODO, ultimately this should take the platforms as parameters -func NewRegistry() *Registry { +func NewRegistry(platformTypes ...Platform) *Registry { + platforms := make(map[string]Platform) + for _, platform := range platformTypes { + if _, ok := platforms[platform.Name()]; ok { + logger.Panicf("Multiple platforms of the same name specified: %s", platform.Name()) + } + platforms[platform.Name()] = platform + } return &Registry{ - Platforms: map[string]Platform{ - pb.ChaincodeSpec_GOLANG.String(): &golang.Platform{}, - pb.ChaincodeSpec_CAR.String(): &car.Platform{}, - pb.ChaincodeSpec_JAVA.String(): &java.Platform{}, - pb.ChaincodeSpec_NODE.String(): &node.Platform{}, - }, + Platforms: platforms, PackageWriter: PackageWriterWrapper(cutil.WriteBytesToPackage), } } diff --git a/core/chaincode/platforms/platforms_test.go b/core/chaincode/platforms/platforms_test.go index add8238c054..113865c8883 100644 --- a/core/chaincode/platforms/platforms_test.go +++ b/core/chaincode/platforms/platforms_test.go @@ -16,11 +16,7 @@ import ( "github.com/hyperledger/fabric/common/metadata" "github.com/hyperledger/fabric/core/chaincode/platforms" - "github.com/hyperledger/fabric/core/chaincode/platforms/car" - "github.com/hyperledger/fabric/core/chaincode/platforms/golang" - "github.com/hyperledger/fabric/core/chaincode/platforms/java" "github.com/hyperledger/fabric/core/chaincode/platforms/mock" - "github.com/hyperledger/fabric/core/chaincode/platforms/node" pb "github.com/hyperledger/fabric/protos/peer" . "github.com/onsi/ginkgo" @@ -297,14 +293,28 @@ ENV CORE_CHAINCODE_BUILDLEVEL=%s`, metadata.Version, metadata.BaseVersion, metad Describe("NewRegistry", func() { It("initializes with the known platform types and util writer", func() { - registry = platforms.NewRegistry() + fakePlatformFoo := &mock.Platform{} + fakePlatformFoo.NameReturns("foo") + fakePlatformBar := &mock.Platform{} + fakePlatformBar.NameReturns("bar") + + registry = platforms.NewRegistry(fakePlatformFoo, fakePlatformBar) + Expect(registry.Platforms).To(Equal(map[string]platforms.Platform{ - pb.ChaincodeSpec_GOLANG.String(): &golang.Platform{}, - pb.ChaincodeSpec_CAR.String(): &car.Platform{}, - pb.ChaincodeSpec_JAVA.String(): &java.Platform{}, - pb.ChaincodeSpec_NODE.String(): &node.Platform{}, + "foo": fakePlatformFoo, + "bar": fakePlatformBar, })) }) + + Context("when two platforms report the same name", func() { + It("panics", func() { + fakePlatformFoo1 := &mock.Platform{} + fakePlatformFoo1.NameReturns("foo") + fakePlatformFoo2 := &mock.Platform{} + fakePlatformFoo2.NameReturns("foo") + Expect(func() { platforms.NewRegistry(fakePlatformFoo1, fakePlatformFoo2) }).To(Panic()) + }) + }) }) Describe("PackageWriterWrapper", func() { diff --git a/core/chaincode/systemchaincode_test.go b/core/chaincode/systemchaincode_test.go index 970757de648..7d182b015b2 100644 --- a/core/chaincode/systemchaincode_test.go +++ b/core/chaincode/systemchaincode_test.go @@ -15,6 +15,8 @@ import ( "github.com/hyperledger/fabric/common/crypto/tlsgen" "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/core/chaincode/accesscontrol" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/container" @@ -141,6 +143,7 @@ func initSysCCTests() (*oldSysCCInfo, net.Listener, *ChaincodeSupport, error) { }, ), sccp, + platforms.NewRegistry(&golang.Platform{}), ) pb.RegisterChaincodeSupportServer(grpcServer, chaincodeSupport) diff --git a/core/committer/txvalidator/validator.go b/core/committer/txvalidator/validator.go index f957c1e79ef..b5259403ab3 100644 --- a/core/committer/txvalidator/validator.go +++ b/core/committer/txvalidator/validator.go @@ -14,6 +14,8 @@ import ( "github.com/hyperledger/fabric/common/configtx" commonerrors "github.com/hyperledger/fabric/common/errors" "github.com/hyperledger/fabric/common/flogging" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/common/sysccprovider" "github.com/hyperledger/fabric/core/common/validation" "github.com/hyperledger/fabric/core/ledger" @@ -563,7 +565,7 @@ func (v *TxValidator) getTxCCInstance(payload *common.Payload) (invokeCCIns, upg } func (v *TxValidator) getUpgradeTxInstance(chainID string, cdsBytes []byte) (*sysccprovider.ChaincodeInstance, error) { - cds, err := utils.GetChaincodeDeploymentSpec(cdsBytes) + cds, err := utils.GetChaincodeDeploymentSpec(cdsBytes, platforms.NewRegistry(&golang.Platform{})) if err != nil { return nil, err } diff --git a/core/common/ccprovider/cc_statedb_artifacts_provider.go b/core/common/ccprovider/cc_statedb_artifacts_provider.go index 8d9a70dba07..90288b5eea6 100644 --- a/core/common/ccprovider/cc_statedb_artifacts_provider.go +++ b/core/common/ccprovider/cc_statedb_artifacts_provider.go @@ -31,7 +31,7 @@ type TarFileEntry struct { // ExtractStatedbArtifactsAsTarbytes extracts the statedb artifacts from the code package tar and create a statedb artifact tar. // The state db artifacts are expected to contain state db specific artifacts such as index specification in the case of couchdb. // This function is intented to be used during chaincode instantiate/upgrade so that statedb artifacts can be created. -func ExtractStatedbArtifactsForChaincode(ccname, ccversion string) (installed bool, statedbArtifactsTar []byte, err error) { +func ExtractStatedbArtifactsForChaincode(ccname, ccversion string, pr *platforms.Registry) (installed bool, statedbArtifactsTar []byte, err error) { ccpackage, err := GetChaincodeFromFS(ccname, ccversion) if err != nil { // TODO for now, we assume that an error indicates that the chaincode is not installed on the peer. @@ -41,16 +41,16 @@ func ExtractStatedbArtifactsForChaincode(ccname, ccversion string) (installed bo return false, nil, nil } - statedbArtifactsTar, err = ExtractStatedbArtifactsFromCCPackage(ccpackage) + statedbArtifactsTar, err = ExtractStatedbArtifactsFromCCPackage(ccpackage, pr) return true, statedbArtifactsTar, err } // ExtractStatedbArtifactsFromCCPackage extracts the statedb artifacts from the code package tar and create a statedb artifact tar. // The state db artifacts are expected to contain state db specific artifacts such as index specification in the case of couchdb. // This function is called during chaincode instantiate/upgrade (from above), and from install, so that statedb artifacts can be created. -func ExtractStatedbArtifactsFromCCPackage(ccpackage CCPackage) (statedbArtifactsTar []byte, err error) { +func ExtractStatedbArtifactsFromCCPackage(ccpackage CCPackage, pr *platforms.Registry) (statedbArtifactsTar []byte, err error) { cds := ccpackage.GetDepSpec() - metaprov, err := platforms.NewRegistry().GetMetadataProvider(cds) + metaprov, err := pr.GetMetadataProvider(cds) if err != nil { ccproviderLogger.Infof("invalid deployment spec: %s", err) return nil, fmt.Errorf("invalid deployment spec") diff --git a/core/container/controller.go b/core/container/controller.go index 25fcce9dbe0..bce05114e6f 100644 --- a/core/container/controller.go +++ b/core/container/controller.go @@ -127,12 +127,13 @@ type StartContainerReq struct { // the dockercontroller package with the CDS, which is also // undesirable. type PlatformBuilder struct { - DeploymentSpec *pb.ChaincodeDeploymentSpec + DeploymentSpec *pb.ChaincodeDeploymentSpec + PlatformRegistry *platforms.Registry } // Build a tar stream based on the CDS func (b *PlatformBuilder) Build() (io.Reader, error) { - return platforms.NewRegistry().GenerateDockerBuild(b.DeploymentSpec) + return b.PlatformRegistry.GenerateDockerBuild(b.DeploymentSpec) } func (si StartContainerReq) Do(ctxt context.Context, v VM) error { @@ -195,10 +196,10 @@ func (vmc *VMController) Process(ctxt context.Context, vmtype string, req VMCReq } // GetChaincodePackageBytes creates bytes for docker container generation using the supplied chaincode specification -func GetChaincodePackageBytes(spec *pb.ChaincodeSpec) ([]byte, error) { +func GetChaincodePackageBytes(pr *platforms.Registry, spec *pb.ChaincodeSpec) ([]byte, error) { if spec == nil || spec.ChaincodeId == nil { return nil, fmt.Errorf("invalid chaincode spec") } - return platforms.NewRegistry().GetDeploymentPayload(spec) + return pr.GetDeploymentPayload(spec) } diff --git a/core/container/controller_test.go b/core/container/controller_test.go index a5ff2c14bd3..f0c13cf1d22 100644 --- a/core/container/controller_test.go +++ b/core/container/controller_test.go @@ -10,23 +10,25 @@ import ( "testing" "github.com/hyperledger/fabric/common/util" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/container" pb "github.com/hyperledger/fabric/protos/peer" "github.com/stretchr/testify/assert" ) func TestVM_GetChaincodePackageBytes(t *testing.T) { - _, err := container.GetChaincodePackageBytes(nil) + _, err := container.GetChaincodePackageBytes(nil, nil) assert.Error(t, err, "GetChaincodePackageBytes did not return error when chaincode spec is nil") spec := &pb.ChaincodeSpec{ChaincodeId: nil} - _, err = container.GetChaincodePackageBytes(spec) + _, err = container.GetChaincodePackageBytes(nil, spec) assert.Error(t, err, "Error expected when GetChaincodePackageBytes is called with nil chaincode ID") assert.Contains(t, err.Error(), "invalid chaincode spec") spec = &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: nil, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs("f")}} - _, err = container.GetChaincodePackageBytes(spec) + _, err = container.GetChaincodePackageBytes(platforms.NewRegistry(&golang.Platform{}), spec) assert.Error(t, err, "GetChaincodePackageBytes did not return error when chaincode ID is nil") } diff --git a/core/container/dockercontroller/dockercontroller_test.go b/core/container/dockercontroller/dockercontroller_test.go index 554b56d7861..dd94bbd5a2b 100644 --- a/core/container/dockercontroller/dockercontroller_test.go +++ b/core/container/dockercontroller/dockercontroller_test.go @@ -26,6 +26,7 @@ import ( "github.com/hyperledger/fabric/common/ledger/testutil" "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/container/ccintf" coreutil "github.com/hyperledger/fabric/core/testutil" pb "github.com/hyperledger/fabric/protos/peer" @@ -119,13 +120,13 @@ func Test_Start(t *testing.T) { ChaincodeId: &pb.ChaincodeID{Name: "ex01", Path: chaincodePath}, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs("f")}, } - codePackage, err := platforms.NewRegistry().GetDeploymentPayload(spec) + codePackage, err := platforms.NewRegistry(&golang.Platform{}).GetDeploymentPayload(spec) if err != nil { t.Fatal() } cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackage} bldr := &mockBuilder{ - buildFunc: func() (io.Reader, error) { return platforms.NewRegistry().GenerateDockerBuild(cds) }, + buildFunc: func() (io.Reader, error) { return platforms.NewRegistry(&golang.Platform{}).GenerateDockerBuild(cds) }, } // case 4: start called with builder and dockerClient.CreateContainer returns diff --git a/core/endorser/endorser.go b/core/endorser/endorser.go index 2d29f43a4ed..c829198279c 100644 --- a/core/endorser/endorser.go +++ b/core/endorser/endorser.go @@ -15,6 +15,7 @@ import ( "github.com/hyperledger/fabric/common/flogging" "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/core/chaincode" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/common/validation" @@ -96,6 +97,7 @@ type Support interface { type Endorser struct { distributePrivateData privateDataDistributor s Support + PlatformRegistry *platforms.Registry PvtRWSetAssembler } @@ -109,10 +111,11 @@ type validateResult struct { } // NewEndorserServer creates and returns a new Endorser server instance. -func NewEndorserServer(privDist privateDataDistributor, s Support) *Endorser { +func NewEndorserServer(privDist privateDataDistributor, s Support, pr *platforms.Registry) *Endorser { e := &Endorser{ distributePrivateData: privDist, s: s, + PlatformRegistry: pr, PvtRWSetAssembler: &rwSetAssembler{}, } return e @@ -154,7 +157,7 @@ func (e *Endorser) callChaincode(ctxt context.Context, chainID string, version s // NOTE that if there's an error all simulation, including the chaincode // table changes in lscc will be thrown away if cid.Name == "lscc" && len(cis.ChaincodeSpec.Input.Args) >= 3 && (string(cis.ChaincodeSpec.Input.Args[0]) == "deploy" || string(cis.ChaincodeSpec.Input.Args[0]) == "upgrade") { - userCDS, err := putils.GetChaincodeDeploymentSpec(cis.ChaincodeSpec.Input.Args[2]) + userCDS, err := putils.GetChaincodeDeploymentSpec(cis.ChaincodeSpec.Input.Args[2], e.PlatformRegistry) if err != nil { return nil, nil, err } diff --git a/core/endorser/endorser_test.go b/core/endorser/endorser_test.go index d5a81929312..411b752cab1 100644 --- a/core/endorser/endorser_test.go +++ b/core/endorser/endorser_test.go @@ -16,6 +16,8 @@ import ( mc "github.com/hyperledger/fabric/common/mocks/config" "github.com/hyperledger/fabric/common/mocks/resourcesconfig" "github.com/hyperledger/fabric/common/util" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/endorser" "github.com/hyperledger/fabric/core/endorser/mocks" @@ -86,7 +88,7 @@ func TestEndorserNilProp(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) pResp, err := es.ProcessProposal(context.Background(), nil) assert.Error(t, err) @@ -100,7 +102,7 @@ func TestEndorserUninvokableSysCC(t *testing.T) { GetApplicationConfigRv: &mc.MockApplication{CapabilitiesRv: &mc.MockApplicationCapabilities{}}, GetTransactionByIDErr: errors.New(""), IsSysCCAndNotInvokableExternalRv: true, - }) + }, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -122,7 +124,7 @@ func TestEndorserCCInvocationFailed(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -144,7 +146,7 @@ func TestEndorserNoCCDef(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -167,7 +169,7 @@ func TestEndorserBadInstPolicy(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -191,7 +193,7 @@ func TestEndorserSysCC(t *testing.T) { ExecuteResp: &pb.Response{Status: 200, Payload: utils.MarshalOrPanic(&pb.ProposalResponse{Response: &pb.Response{}})}, } attachPluginEndorser(support) - es := endorser.NewEndorserServer(pvtEmptyDistributor, support) + es := endorser.NewEndorserServer(pvtEmptyDistributor, support, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -212,7 +214,7 @@ func TestEndorserCCInvocationError(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -233,7 +235,7 @@ func TestEndorserLSCCBadType(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) cds := utils.MarshalOrPanic( &pb.ChaincodeDeploymentSpec{ @@ -262,7 +264,7 @@ func TestEndorserDupTXId(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -285,7 +287,7 @@ func TestEndorserBadACL(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -306,7 +308,7 @@ func TestEndorserGoodPathEmptyChannel(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedPropWithCHIdAndArgs("", "ccid", "0", [][]byte{[]byte("args")}, t) @@ -328,7 +330,7 @@ func TestEndorserLSCCInitFails(t *testing.T) { }, }, ExecuteCDSError: errors.New(""), - }) + }, platforms.NewRegistry(&golang.Platform{})) cds := utils.MarshalOrPanic( &pb.ChaincodeDeploymentSpec{ @@ -361,7 +363,7 @@ func TestEndorserLSCCDeploySysCC(t *testing.T) { }, }, SysCCMap: SysCCMap, - }) + }, platforms.NewRegistry(&golang.Platform{})) cds := utils.MarshalOrPanic( &pb.ChaincodeDeploymentSpec{ @@ -396,7 +398,7 @@ func TestEndorserLSCCJava1(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) cds := utils.MarshalOrPanic( &pb.ChaincodeDeploymentSpec{ @@ -431,7 +433,7 @@ func TestEndorserLSCCJava2(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) cds := utils.MarshalOrPanic( &pb.ChaincodeDeploymentSpec{ @@ -463,7 +465,7 @@ func TestEndorserGoodPathWEvents(t *testing.T) { ExecuteEvent: &pb.ChaincodeEvent{}, } attachPluginEndorser(support) - es := endorser.NewEndorserServer(pvtEmptyDistributor, support) + es := endorser.NewEndorserServer(pvtEmptyDistributor, support, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -484,7 +486,7 @@ func TestEndorserBadChannel(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedPropWithCHID("ccid", "0", "barfchain", t) @@ -508,7 +510,7 @@ func TestEndorserGoodPath(t *testing.T) { ExecuteResp: &pb.Response{Status: 200, Payload: utils.MarshalOrPanic(&pb.ProposalResponse{Response: &pb.Response{}})}, } attachPluginEndorser(support) - es := endorser.NewEndorserServer(pvtEmptyDistributor, support) + es := endorser.NewEndorserServer(pvtEmptyDistributor, support, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -531,7 +533,7 @@ func TestEndorserLSCC(t *testing.T) { ExecuteResp: &pb.Response{Status: 200, Payload: utils.MarshalOrPanic(&pb.ProposalResponse{Response: &pb.Response{}})}, } attachPluginEndorser(support) - es := endorser.NewEndorserServer(pvtEmptyDistributor, support) + es := endorser.NewEndorserServer(pvtEmptyDistributor, support, platforms.NewRegistry(&golang.Platform{})) cds := utils.MarshalOrPanic( &pb.ChaincodeDeploymentSpec{ @@ -579,7 +581,7 @@ func TestEndorseWithPlugin(t *testing.T) { } attachPluginEndorser(support) - es := endorser.NewEndorserServer(pvtEmptyDistributor, support) + es := endorser.NewEndorserServer(pvtEmptyDistributor, support, platforms.NewRegistry(&golang.Platform{})) signedProp := getSignedProp("ccid", "0", t) @@ -602,7 +604,7 @@ func TestSimulateProposal(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) _, _, _, _, err := es.SimulateProposal(nil, "", "", nil, nil, nil, nil) assert.Error(t, err) @@ -624,7 +626,7 @@ func TestEndorserJavaChecks(t *testing.T) { PubSimulationResults: &rwset.TxReadWriteSet{}, }, }, - }) + }, platforms.NewRegistry(&golang.Platform{})) err := es.DisableJavaCCInst(&pb.ChaincodeID{Name: "lscc"}, &pb.ChaincodeInvocationSpec{}) assert.NoError(t, err) @@ -666,7 +668,11 @@ func TestEndorserAcquireTxSimulator(t *testing.T) { ExecuteResp: expectedResponse, } attachPluginEndorser(support) - es := endorser.NewEndorserServer(pvtEmptyDistributor, support) + es := endorser.NewEndorserServer( + pvtEmptyDistributor, + support, + platforms.NewRegistry(&golang.Platform{}), + ) t.Parallel() args := [][]byte{[]byte("args")} @@ -713,7 +719,7 @@ type support interface { func TestUserCDSSanitization(t *testing.T) { fakeSupport := &mocks.Support{} - e := endorser.NewEndorserServer(nil, fakeSupport) + e := endorser.NewEndorserServer(nil, fakeSupport, nil) userCDS := &pb.ChaincodeDeploymentSpec{ ChaincodeSpec: &pb.ChaincodeSpec{ diff --git a/core/handlers/validation/builtin/validation_logic.go b/core/handlers/validation/builtin/validation_logic.go index 1d68ee3f709..974219abf45 100644 --- a/core/handlers/validation/builtin/validation_logic.go +++ b/core/handlers/validation/builtin/validation_logic.go @@ -17,6 +17,11 @@ import ( "github.com/hyperledger/fabric/common/channelconfig" commonerrors "github.com/hyperledger/fabric/common/errors" "github.com/hyperledger/fabric/common/flogging" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/car" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" + "github.com/hyperledger/fabric/core/chaincode/platforms/java" + "github.com/hyperledger/fabric/core/chaincode/platforms/node" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/common/privdata" . "github.com/hyperledger/fabric/core/handlers/validation/api/capabilities" @@ -494,7 +499,17 @@ func (vscc *ValidatorOneValidSignature) ValidateLSCCInvocation( return policyErr(fmt.Errorf("Wrong number of arguments for invocation lscc(%s): received %d", lsccFunc, len(lsccArgs))) } - cdsArgs, err := utils.GetChaincodeDeploymentSpec(lsccArgs[1]) + cdsArgs, err := utils.GetChaincodeDeploymentSpec(lsccArgs[1], platforms.NewRegistry( + // XXX We should definitely _not_ have this external dependency in VSCC + // as adding a platform could cause non-determinism. This is yet another + // reason why all of this custom LSCC validation at commit time has no + // long term hope of staying deterministic and needs to be removed. + &golang.Platform{}, + &node.Platform{}, + &java.Platform{}, + &car.Platform{}, + )) + if err != nil { return policyErr(fmt.Errorf("GetChaincodeDeploymentSpec error %s", err)) } diff --git a/core/handlers/validation/builtin/validation_logic_test.go b/core/handlers/validation/builtin/validation_logic_test.go index cbb0cace9e0..06465071280 100644 --- a/core/handlers/validation/builtin/validation_logic_test.go +++ b/core/handlers/validation/builtin/validation_logic_test.go @@ -22,6 +22,8 @@ import ( "github.com/hyperledger/fabric/common/mocks/scc" "github.com/hyperledger/fabric/common/util" aclmocks "github.com/hyperledger/fabric/core/aclmgmt/mocks" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/committer/txvalidator" mocks2 "github.com/hyperledger/fabric/core/committer/txvalidator/mocks" @@ -424,7 +426,7 @@ func TestRWSetTooBig(t *testing.T) { v := newValidationInstance(state) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -483,7 +485,7 @@ func TestValidateDeployFail(t *testing.T) { v := newValidationInstance(state) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -741,7 +743,7 @@ func TestAlreadyDeployed(t *testing.T) { v := newValidationInstance(state) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -838,7 +840,7 @@ func TestValidateDeployOK(t *testing.T) { v := newValidationInstance(state) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -887,7 +889,7 @@ func TestValidateDeployWithCollection(t *testing.T) { }) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -978,7 +980,7 @@ func TestValidateDeployWithCollection(t *testing.T) { v = newValidationInstance(state) - lccc = lscc.New(mp, mockAclProvider) + lccc = lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc = shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -1002,7 +1004,7 @@ func TestValidateDeployWithPolicies(t *testing.T) { v := newValidationInstance(state) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -1073,7 +1075,7 @@ func TestInvalidUpgrade(t *testing.T) { v := newValidationInstance(state) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -1114,7 +1116,7 @@ func TestValidateUpgradeOK(t *testing.T) { v := newValidationInstance(state) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -1180,7 +1182,7 @@ func TestInvalidateUpgradeBadVersion(t *testing.T) { v := newValidationInstance(state) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -1252,7 +1254,7 @@ func validateUpgradeWithCollection(t *testing.T, V1_2Validation bool) { }) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -1440,7 +1442,7 @@ func TestValidateUpgradeWithPoliciesOK(t *testing.T) { v := newValidationInstance(state) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -1529,7 +1531,7 @@ func validateUpgradeWithNewFailAllIP(t *testing.T, v11capability, expecterr bool v := newCustomValidationInstance(qec, capabilities) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State @@ -1609,7 +1611,7 @@ func TestValidateUpgradeWithPoliciesFail(t *testing.T) { v := newValidationInstance(state) mockAclProvider := &aclmocks.MockACLProvider{} - lccc := lscc.New(mp, mockAclProvider) + lccc := lscc.New(mp, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) stublccc := shim.NewMockStub("lscc", lccc) state["lscc"] = stublccc.State diff --git a/core/ledger/cceventmgmt/defs.go b/core/ledger/cceventmgmt/defs.go index 770343dd315..c74bacc0ad1 100644 --- a/core/ledger/cceventmgmt/defs.go +++ b/core/ledger/cceventmgmt/defs.go @@ -9,6 +9,7 @@ package cceventmgmt import ( "fmt" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/common/sysccprovider" ) @@ -50,6 +51,7 @@ type ChaincodeInfoProvider interface { } type chaincodeInfoProviderImpl struct { + PlatformRegistry *platforms.Registry } // IsChaincodeDeployed implements function in the interface ChaincodeInfoProvider @@ -59,5 +61,5 @@ func (p *chaincodeInfoProviderImpl) IsChaincodeDeployed(chainid string, chaincod // RetrieveChaincodeArtifacts implements function in the interface ChaincodeInfoProvider func (p *chaincodeInfoProviderImpl) RetrieveChaincodeArtifacts(chaincodeDefinition *ChaincodeDefinition) (installed bool, dbArtifactsTar []byte, err error) { - return ccprovider.ExtractStatedbArtifactsForChaincode(chaincodeDefinition.Name, chaincodeDefinition.Version) + return ccprovider.ExtractStatedbArtifactsForChaincode(chaincodeDefinition.Name, chaincodeDefinition.Version, p.PlatformRegistry) } diff --git a/core/ledger/cceventmgmt/mgr.go b/core/ledger/cceventmgmt/mgr.go index 2286e444b6e..36069ce1649 100644 --- a/core/ledger/cceventmgmt/mgr.go +++ b/core/ledger/cceventmgmt/mgr.go @@ -10,6 +10,7 @@ import ( "sync" "github.com/hyperledger/fabric/common/flogging" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/common/sysccprovider" ) @@ -18,8 +19,8 @@ var logger = flogging.MustGetLogger("cceventmgmt") var mgr *Mgr // Initialize initializes event mgmt -func Initialize() { - initialize(&chaincodeInfoProviderImpl{}) +func Initialize(pr *platforms.Registry) { + initialize(&chaincodeInfoProviderImpl{PlatformRegistry: pr}) } func initialize(ccInfoProvider ChaincodeInfoProvider) { diff --git a/core/ledger/kvledger/example/main/example.go b/core/ledger/kvledger/example/main/example.go index 70810a79874..72564125138 100644 --- a/core/ledger/kvledger/example/main/example.go +++ b/core/ledger/kvledger/example/main/example.go @@ -21,6 +21,8 @@ import ( "os" configtxtest "github.com/hyperledger/fabric/common/configtx/test" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/ledger" "github.com/hyperledger/fabric/core/ledger/kvledger/example" "github.com/hyperledger/fabric/core/ledger/ledgerconfig" @@ -53,7 +55,7 @@ func init() { // Note, if subledgers are supported in the future, // the various ledgers could be created/managed at this level cleanup() - ledgermgmt.Initialize(nil) + ledgermgmt.Initialize(nil, platforms.NewRegistry(&golang.Platform{})) var err error gb, _ := configtxtest.MakeGenesisBlock(ledgerID) diff --git a/core/ledger/kvledger/marble_example/main/marble_example.go b/core/ledger/kvledger/marble_example/main/marble_example.go index cb6432fd649..6b4c53084e6 100644 --- a/core/ledger/kvledger/marble_example/main/marble_example.go +++ b/core/ledger/kvledger/marble_example/main/marble_example.go @@ -22,6 +22,8 @@ import ( "os" configtxtest "github.com/hyperledger/fabric/common/configtx/test" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/ledger" "github.com/hyperledger/fabric/core/ledger/kvledger/example" "github.com/hyperledger/fabric/core/ledger/ledgerconfig" @@ -54,7 +56,7 @@ func init() { testutil.SetupCoreYAMLConfig() cleanup() - ledgermgmt.Initialize(nil) + ledgermgmt.Initialize(nil, platforms.NewRegistry(&golang.Platform{})) var err error gb, _ := configtxtest.MakeGenesisBlock(ledgerID) peerLedger, err = ledgermgmt.CreateLedger(gb) diff --git a/core/ledger/ledgermgmt/ledger_mgmt.go b/core/ledger/ledgermgmt/ledger_mgmt.go index 35031c34eb5..66f0cbbeee9 100644 --- a/core/ledger/ledgermgmt/ledger_mgmt.go +++ b/core/ledger/ledgermgmt/ledger_mgmt.go @@ -25,6 +25,7 @@ import ( "fmt" "github.com/hyperledger/fabric/common/flogging" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/ledger" "github.com/hyperledger/fabric/core/ledger/customtx" "github.com/hyperledger/fabric/core/ledger/kvledger" @@ -47,20 +48,20 @@ var initialized bool var once sync.Once // Initialize initializes ledgermgmt -func Initialize(customTxProcessors customtx.Processors) { +func Initialize(customTxProcessors customtx.Processors, pr *platforms.Registry) { once.Do(func() { - initialize(customTxProcessors, nil) + initialize(customTxProcessors, nil, pr) }) } -func initialize(customTxProcessors customtx.Processors, statelisteners []ledger.StateListener) { +func initialize(customTxProcessors customtx.Processors, statelisteners []ledger.StateListener, pr *platforms.Registry) { logger.Info("Initializing ledger mgmt") lock.Lock() defer lock.Unlock() initialized = true openedLedgers = make(map[string]ledger.PeerLedger) customtx.Initialize(customTxProcessors) - cceventmgmt.Initialize() + cceventmgmt.Initialize(pr) finalStateListeners := addListenerForCCEventsHandler(statelisteners) provider, err := kvledger.NewProvider() if err != nil { diff --git a/core/ledger/ledgermgmt/ledger_mgmt_test.go b/core/ledger/ledgermgmt/ledger_mgmt_test.go index 5b0abfcf64c..050c3ce667d 100644 --- a/core/ledger/ledgermgmt/ledger_mgmt_test.go +++ b/core/ledger/ledgermgmt/ledger_mgmt_test.go @@ -24,6 +24,8 @@ import ( "github.com/hyperledger/fabric/common/configtx/test" "github.com/hyperledger/fabric/common/ledger/testutil" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/ledger" "github.com/spf13/viper" ) @@ -85,7 +87,7 @@ func TestLedgerMgmt(t *testing.T) { Close() // Restart ledger mgmt with existing ledgers - Initialize(nil) + Initialize(nil, platforms.NewRegistry(&golang.Platform{})) l, err = OpenLedger(ledgerID) testutil.AssertNoError(t, err, "") Close() diff --git a/core/ledger/ledgermgmt/ledger_mgmt_test_exports.go b/core/ledger/ledgermgmt/ledger_mgmt_test_exports.go index f398e97147f..f3e39272f3d 100644 --- a/core/ledger/ledgermgmt/ledger_mgmt_test_exports.go +++ b/core/ledger/ledgermgmt/ledger_mgmt_test_exports.go @@ -19,6 +19,8 @@ package ledgermgmt import ( "os" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/ledger/customtx" "github.com/hyperledger/fabric/core/ledger/ledgerconfig" @@ -29,14 +31,14 @@ import ( // InitializeTestEnv initializes ledgermgmt for tests func InitializeTestEnv() { remove() - initialize(nil, nil) + initialize(nil, nil, platforms.NewRegistry(&golang.Platform{})) } // InitializeTestEnvWithCustomProcessors initializes ledgermgmt for tests with the supplied custom tx processors func InitializeTestEnvWithCustomProcessors(customTxProcessors customtx.Processors) { remove() customtx.InitializeTestEnv(customTxProcessors) - initialize(customTxProcessors, nil) + initialize(customTxProcessors, nil, platforms.NewRegistry(&golang.Platform{})) } // CleanupTestEnv closes the ledgermagmt and removes the store directory diff --git a/core/peer/peer.go b/core/peer/peer.go index d5fdd8d961f..bf8ae81e1e1 100644 --- a/core/peer/peer.go +++ b/core/peer/peer.go @@ -21,6 +21,7 @@ import ( "github.com/hyperledger/fabric/common/ledger/blockledger" fileledger "github.com/hyperledger/fabric/common/ledger/blockledger/file" "github.com/hyperledger/fabric/common/policies" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/comm" "github.com/hyperledger/fabric/core/committer" "github.com/hyperledger/fabric/core/committer/txvalidator" @@ -188,7 +189,7 @@ var validationWorkersSemaphore *semaphore.Weighted // Initialize sets up any chains that the peer has from the persistence. This // function should be called at the start up when the ledger and gossip // ready -func Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, pm txvalidator.PluginMapper) { +func Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, pm txvalidator.PluginMapper, pr *platforms.Registry) { nWorkers := viper.GetInt("peer.validatorPoolSize") if nWorkers <= 0 { nWorkers = runtime.NumCPU() @@ -200,7 +201,7 @@ func Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccp var cb *common.Block var ledger ledger.PeerLedger - ledgermgmt.Initialize(ConfigTxProcessors) + ledgermgmt.Initialize(ConfigTxProcessors, pr) ledgerIds, err := ledgermgmt.GetLedgerIDs() if err != nil { panic(fmt.Errorf("Error in initializing ledgermgmt: %s", err)) diff --git a/core/peer/peer_impl.go b/core/peer/peer_impl.go index bd49684527f..60133920ce5 100644 --- a/core/peer/peer_impl.go +++ b/core/peer/peer_impl.go @@ -9,6 +9,7 @@ package peer import ( "github.com/hyperledger/fabric/common/channelconfig" "github.com/hyperledger/fabric/common/policies" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/committer/txvalidator" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/common/sysccprovider" @@ -29,7 +30,7 @@ type Operations interface { GetMSPIDs(cid string) []string GetPolicyManager(cid string) policies.Manager InitChain(cid string) - Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, pm txvalidator.PluginMapper) + Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, pm txvalidator.PluginMapper, pr *platforms.Registry) } type peerImpl struct { @@ -41,7 +42,7 @@ type peerImpl struct { getMSPIDs func(cid string) []string getPolicyManager func(cid string) policies.Manager initChain func(cid string) - initialize func(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, mapper txvalidator.PluginMapper) + initialize func(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, mapper txvalidator.PluginMapper, pr *platforms.Registry) } // Default provides in implementation of the Peer interface that provides @@ -72,6 +73,6 @@ func (p *peerImpl) GetLedger(cid string) ledger.PeerLedger { return p.getL func (p *peerImpl) GetMSPIDs(cid string) []string { return p.getMSPIDs(cid) } func (p *peerImpl) GetPolicyManager(cid string) policies.Manager { return p.getPolicyManager(cid) } func (p *peerImpl) InitChain(cid string) { p.initChain(cid) } -func (p *peerImpl) Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, mapper txvalidator.PluginMapper) { - p.initialize(init, ccp, sccp, mapper) +func (p *peerImpl) Initialize(init func(string), ccp ccprovider.ChaincodeProvider, sccp sysccprovider.SystemChaincodeProvider, mapper txvalidator.PluginMapper, pr *platforms.Registry) { + p.initialize(init, ccp, sccp, mapper, pr) } diff --git a/core/peer/peer_test.go b/core/peer/peer_test.go index bafa94b801b..db922519ecf 100644 --- a/core/peer/peer_test.go +++ b/core/peer/peer_test.go @@ -15,6 +15,7 @@ import ( configtxtest "github.com/hyperledger/fabric/common/configtx/test" "github.com/hyperledger/fabric/common/localmsp" mscc "github.com/hyperledger/fabric/common/mocks/scc" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/comm" "github.com/hyperledger/fabric/core/committer/txvalidator" "github.com/hyperledger/fabric/core/deliverservice" @@ -84,14 +85,14 @@ func TestInitialize(t *testing.T) { cleanup := setupPeerFS(t) defer cleanup() - Initialize(nil, &ccprovider.MockCcProviderImpl{}, (&mscc.MocksccProviderFactory{}).NewSystemChaincodeProvider(), txvalidator.MapBasedPluginMapper(map[string]validation.PluginFactory{})) + Initialize(nil, &ccprovider.MockCcProviderImpl{}, (&mscc.MocksccProviderFactory{}).NewSystemChaincodeProvider(), txvalidator.MapBasedPluginMapper(map[string]validation.PluginFactory{}), nil) } func TestCreateChainFromBlock(t *testing.T) { cleanup := setupPeerFS(t) defer cleanup() - Initialize(nil, &ccprovider.MockCcProviderImpl{}, (&mscc.MocksccProviderFactory{}).NewSystemChaincodeProvider(), txvalidator.MapBasedPluginMapper(map[string]validation.PluginFactory{})) + Initialize(nil, &ccprovider.MockCcProviderImpl{}, (&mscc.MocksccProviderFactory{}).NewSystemChaincodeProvider(), txvalidator.MapBasedPluginMapper(map[string]validation.PluginFactory{}), &platforms.Registry{}) testChainID := fmt.Sprintf("mytestchainid-%d", rand.Int()) block, err := configtxtest.MakeGenesisBlock(testChainID) if err != nil { diff --git a/core/scc/cscc/configure_test.go b/core/scc/cscc/configure_test.go index 8d1c69c7fc1..109f0803283 100644 --- a/core/scc/cscc/configure_test.go +++ b/core/scc/cscc/configure_test.go @@ -29,6 +29,8 @@ import ( "github.com/hyperledger/fabric/core/aclmgmt/resources" "github.com/hyperledger/fabric/core/chaincode" "github.com/hyperledger/fabric/core/chaincode/accesscontrol" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/container" @@ -229,6 +231,7 @@ func TestConfigerInvokeJoinChainCorrectParams(t *testing.T) { }, ), mp, + platforms.NewRegistry(&golang.Platform{}), ) // Init the policy checker diff --git a/core/scc/importsysccs.go b/core/scc/importsysccs.go index a2f991e6ce9..f294e170201 100644 --- a/core/scc/importsysccs.go +++ b/core/scc/importsysccs.go @@ -9,13 +9,14 @@ package scc import ( //import system chaincodes here "github.com/hyperledger/fabric/core/aclmgmt" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/scc/cscc" "github.com/hyperledger/fabric/core/scc/lscc" "github.com/hyperledger/fabric/core/scc/qscc" ) -func builtInSystemChaincodes(ccp ccprovider.ChaincodeProvider, p *Provider, aclProvider aclmgmt.ACLProvider) []*SystemChaincode { +func builtInSystemChaincodes(ccp ccprovider.ChaincodeProvider, p *Provider, aclProvider aclmgmt.ACLProvider, pr *platforms.Registry) []*SystemChaincode { return []*SystemChaincode{ { Enabled: true, @@ -30,7 +31,7 @@ func builtInSystemChaincodes(ccp ccprovider.ChaincodeProvider, p *Provider, aclP Name: "lscc", Path: "github.com/hyperledger/fabric/core/scc/lscc", InitArgs: nil, - Chaincode: lscc.New(p, aclProvider), + Chaincode: lscc.New(p, aclProvider, pr), InvokableExternal: true, // lscc is invoked to deploy new chaincodes InvokableCC2CC: true, // lscc can be invoked by other chaincodes }, diff --git a/core/scc/lscc/lscc.go b/core/scc/lscc/lscc.go index d1e1d65166b..853c54d048a 100644 --- a/core/scc/lscc/lscc.go +++ b/core/scc/lscc/lscc.go @@ -15,6 +15,7 @@ import ( "github.com/hyperledger/fabric/common/flogging" "github.com/hyperledger/fabric/core/aclmgmt" "github.com/hyperledger/fabric/core/aclmgmt/resources" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/chaincode/platforms/ccmetadata" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/common/ccprovider" @@ -129,16 +130,19 @@ type lifeCycleSysCC struct { // support provides the implementation of several // static functions support FilesystemSupport + + PlatformRegistry *platforms.Registry } // New creates a new instance of the LSCC // Typically there is only one of these per peer -func New(sccp sysccprovider.SystemChaincodeProvider, aclProvider aclmgmt.ACLProvider) *lifeCycleSysCC { +func New(sccp sysccprovider.SystemChaincodeProvider, aclProvider aclmgmt.ACLProvider, platformRegistry *platforms.Registry) *lifeCycleSysCC { return &lifeCycleSysCC{ - support: &supportImpl{}, - policyChecker: policyprovider.GetPolicyChecker(), - sccprovider: sccp, - aclProvider: aclProvider, + support: &supportImpl{}, + policyChecker: policyprovider.GetPolicyChecker(), + sccprovider: sccp, + aclProvider: aclProvider, + PlatformRegistry: platformRegistry, } } @@ -499,7 +503,7 @@ func (lscc *lifeCycleSysCC) executeInstall(stub shim.ChaincodeStubInterface, ccb } // Get any statedb artifacts from the chaincode package, e.g. couchdb index definitions - statedbArtifactsTar, err := ccprovider.ExtractStatedbArtifactsFromCCPackage(ccpack) + statedbArtifactsTar, err := ccprovider.ExtractStatedbArtifactsFromCCPackage(ccpack, lscc.PlatformRegistry) if err != nil { return err } @@ -779,7 +783,7 @@ func (lscc *lifeCycleSysCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response } depSpec := args[2] - cds, err := utils.GetChaincodeDeploymentSpec(depSpec) + cds, err := utils.GetChaincodeDeploymentSpec(depSpec, lscc.PlatformRegistry) if err != nil { return shim.Error(err.Error()) } diff --git a/core/scc/lscc/lscc_test.go b/core/scc/lscc/lscc_test.go index 7940f30e76f..0c0d0de1b50 100644 --- a/core/scc/lscc/lscc_test.go +++ b/core/scc/lscc/lscc_test.go @@ -23,6 +23,8 @@ import ( "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/core/aclmgmt/mocks" "github.com/hyperledger/fabric/core/aclmgmt/resources" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/common/ccprovider" cutil "github.com/hyperledger/fabric/core/container/util" @@ -44,7 +46,7 @@ import ( ) func constructDeploymentSpec(name string, path string, version string, initArgs [][]byte, createInvalidIndex bool, createFS bool, scc *lifeCycleSysCC) (*pb.ChaincodeDeploymentSpec, error) { - spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: name, Path: path, Version: version}, Input: &pb.ChaincodeInput{Args: initArgs}} + spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: name, Path: path, Version: version}, Input: &pb.ChaincodeInput{Args: initArgs}} codePackageBytes := bytes.NewBuffer(nil) gz := gzip.NewWriter(codePackageBytes) @@ -96,9 +98,9 @@ func constructDeploymentSpec(name string, path string, version string, initArgs func TestInstall(t *testing.T) { // Initialize cceventmgmt Mgr // TODO cceventmgmt singleton should be refactored out of peer in the future. See CR 16549 for details. - cceventmgmt.Initialize() + cceventmgmt.Initialize(platforms.NewRegistry(&golang.Platform{})) - scc := New(NewMockProvider(), mockAclProvider) + scc := New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub := shim.NewMockStub("lscc", scc) res := stub.MockInit("1", nil) @@ -179,7 +181,7 @@ func TestDeploy(t *testing.T) { testDeploy(t, "example02", "1{}0", path, false, false, true, InvalidVersionErr("1{}0").Error(), nil, nil, nil) testDeploy(t, "example02", "0", path, true, true, true, EmptyChaincodeNameErr("").Error(), nil, nil, nil) - scc := New(NewMockProvider(), mockAclProvider) + scc := New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub := shim.NewMockStub("lscc", scc) res := stub.MockInit("1", nil) @@ -200,7 +202,7 @@ func TestDeploy(t *testing.T) { testDeploy(t, "example02", "1.0", path, false, false, true, "", scc, stub, nil) testDeploy(t, "example02", "1.0", path, false, false, true, "chaincode with name 'example02' already exists", scc, stub, nil) - scc = New(NewMockProvider(), mockAclProvider) + scc = New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -209,7 +211,7 @@ func TestDeploy(t *testing.T) { testDeploy(t, "example02", "1.0", path, false, false, true, "barf", scc, stub, nil) - scc = New(NewMockProvider(), mockAclProvider) + scc = New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -218,7 +220,7 @@ func TestDeploy(t *testing.T) { testDeploy(t, "example02", "1.0", path, false, false, true, "barf", scc, stub, nil) - scc = New(NewMockProvider(), mockAclProvider) + scc = New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -239,7 +241,7 @@ func TestDeploy(t *testing.T) { }, }).NewSystemChaincodeProvider().(*mscc.MocksccProviderImpl) - scc = New(mocksccProvider, mockAclProvider) + scc = New(mocksccProvider, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -266,7 +268,7 @@ func TestDeploy(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, ccpBytes) - scc = New(mocksccProvider, mockAclProvider) + scc = New(mocksccProvider, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -282,7 +284,7 @@ func TestDeploy(t *testing.T) { assert.Equal(t, true, ok) assert.Equal(t, ccpBytes, actualccpBytes) - scc = New(mocksccProvider, mockAclProvider) + scc = New(mocksccProvider, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -321,7 +323,7 @@ func createCollectionConfig(collectionName string, signaturePolicyEnvelope *comm func testDeploy(t *testing.T, ccname string, version string, path string, forceBlankCCName bool, forceBlankVersion bool, install bool, expectedErrorMsg string, scc *lifeCycleSysCC, stub *shim.MockStub, collectionConfigBytes []byte) { if scc == nil { - scc = New(NewMockProvider(), mockAclProvider) + scc = New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res := stub.MockInit("1", nil) @@ -436,7 +438,7 @@ func TestUpgrade(t *testing.T) { testUpgrade(t, "example02", "0", "example*02", "1{}0", path, InvalidChaincodeNameErr("example*02").Error(), nil, nil, nil) testUpgrade(t, "example02", "0", "", "1", path, EmptyChaincodeNameErr("").Error(), nil, nil, nil) - scc := New(NewMockProvider(), mockAclProvider) + scc := New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub := shim.NewMockStub("lscc", scc) res := stub.MockInit("1", nil) @@ -446,7 +448,7 @@ func TestUpgrade(t *testing.T) { testUpgrade(t, "example02", "0", "example02", "1", path, "barf", scc, stub, nil) - scc = New(NewMockProvider(), mockAclProvider) + scc = New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -454,7 +456,7 @@ func TestUpgrade(t *testing.T) { testUpgrade(t, "example02", "0", "example02", "1", path, "instantiation policy missing", scc, stub, nil) - scc = New(NewMockProvider(), mockAclProvider) + scc = New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -465,7 +467,7 @@ func TestUpgrade(t *testing.T) { testUpgrade(t, "example02", "0", "example02", "1", path, "barf", scc, stub, nil) - scc = New(NewMockProvider(), mockAclProvider) + scc = New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -486,7 +488,7 @@ func TestUpgrade(t *testing.T) { }, }).NewSystemChaincodeProvider().(*mscc.MocksccProviderImpl) - scc = New(mocksccProvider, mockAclProvider) + scc = New(mocksccProvider, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -520,7 +522,7 @@ func TestUpgrade(t *testing.T) { }, }).NewSystemChaincodeProvider().(*mscc.MocksccProviderImpl) - scc = New(mocksccProvider, mockAclProvider) + scc = New(mocksccProvider, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -534,7 +536,7 @@ func TestUpgrade(t *testing.T) { _, ok := stub.State["example02"] assert.Equal(t, true, ok) - scc = New(mocksccProvider, mockAclProvider) + scc = New(mocksccProvider, mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res = stub.MockInit("1", nil) @@ -556,7 +558,7 @@ func TestUpgrade(t *testing.T) { func testUpgrade(t *testing.T, ccname string, version string, newccname string, newversion string, path string, expectedErrorMsg string, scc *lifeCycleSysCC, stub *shim.MockStub, collectionConfigBytes []byte) { if scc == nil { - scc = New(NewMockProvider(), mockAclProvider) + scc = New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub = shim.NewMockStub("lscc", scc) res := stub.MockInit("1", nil) @@ -618,7 +620,7 @@ func testUpgrade(t *testing.T, ccname string, version string, newccname string, } func TestFunctionsWithAliases(t *testing.T) { - scc := New(NewMockProvider(), mockAclProvider) + scc := New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub := shim.NewMockStub("lscc", scc) res := stub.MockInit("1", nil) @@ -668,7 +670,7 @@ func TestFunctionsWithAliases(t *testing.T) { } func TestGetChaincodes(t *testing.T) { - scc := New(NewMockProvider(), mockAclProvider) + scc := New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub := shim.NewMockStub("lscc", scc) stub.ChannelID = "test" @@ -699,7 +701,7 @@ func TestGetChaincodes(t *testing.T) { } func TestGetInstalledChaincodes(t *testing.T) { - scc := New(NewMockProvider(), mockAclProvider) + scc := New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) scc.support = &lscc.MockSupport{} stub := shim.NewMockStub("lscc", scc) res := stub.MockInit("1", nil) @@ -757,7 +759,7 @@ func TestGetInstalledChaincodes(t *testing.T) { } func TestNewLifeCycleSysCC(t *testing.T) { - scc := New(NewMockProvider(), mockAclProvider) + scc := New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) assert.NotNil(t, scc) stub := shim.NewMockStub("lscc", scc) res := stub.MockInit("1", nil) @@ -769,7 +771,7 @@ func TestNewLifeCycleSysCC(t *testing.T) { } func TestGetChaincodeData(t *testing.T) { - scc := New(NewMockProvider(), mockAclProvider) + scc := New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) assert.NotNil(t, scc) stub := shim.NewMockStub("lscc", scc) res := stub.MockInit("1", nil) @@ -784,7 +786,7 @@ func TestGetChaincodeData(t *testing.T) { } func TestExecuteInstall(t *testing.T) { - scc := New(NewMockProvider(), mockAclProvider) + scc := New(NewMockProvider(), mockAclProvider, platforms.NewRegistry(&golang.Platform{})) assert.NotNil(t, scc) stub := shim.NewMockStub("lscc", scc) res := stub.MockInit("1", nil) diff --git a/core/scc/register.go b/core/scc/register.go index b9295f2a638..a7c254b3cd5 100644 --- a/core/scc/register.go +++ b/core/scc/register.go @@ -10,10 +10,11 @@ package scc import ( "github.com/hyperledger/fabric/core/aclmgmt" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/common/ccprovider" ) // CreateSysCCs creates all of the system chaincodes which are compiled into fabric -func CreateSysCCs(ccp ccprovider.ChaincodeProvider, p *Provider, aclProvider aclmgmt.ACLProvider) []*SystemChaincode { - return builtInSystemChaincodes(ccp, p, aclProvider) +func CreateSysCCs(ccp ccprovider.ChaincodeProvider, p *Provider, aclProvider aclmgmt.ACLProvider, pr *platforms.Registry) []*SystemChaincode { + return builtInSystemChaincodes(ccp, p, aclProvider, pr) } diff --git a/core/scc/register_pluginsenabled.go b/core/scc/register_pluginsenabled.go index 39ac861e441..b72ed2fa1da 100644 --- a/core/scc/register_pluginsenabled.go +++ b/core/scc/register_pluginsenabled.go @@ -11,11 +11,12 @@ package scc import ( "github.com/hyperledger/fabric/core/aclmgmt" + "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/common/ccprovider" ) // CreateSysCCs creates all of the system chaincodes which are compiled into fabric // as well as those which are loaded by plugin -func CreateSysCCs(ccp ccprovider.ChaincodeProvider, p *Provider, aclProvider aclmgmt.ACLProvider) []*SystemChaincode { - return append(builtInSystemChaincodes(ccp, p, aclProvider), loadSysCCs(p)...) +func CreateSysCCs(ccp ccprovider.ChaincodeProvider, p *Provider, aclProvider aclmgmt.ACLProvider, pr *platforms.Registry) []*SystemChaincode { + return append(builtInSystemChaincodes(ccp, p, aclProvider, pr), loadSysCCs(p)...) } diff --git a/core/scc/scc_test.go b/core/scc/scc_test.go index 38ffb240963..7768197f8f2 100644 --- a/core/scc/scc_test.go +++ b/core/scc/scc_test.go @@ -29,7 +29,7 @@ func newTestProvider() *Provider { ccp := &ccprovider2.MockCcProviderImpl{} mockAclProvider := &aclmocks.MockACLProvider{} p := NewProvider(peer.Default, peer.DefaultSupport, inproccontroller.NewRegistry()) - for _, cc := range CreateSysCCs(ccp, p, mockAclProvider) { + for _, cc := range CreateSysCCs(ccp, p, mockAclProvider, nil) { p.RegisterSysCC(cc) } return p @@ -93,7 +93,7 @@ func TestSccProviderImpl_GetQueryExecutorForLedger(t *testing.T) { func TestRegisterSysCC(t *testing.T) { ccp := &ccprovider2.MockCcProviderImpl{} mockAclProvider := &aclmocks.MockACLProvider{} - assert.NotPanics(t, func() { CreateSysCCs(ccp, newTestProvider(), mockAclProvider) }, "expected successful init") + assert.NotPanics(t, func() { CreateSysCCs(ccp, newTestProvider(), mockAclProvider, nil) }, "expected successful init") p := &Provider{ Registrar: inproccontroller.NewRegistry(), diff --git a/peer/chaincode/chaincode.go b/peer/chaincode/chaincode.go index 473f8e9bed7..0217a1282b6 100644 --- a/peer/chaincode/chaincode.go +++ b/peer/chaincode/chaincode.go @@ -11,6 +11,11 @@ import ( "time" "github.com/hyperledger/fabric/common/flogging" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/car" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" + "github.com/hyperledger/fabric/core/chaincode/platforms/java" + "github.com/hyperledger/fabric/core/chaincode/platforms/node" "github.com/hyperledger/fabric/peer/common" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -23,6 +28,17 @@ const ( var logger = flogging.MustGetLogger("chaincodeCmd") +// XXX This is a terrible singleton hack, however +// it simply making a latent dependency explicit. +// It should be removed along with the other package +// scoped variables +var platformRegistry = platforms.NewRegistry( + &golang.Platform{}, + &car.Platform{}, + &java.Platform{}, + &node.Platform{}, +) + func addFlags(cmd *cobra.Command) { common.AddOrdererFlags(cmd) flags := cmd.PersistentFlags() diff --git a/peer/chaincode/common.go b/peer/chaincode/common.go index 0678aa2f149..a0f9bb74a25 100644 --- a/peer/chaincode/common.go +++ b/peer/chaincode/common.go @@ -20,7 +20,6 @@ import ( "github.com/hyperledger/fabric/common/localmsp" "github.com/hyperledger/fabric/common/util" "github.com/hyperledger/fabric/core/chaincode" - "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/container" "github.com/hyperledger/fabric/msp" @@ -44,7 +43,7 @@ func checkSpec(spec *pb.ChaincodeSpec) error { return errors.New("expected chaincode specification, nil received") } - return platforms.NewRegistry().ValidateSpec(spec) + return platformRegistry.ValidateSpec(spec) } // getChaincodeDeploymentSpec get chaincode deployment spec given the chaincode spec @@ -56,7 +55,7 @@ func getChaincodeDeploymentSpec(spec *pb.ChaincodeSpec, crtPkg bool) (*pb.Chainc return nil, err } - codePackageBytes, err = container.GetChaincodePackageBytes(spec) + codePackageBytes, err = container.GetChaincodePackageBytes(platformRegistry, spec) if err != nil { err = errors.WithMessage(err, "error getting chaincode package bytes") return nil, err diff --git a/peer/chaincode/install.go b/peer/chaincode/install.go index c77d9c16709..b9f49d9692b 100644 --- a/peer/chaincode/install.go +++ b/peer/chaincode/install.go @@ -141,7 +141,7 @@ func getPackageFromFile(ccpackfile string) (proto.Message, *pb.ChaincodeDeployme } //...and get the CDS at last - cds, err = utils.GetChaincodeDeploymentSpec(sCDS.ChaincodeDeploymentSpec) + cds, err = utils.GetChaincodeDeploymentSpec(sCDS.ChaincodeDeploymentSpec, platformRegistry) if err != nil { return nil, nil, fmt.Errorf("error extracting chaincode deployment spec(%s)", err) } diff --git a/peer/node/start.go b/peer/node/start.go index d51aed83aba..814ccac9e54 100644 --- a/peer/node/start.go +++ b/peer/node/start.go @@ -30,6 +30,11 @@ import ( "github.com/hyperledger/fabric/core/cclifecycle" "github.com/hyperledger/fabric/core/chaincode" "github.com/hyperledger/fabric/core/chaincode/accesscontrol" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/car" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" + "github.com/hyperledger/fabric/core/chaincode/platforms/java" + "github.com/hyperledger/fabric/core/chaincode/platforms/node" "github.com/hyperledger/fabric/core/comm" "github.com/hyperledger/fabric/core/committer/txvalidator" "github.com/hyperledger/fabric/core/common/ccprovider" @@ -149,8 +154,15 @@ func serve(args []string) error { aclmgmt.ResourceGetter(peer.GetStableChannelConfig), ) + pr := platforms.NewRegistry( + &golang.Platform{}, + &node.Platform{}, + &java.Platform{}, + &car.Platform{}, + ) + //initialize resource management exit - ledgermgmt.Initialize(peer.ConfigTxProcessors) + ledgermgmt.Initialize(peer.ConfigTxProcessors, pr) // Parameter overrides must be processed before any parameters are // cached. Failures to cache cause the server to terminate immediately. @@ -233,7 +245,7 @@ func serve(args []string) error { if err != nil { logger.Panicf("Failed to create chaincode server: %s", err) } - chaincodeSupport, ccp, sccp := registerChaincodeSupport(ccSrv, ccEndpoint, ca, aclProvider) + chaincodeSupport, ccp, sccp := registerChaincodeSupport(ccSrv, ccEndpoint, ca, aclProvider, pr) go ccSrv.Start() logger.Debugf("Running peer") @@ -278,7 +290,7 @@ func serve(args []string) error { SigningIdentityFetcher: signingIdentityFetcher, }) endorserSupport.PluginEndorser = pluginEndorser - serverEndorser := endorser.NewEndorserServer(privDataDist, endorserSupport) + serverEndorser := endorser.NewEndorserServer(privDataDist, endorserSupport, pr) auth := authHandler.ChainFilters(serverEndorser, authFilters...) // Register the Endorser server pb.RegisterEndorserServer(peerServer.Server(), auth) @@ -368,7 +380,7 @@ func serve(args []string) error { logger.Panicf("Failed subscribing to chaincode lifecycle updates") } cceventmgmt.GetMgr().Register(cid, sub) - }, ccp, sccp, txvalidator.MapBasedPluginMapper(validationPluginsByName)) + }, ccp, sccp, txvalidator.MapBasedPluginMapper(validationPluginsByName), pr) if viper.GetBool("peer.discovery.enabled") { registerDiscoveryService(peerServer, policyMgr, lifecycle) @@ -602,7 +614,7 @@ func computeChaincodeEndpoint(peerHostname string) (ccEndpoint string, err error //NOTE - when we implement JOIN we will no longer pass the chainID as param //The chaincode support will come up without registering system chaincodes //which will be registered only during join phase. -func registerChaincodeSupport(grpcServer *comm.GRPCServer, ccEndpoint string, ca tlsgen.CA, aclProvider aclmgmt.ACLProvider) (*chaincode.ChaincodeSupport, ccprovider.ChaincodeProvider, *scc.Provider) { +func registerChaincodeSupport(grpcServer *comm.GRPCServer, ccEndpoint string, ca tlsgen.CA, aclProvider aclmgmt.ACLProvider, pr *platforms.Registry) (*chaincode.ChaincodeSupport, ccprovider.ChaincodeProvider, *scc.Provider) { //get user mode userRunsCC := chaincode.IsDevMode() tlsEnabled := viper.GetBool("peer.tls.enabled") @@ -626,6 +638,7 @@ func registerChaincodeSupport(grpcServer *comm.GRPCServer, ccEndpoint string, ca inproccontroller.ContainerType: ipRegistry, }), sccp, + pr, ) ccp := chaincode.NewProvider(chaincodeSupport) @@ -635,7 +648,7 @@ func registerChaincodeSupport(grpcServer *comm.GRPCServer, ccEndpoint string, ca } //Now that chaincode is initialized, register all system chaincodes. - sccs := scc.CreateSysCCs(ccp, sccp, aclProvider) + sccs := scc.CreateSysCCs(ccp, sccp, aclProvider, pr) for _, cc := range sccs { sccp.RegisterSysCC(cc) } diff --git a/protos/utils/proputils.go b/protos/utils/proputils.go index 5c956b49d66..79920357809 100644 --- a/protos/utils/proputils.go +++ b/protos/utils/proputils.go @@ -148,7 +148,7 @@ func GetProposalResponse(prBytes []byte) (*peer.ProposalResponse, error) { } // GetChaincodeDeploymentSpec returns a ChaincodeDeploymentSpec given args -func GetChaincodeDeploymentSpec(code []byte) (*peer.ChaincodeDeploymentSpec, error) { +func GetChaincodeDeploymentSpec(code []byte, pr *platforms.Registry) (*peer.ChaincodeDeploymentSpec, error) { cds := &peer.ChaincodeDeploymentSpec{} err := proto.Unmarshal(code, cds) if err != nil { @@ -156,7 +156,7 @@ func GetChaincodeDeploymentSpec(code []byte) (*peer.ChaincodeDeploymentSpec, err } // FAB-2122: Validate the CDS according to platform specific requirements - return cds, platforms.NewRegistry().ValidateDeploymentSpec(cds) + return cds, pr.ValidateDeploymentSpec(cds) } // GetChaincodeAction gets the ChaincodeAction given chaicnode action bytes diff --git a/protos/utils/proputils_test.go b/protos/utils/proputils_test.go index e4794c43369..aea1ee3d5c5 100644 --- a/protos/utils/proputils_test.go +++ b/protos/utils/proputils_test.go @@ -17,6 +17,8 @@ import ( "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric/common/util" + "github.com/hyperledger/fabric/core/chaincode/platforms" + "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/msp" mspmgmt "github.com/hyperledger/fabric/msp/mgmt" "github.com/hyperledger/fabric/msp/mgmt/testtools" @@ -157,7 +159,9 @@ func TestGetNonce(t *testing.T) { } func TestGetChaincodeDeploymentSpec(t *testing.T) { - _, err := utils.GetChaincodeDeploymentSpec([]byte("bad spec")) + pr := platforms.NewRegistry(&golang.Platform{}) + + _, err := utils.GetChaincodeDeploymentSpec([]byte("bad spec"), pr) assert.Error(t, err, "Expected error with malformed spec") cds, _ := proto.Marshal(&pb.ChaincodeDeploymentSpec{ @@ -165,7 +169,7 @@ func TestGetChaincodeDeploymentSpec(t *testing.T) { Type: pb.ChaincodeSpec_GOLANG, }, }) - _, err = utils.GetChaincodeDeploymentSpec(cds) + _, err = utils.GetChaincodeDeploymentSpec(cds, pr) assert.NoError(t, err, "Unexpected error getting deployment spec") cds, _ = proto.Marshal(&pb.ChaincodeDeploymentSpec{ @@ -173,7 +177,7 @@ func TestGetChaincodeDeploymentSpec(t *testing.T) { Type: pb.ChaincodeSpec_UNDEFINED, }, }) - _, err = utils.GetChaincodeDeploymentSpec(cds) + _, err = utils.GetChaincodeDeploymentSpec(cds, pr) assert.Error(t, err, "Expected error with invalid spec type") }