From d861bbfe175c027e008ab83fb98e5122b88521b5 Mon Sep 17 00:00:00 2001 From: Jason Yellick Date: Mon, 4 Jun 2018 13:41:45 -0400 Subject: [PATCH] FAB-10998 GetChaincodeData to use LSCC directly Now that LSCC can be queried directly for chaincode definitions instead of having to go the roundabout way of invoking chaincode, the assorted internal users of 'getccdata' can be converted to use the new interface. Change-Id: Ic435742817643d2dc08d83afe2f66980c649b56a Signed-off-by: Jason Yellick --- core/chaincode/chaincode_support.go | 20 +--- core/chaincode/chaincode_support_test.go | 4 +- core/chaincode/exectransaction_test.go | 5 +- core/chaincode/handler.go | 4 +- core/chaincode/handler_test.go | 7 +- core/chaincode/lifecycle/lifecycle.go | 51 +------- .../lifecycle/lifecycle_suite_test.go | 5 - core/chaincode/lifecycle/lifecycle_test.go | 110 +++--------------- .../lifecycle/mock/instantiated_cc_store.go | 70 +++++++++++ .../mock/chaincode_definition_getter.go | 33 ++---- core/chaincode/mock/lifecycle.go | 33 ++---- core/endorser/endorser.go | 4 +- core/endorser/mocks/support.go | 28 ++--- core/endorser/support.go | 12 +- core/mocks/endorser/support.go | 2 +- peer/node/start.go | 7 +- 16 files changed, 153 insertions(+), 242 deletions(-) diff --git a/core/chaincode/chaincode_support.go b/core/chaincode/chaincode_support.go index 0d0fea74337..4ce36bd368a 100644 --- a/core/chaincode/chaincode_support.go +++ b/core/chaincode/chaincode_support.go @@ -17,6 +17,7 @@ import ( "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/common/sysccprovider" "github.com/hyperledger/fabric/core/container/ccintf" + "github.com/hyperledger/fabric/core/ledger" "github.com/hyperledger/fabric/core/peer" pb "github.com/hyperledger/fabric/protos/peer" "github.com/pkg/errors" @@ -37,14 +38,7 @@ type Launcher interface { // Lifecycle provides a way to retrieve chaincode definitions and the packages necessary to run them type Lifecycle interface { // GetChaincodeDefinition returns the details for a chaincode by name - GetChaincodeDefinition( - ctx context.Context, - txid string, - signedProp *pb.SignedProposal, - prop *pb.Proposal, - chainID string, - chaincodeID string, - ) (ccprovider.ChaincodeDefinition, error) + GetChaincodeDefinition(chaincodeName string, txSim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) // ChaincodeContainerInfo returns the package necessary to launch a chaincode ChaincodeContainerInfo(chainID string, chaincodeID string) (*lifecycle.ChaincodeContainerInfo, error) @@ -71,7 +65,7 @@ func NewChaincodeSupport( caCert []byte, certGenerator CertGenerator, packageProvider PackageProvider, - chaincodeStore lifecycle.InstantiatedChaincodeStore, + lifecycle Lifecycle, aclProvider ACLProvider, processor Processor, sccp sysccprovider.SystemChaincodeProvider, @@ -84,6 +78,7 @@ func NewChaincodeSupport( HandlerRegistry: NewHandlerRegistry(userRunsCC), ACLProvider: aclProvider, sccp: sccp, + Lifecycle: lifecycle, } // Keep TestQueries working @@ -91,11 +86,6 @@ func NewChaincodeSupport( certGenerator = nil } - cs.Lifecycle = &lifecycle.Lifecycle{ - Executor: cs, - InstantiatedChaincodeStore: chaincodeStore, - } - cs.Runtime = &ContainerRuntime{ CertGenerator: certGenerator, Processor: processor, @@ -188,7 +178,7 @@ func (cs *ChaincodeSupport) HandleChaincodeStream(ctxt context.Context, stream c handler := &Handler{ Invoker: cs, - DefinitionGetter: &lifecycle.Lifecycle{Executor: cs}, + DefinitionGetter: cs.Lifecycle, Keepalive: cs.Keepalive, Registry: cs.HandlerRegistry, ACLProvider: cs.ACLProvider, diff --git a/core/chaincode/chaincode_support_test.go b/core/chaincode/chaincode_support_test.go index 56225c3c6e2..7278b54f8cb 100644 --- a/core/chaincode/chaincode_support_test.go +++ b/core/chaincode/chaincode_support_test.go @@ -183,7 +183,9 @@ func initMockPeer(chainIDs ...string) (*ChaincodeSupport, error) { ca.CertBytes(), certGenerator, &ccprovider.CCInfoFSImpl{}, - lsccImpl, + &lifecycle.Lifecycle{ + InstantiatedChaincodeStore: lsccImpl, + }, mockAclProvider, container.NewVMController( map[string]container.VMProvider{ diff --git a/core/chaincode/exectransaction_test.go b/core/chaincode/exectransaction_test.go index 59b597e8862..bf5c7da5777 100644 --- a/core/chaincode/exectransaction_test.go +++ b/core/chaincode/exectransaction_test.go @@ -34,6 +34,7 @@ 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/lifecycle" "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/chaincode/platforms/golang" "github.com/hyperledger/fabric/core/chaincode/shim" @@ -137,7 +138,9 @@ func initPeer(chainIDs ...string) (net.Listener, *ChaincodeSupport, func(), erro ca.CertBytes(), certGenerator, &ccprovider.CCInfoFSImpl{}, - lsccImpl, + &lifecycle.Lifecycle{ + InstantiatedChaincodeStore: lsccImpl, + }, aclmgmt.NewACLProvider(func(string) channelconfig.Resources { return nil }), container.NewVMController( map[string]container.VMProvider{ diff --git a/core/chaincode/handler.go b/core/chaincode/handler.go index 5d6c565747b..185242a0cd4 100644 --- a/core/chaincode/handler.go +++ b/core/chaincode/handler.go @@ -88,7 +88,7 @@ type QueryResponseBuilder interface { // ChaincodeDefinitionGetter is responsible for retrieving a chaincode definition // from the system. The definition is used by the InstantiationPolicyChecker. type ChaincodeDefinitionGetter interface { - GetChaincodeDefinition(ctxt context.Context, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chainID string, chaincodeID string) (ccprovider.ChaincodeDefinition, error) + GetChaincodeDefinition(chaincodeName string, txSim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) } // LedgerGetter is used to get ledgers for chaincode. @@ -858,7 +858,7 @@ func (h *Handler) HandleInvokeChaincode(msg *pb.ChaincodeMessage, txContext *Tra version := h.SystemCCVersion if !h.SystemCCProvider.IsSysCC(targetInstance.ChaincodeName) { // if its a user chaincode, get the details - cd, err := h.DefinitionGetter.GetChaincodeDefinition(ctxt, msg.Txid, txContext.SignedProp, txContext.Proposal, targetInstance.ChainID, targetInstance.ChaincodeName) + cd, err := h.DefinitionGetter.GetChaincodeDefinition(targetInstance.ChaincodeName, txsim) if err != nil { return nil, errors.WithStack(err) } diff --git a/core/chaincode/handler_test.go b/core/chaincode/handler_test.go index bb2447e05f2..ee462babd1d 100644 --- a/core/chaincode/handler_test.go +++ b/core/chaincode/handler_test.go @@ -1583,12 +1583,9 @@ var _ = Describe("Handler", func() { Expect(err).NotTo(HaveOccurred()) Expect(fakeDefinitionGetter.GetChaincodeDefinitionCallCount()).To(Equal(1)) - _, txid, signedProp, prop, chainID, ccname := fakeDefinitionGetter.GetChaincodeDefinitionArgsForCall(0) - Expect(txid).To(Equal("tx-id")) - Expect(signedProp).To(Equal(expectedSignedProp)) - Expect(prop).To(Equal(expectedProposal)) - Expect(chainID).To(Equal("channel-id")) + ccname, txSim := fakeDefinitionGetter.GetChaincodeDefinitionArgsForCall(0) Expect(ccname).To(Equal("target-chaincode-name")) + Expect(txSim).To(Equal(newTxSimulator)) }) It("checks the instantiation policy on the target", func() { diff --git a/core/chaincode/lifecycle/lifecycle.go b/core/chaincode/lifecycle/lifecycle.go index 6365cbe7ad1..d468429018f 100644 --- a/core/chaincode/lifecycle/lifecycle.go +++ b/core/chaincode/lifecycle/lifecycle.go @@ -7,28 +7,20 @@ SPDX-License-Identifier: Apache-2.0 package lifecycle import ( - "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/common/util" - "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/common/ccprovider" + "github.com/hyperledger/fabric/core/ledger" pb "github.com/hyperledger/fabric/protos/peer" "github.com/pkg/errors" - "golang.org/x/net/context" ) -// Executor is used to invoke chaincode. -type Executor interface { - Execute(ctxt context.Context, cccid *ccprovider.CCContext, cis *pb.ChaincodeInvocationSpec) (*pb.Response, *pb.ChaincodeEvent, error) -} - // InstantiatedChaincodeStore returns information on chaincodes which are instantiated type InstantiatedChaincodeStore interface { ChaincodeDeploymentSpec(channelID, chaincodeName string) (*pb.ChaincodeDeploymentSpec, error) + ChaincodeDefinition(chaincodeName string, txSim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) } // Lifecycle provides methods to invoke the lifecycle system chaincode. type Lifecycle struct { - Executor Executor InstantiatedChaincodeStore InstantiatedChaincodeStore } @@ -54,42 +46,9 @@ func (l *Lifecycle) ChaincodeContainerInfo(channelID, chaincodeName string) (*Ch } // GetChaincodeDefinition returns a ccprovider.ChaincodeDefinition for the chaincode -// associated with the provided channel and name. -func (l *Lifecycle) GetChaincodeDefinition( - ctx context.Context, - txid string, - signedProp *pb.SignedProposal, - prop *pb.Proposal, - chainID string, - chaincodeID string, -) (ccprovider.ChaincodeDefinition, error) { - version := util.GetSysCCVersion() - cccid := ccprovider.NewCCContext(chainID, "lscc", version, txid, true, signedProp, prop) - - invocationSpec := &pb.ChaincodeInvocationSpec{ - ChaincodeSpec: &pb.ChaincodeSpec{ - Type: pb.ChaincodeSpec_GOLANG, - ChaincodeId: &pb.ChaincodeID{Name: cccid.Name}, - Input: &pb.ChaincodeInput{ - Args: util.ToChaincodeArgs("getccdata", chainID, chaincodeID), - }, - }, - } - res, _, err := l.Executor.Execute(ctx, cccid, invocationSpec) - if err != nil { - return nil, errors.Wrapf(err, "getccdata %s/%s failed", chainID, chaincodeID) - } - if res.Status != shim.OK { - return nil, errors.Errorf("getccdata %s/%s responded with error: %s", chainID, chaincodeID, res.Message) - } - - cd := &ccprovider.ChaincodeData{} - err = proto.Unmarshal(res.Payload, cd) - if err != nil { - return nil, errors.Wrap(err, "failed to unmarshal chaincode definition") - } - - return cd, nil +// associated with the provided txsim and name. +func (l *Lifecycle) GetChaincodeDefinition(chaincodeName string, txSim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) { + return l.InstantiatedChaincodeStore.ChaincodeDefinition(chaincodeName, txSim) } func DeploymentSpecToChaincodeContainerInfo(cds *pb.ChaincodeDeploymentSpec) *ChaincodeContainerInfo { diff --git a/core/chaincode/lifecycle/lifecycle_suite_test.go b/core/chaincode/lifecycle/lifecycle_suite_test.go index 806f73b34ed..da46abbed62 100644 --- a/core/chaincode/lifecycle/lifecycle_suite_test.go +++ b/core/chaincode/lifecycle/lifecycle_suite_test.go @@ -15,11 +15,6 @@ import ( "testing" ) -//go:generate counterfeiter -o mock/executor.go --fake-name Executor . executor -type executor interface { - lifecycle.Executor -} - //go:generate counterfeiter -o mock/instantiated_cc_store.go --fake-name InstantiatedChaincodeStore . instantiatedChaincodeStore type instantiatedChaincodeStore interface { lifecycle.InstantiatedChaincodeStore diff --git a/core/chaincode/lifecycle/lifecycle_test.go b/core/chaincode/lifecycle/lifecycle_test.go index 632fec11409..465d1ab8873 100644 --- a/core/chaincode/lifecycle/lifecycle_test.go +++ b/core/chaincode/lifecycle/lifecycle_test.go @@ -7,31 +7,32 @@ SPDX-License-Identifier: Apache-2.0 package lifecycle_test import ( - "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/common/util" lc "github.com/hyperledger/fabric/core/chaincode/lifecycle" "github.com/hyperledger/fabric/core/chaincode/lifecycle/mock" - "github.com/hyperledger/fabric/core/chaincode/shim" "github.com/hyperledger/fabric/core/common/ccprovider" pb "github.com/hyperledger/fabric/protos/peer" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/pkg/errors" - "golang.org/x/net/context" ) var _ = Describe("Lifecycle", func() { var ( - lifecycle *lc.Lifecycle + lifecycle *lc.Lifecycle + fakeInstantiatedCCStore *mock.InstantiatedChaincodeStore ) BeforeEach(func() { + fakeInstantiatedCCStore = &mock.InstantiatedChaincodeStore{} + + lifecycle = &lc.Lifecycle{ + InstantiatedChaincodeStore: fakeInstantiatedCCStore, + } }) Describe("ChaincodeContainerInfo", func() { var ( - fakeInstantiatedCCStore *mock.InstantiatedChaincodeStore - deploymentSpec *pb.ChaincodeDeploymentSpec + deploymentSpec *pb.ChaincodeDeploymentSpec ) BeforeEach(func() { @@ -47,12 +48,7 @@ var _ = Describe("Lifecycle", func() { ExecEnv: pb.ChaincodeDeploymentSpec_SYSTEM, } - fakeInstantiatedCCStore = &mock.InstantiatedChaincodeStore{} fakeInstantiatedCCStore.ChaincodeDeploymentSpecReturns(deploymentSpec, nil) - - lifecycle = &lc.Lifecycle{ - InstantiatedChaincodeStore: fakeInstantiatedCCStore, - } }) It("invokes lscc getdepspec with the correct args", func() { @@ -85,94 +81,24 @@ var _ = Describe("Lifecycle", func() { Describe("GetChaincodeDefinition", func() { var ( chaincodeData *ccprovider.ChaincodeData - - fakeExecutor *mock.Executor - signedProp *pb.SignedProposal - proposal *pb.Proposal ) BeforeEach(func() { - fakeExecutor = &mock.Executor{} - signedProp = &pb.SignedProposal{ProposalBytes: []byte("some-proposal-bytes")} - proposal = &pb.Proposal{Payload: []byte("some-payload-bytes")} - - lifecycle = &lc.Lifecycle{ - Executor: fakeExecutor, - } - chaincodeData = &ccprovider.ChaincodeData{ - Name: "george", - Version: "old", - } - payload, err := proto.Marshal(chaincodeData) - Expect(err).NotTo(HaveOccurred()) - - response := &pb.Response{ - Status: shim.OK, - Payload: payload, + Name: "chaincode-data-name", } - fakeExecutor.ExecuteReturns(response, nil, nil) - }) - It("invokes lscc getccdata with the correct args", func() { - cd, err := lifecycle.GetChaincodeDefinition(context.Background(), "tx-id", signedProp, proposal, "chain-id", "chaincode-id") - Expect(err).NotTo(HaveOccurred()) - Expect(cd).To(Equal(chaincodeData)) - - Expect(fakeExecutor.ExecuteCallCount()).To(Equal(1)) - ctx, cccid, cis := fakeExecutor.ExecuteArgsForCall(0) - Expect(ctx).To(Equal(context.Background())) - Expect(cccid).To(Equal(ccprovider.NewCCContext("chain-id", "lscc", "latest", "tx-id", true, signedProp, proposal))) - Expect(cis).To(Equal(&pb.ChaincodeInvocationSpec{ - ChaincodeSpec: &pb.ChaincodeSpec{ - Type: pb.ChaincodeSpec_GOLANG, - ChaincodeId: &pb.ChaincodeID{Name: "lscc"}, - Input: &pb.ChaincodeInput{ - Args: util.ToChaincodeArgs("getccdata", "chain-id", "chaincode-id"), - }, - }, - })) + fakeInstantiatedCCStore.ChaincodeDefinitionReturns(chaincodeData, errors.New("fake-error")) }) - Context("when the executor fails", func() { - BeforeEach(func() { - fakeExecutor.ExecuteReturns(nil, nil, errors.New("mango-tango")) - }) - - It("returns a wrapped error", func() { - _, err := lifecycle.GetChaincodeDefinition(context.Background(), "tx-id", signedProp, proposal, "chain-id", "chaincode-id") - Expect(err).To(MatchError("getccdata chain-id/chaincode-id failed: mango-tango")) - }) - }) - - Context("when the executor returns an error response", func() { - BeforeEach(func() { - response := &pb.Response{ - Status: shim.ERROR, - Message: "danger-danger", - } - fakeExecutor.ExecuteReturns(response, nil, nil) - }) - - It("returns a wrapped error", func() { - _, err := lifecycle.GetChaincodeDefinition(context.Background(), "tx-id", signedProp, proposal, "chain-id", "chaincode-id") - Expect(err).To(MatchError("getccdata chain-id/chaincode-id responded with error: danger-danger")) - }) - }) - - Context("when unmarshaling the response fails", func() { - BeforeEach(func() { - response := &pb.Response{ - Status: shim.OK, - Payload: []byte("totally-bogus-payload"), - } - fakeExecutor.ExecuteReturns(response, nil, nil) - }) - - It("returns a wrapped error", func() { - _, err := lifecycle.GetChaincodeDefinition(context.Background(), "tx-id", signedProp, proposal, "chain-id", "chaincode-id") - Expect(err).To(MatchError(HavePrefix("failed to unmarshal chaincode definition: proto: "))) - }) + It("passes through to the underlying implementation", func() { + chaincodeDefinition, err := lifecycle.GetChaincodeDefinition("foo", nil) + Expect(chaincodeDefinition.(*ccprovider.ChaincodeData)).To(Equal(chaincodeData)) + Expect(err).To(MatchError("fake-error")) + Expect(fakeInstantiatedCCStore.ChaincodeDefinitionCallCount()).To(Equal(1)) + ccNameArg, txSimArg := fakeInstantiatedCCStore.ChaincodeDefinitionArgsForCall(0) + Expect(ccNameArg).To(Equal("foo")) + Expect(txSimArg).To(BeNil()) }) }) }) diff --git a/core/chaincode/lifecycle/mock/instantiated_cc_store.go b/core/chaincode/lifecycle/mock/instantiated_cc_store.go index 703e9c50940..7c9aadf34ad 100644 --- a/core/chaincode/lifecycle/mock/instantiated_cc_store.go +++ b/core/chaincode/lifecycle/mock/instantiated_cc_store.go @@ -4,6 +4,8 @@ package mock import ( "sync" + "github.com/hyperledger/fabric/core/common/ccprovider" + "github.com/hyperledger/fabric/core/ledger" pb "github.com/hyperledger/fabric/protos/peer" ) @@ -22,6 +24,20 @@ type InstantiatedChaincodeStore struct { result1 *pb.ChaincodeDeploymentSpec result2 error } + ChaincodeDefinitionStub func(chaincodeName string, txSim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) + chaincodeDefinitionMutex sync.RWMutex + chaincodeDefinitionArgsForCall []struct { + chaincodeName string + txSim ledger.QueryExecutor + } + chaincodeDefinitionReturns struct { + result1 ccprovider.ChaincodeDefinition + result2 error + } + chaincodeDefinitionReturnsOnCall map[int]struct { + result1 ccprovider.ChaincodeDefinition + result2 error + } invocations map[string][][]interface{} invocationsMutex sync.RWMutex } @@ -78,11 +94,65 @@ func (fake *InstantiatedChaincodeStore) ChaincodeDeploymentSpecReturnsOnCall(i i }{result1, result2} } +func (fake *InstantiatedChaincodeStore) ChaincodeDefinition(chaincodeName string, txSim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) { + fake.chaincodeDefinitionMutex.Lock() + ret, specificReturn := fake.chaincodeDefinitionReturnsOnCall[len(fake.chaincodeDefinitionArgsForCall)] + fake.chaincodeDefinitionArgsForCall = append(fake.chaincodeDefinitionArgsForCall, struct { + chaincodeName string + txSim ledger.QueryExecutor + }{chaincodeName, txSim}) + fake.recordInvocation("ChaincodeDefinition", []interface{}{chaincodeName, txSim}) + fake.chaincodeDefinitionMutex.Unlock() + if fake.ChaincodeDefinitionStub != nil { + return fake.ChaincodeDefinitionStub(chaincodeName, txSim) + } + if specificReturn { + return ret.result1, ret.result2 + } + return fake.chaincodeDefinitionReturns.result1, fake.chaincodeDefinitionReturns.result2 +} + +func (fake *InstantiatedChaincodeStore) ChaincodeDefinitionCallCount() int { + fake.chaincodeDefinitionMutex.RLock() + defer fake.chaincodeDefinitionMutex.RUnlock() + return len(fake.chaincodeDefinitionArgsForCall) +} + +func (fake *InstantiatedChaincodeStore) ChaincodeDefinitionArgsForCall(i int) (string, ledger.QueryExecutor) { + fake.chaincodeDefinitionMutex.RLock() + defer fake.chaincodeDefinitionMutex.RUnlock() + return fake.chaincodeDefinitionArgsForCall[i].chaincodeName, fake.chaincodeDefinitionArgsForCall[i].txSim +} + +func (fake *InstantiatedChaincodeStore) ChaincodeDefinitionReturns(result1 ccprovider.ChaincodeDefinition, result2 error) { + fake.ChaincodeDefinitionStub = nil + fake.chaincodeDefinitionReturns = struct { + result1 ccprovider.ChaincodeDefinition + result2 error + }{result1, result2} +} + +func (fake *InstantiatedChaincodeStore) ChaincodeDefinitionReturnsOnCall(i int, result1 ccprovider.ChaincodeDefinition, result2 error) { + fake.ChaincodeDefinitionStub = nil + if fake.chaincodeDefinitionReturnsOnCall == nil { + fake.chaincodeDefinitionReturnsOnCall = make(map[int]struct { + result1 ccprovider.ChaincodeDefinition + result2 error + }) + } + fake.chaincodeDefinitionReturnsOnCall[i] = struct { + result1 ccprovider.ChaincodeDefinition + result2 error + }{result1, result2} +} + func (fake *InstantiatedChaincodeStore) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() fake.chaincodeDeploymentSpecMutex.RLock() defer fake.chaincodeDeploymentSpecMutex.RUnlock() + fake.chaincodeDefinitionMutex.RLock() + defer fake.chaincodeDefinitionMutex.RUnlock() copiedInvocations := map[string][][]interface{}{} for key, value := range fake.invocations { copiedInvocations[key] = value diff --git a/core/chaincode/mock/chaincode_definition_getter.go b/core/chaincode/mock/chaincode_definition_getter.go index 6c994e1afde..97f6dbf707a 100644 --- a/core/chaincode/mock/chaincode_definition_getter.go +++ b/core/chaincode/mock/chaincode_definition_getter.go @@ -5,20 +5,15 @@ import ( "sync" "github.com/hyperledger/fabric/core/common/ccprovider" - pb "github.com/hyperledger/fabric/protos/peer" - "golang.org/x/net/context" + "github.com/hyperledger/fabric/core/ledger" ) type ChaincodeDefinitionGetter struct { - GetChaincodeDefinitionStub func(ctxt context.Context, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chainID string, chaincodeID string) (ccprovider.ChaincodeDefinition, error) + GetChaincodeDefinitionStub func(chaincodeName string, txSim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) getChaincodeDefinitionMutex sync.RWMutex getChaincodeDefinitionArgsForCall []struct { - ctxt context.Context - txid string - signedProp *pb.SignedProposal - prop *pb.Proposal - chainID string - chaincodeID string + chaincodeName string + txSim ledger.QueryExecutor } getChaincodeDefinitionReturns struct { result1 ccprovider.ChaincodeDefinition @@ -32,21 +27,17 @@ type ChaincodeDefinitionGetter struct { invocationsMutex sync.RWMutex } -func (fake *ChaincodeDefinitionGetter) GetChaincodeDefinition(ctxt context.Context, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chainID string, chaincodeID string) (ccprovider.ChaincodeDefinition, error) { +func (fake *ChaincodeDefinitionGetter) GetChaincodeDefinition(chaincodeName string, txSim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) { fake.getChaincodeDefinitionMutex.Lock() ret, specificReturn := fake.getChaincodeDefinitionReturnsOnCall[len(fake.getChaincodeDefinitionArgsForCall)] fake.getChaincodeDefinitionArgsForCall = append(fake.getChaincodeDefinitionArgsForCall, struct { - ctxt context.Context - txid string - signedProp *pb.SignedProposal - prop *pb.Proposal - chainID string - chaincodeID string - }{ctxt, txid, signedProp, prop, chainID, chaincodeID}) - fake.recordInvocation("GetChaincodeDefinition", []interface{}{ctxt, txid, signedProp, prop, chainID, chaincodeID}) + chaincodeName string + txSim ledger.QueryExecutor + }{chaincodeName, txSim}) + fake.recordInvocation("GetChaincodeDefinition", []interface{}{chaincodeName, txSim}) fake.getChaincodeDefinitionMutex.Unlock() if fake.GetChaincodeDefinitionStub != nil { - return fake.GetChaincodeDefinitionStub(ctxt, txid, signedProp, prop, chainID, chaincodeID) + return fake.GetChaincodeDefinitionStub(chaincodeName, txSim) } if specificReturn { return ret.result1, ret.result2 @@ -60,10 +51,10 @@ func (fake *ChaincodeDefinitionGetter) GetChaincodeDefinitionCallCount() int { return len(fake.getChaincodeDefinitionArgsForCall) } -func (fake *ChaincodeDefinitionGetter) GetChaincodeDefinitionArgsForCall(i int) (context.Context, string, *pb.SignedProposal, *pb.Proposal, string, string) { +func (fake *ChaincodeDefinitionGetter) GetChaincodeDefinitionArgsForCall(i int) (string, ledger.QueryExecutor) { fake.getChaincodeDefinitionMutex.RLock() defer fake.getChaincodeDefinitionMutex.RUnlock() - return fake.getChaincodeDefinitionArgsForCall[i].ctxt, fake.getChaincodeDefinitionArgsForCall[i].txid, fake.getChaincodeDefinitionArgsForCall[i].signedProp, fake.getChaincodeDefinitionArgsForCall[i].prop, fake.getChaincodeDefinitionArgsForCall[i].chainID, fake.getChaincodeDefinitionArgsForCall[i].chaincodeID + return fake.getChaincodeDefinitionArgsForCall[i].chaincodeName, fake.getChaincodeDefinitionArgsForCall[i].txSim } func (fake *ChaincodeDefinitionGetter) GetChaincodeDefinitionReturns(result1 ccprovider.ChaincodeDefinition, result2 error) { diff --git a/core/chaincode/mock/lifecycle.go b/core/chaincode/mock/lifecycle.go index b860dd91bfe..7d122c6ecf5 100644 --- a/core/chaincode/mock/lifecycle.go +++ b/core/chaincode/mock/lifecycle.go @@ -6,20 +6,15 @@ import ( "github.com/hyperledger/fabric/core/chaincode/lifecycle" "github.com/hyperledger/fabric/core/common/ccprovider" - pb "github.com/hyperledger/fabric/protos/peer" - "golang.org/x/net/context" + "github.com/hyperledger/fabric/core/ledger" ) type Lifecycle struct { - GetChaincodeDefinitionStub func(ctx context.Context, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chainID string, chaincodeID string) (ccprovider.ChaincodeDefinition, error) + GetChaincodeDefinitionStub func(chaincodeName string, txSim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) getChaincodeDefinitionMutex sync.RWMutex getChaincodeDefinitionArgsForCall []struct { - ctx context.Context - txid string - signedProp *pb.SignedProposal - prop *pb.Proposal - chainID string - chaincodeID string + chaincodeName string + txSim ledger.QueryExecutor } getChaincodeDefinitionReturns struct { result1 ccprovider.ChaincodeDefinition @@ -47,21 +42,17 @@ type Lifecycle struct { invocationsMutex sync.RWMutex } -func (fake *Lifecycle) GetChaincodeDefinition(ctx context.Context, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chainID string, chaincodeID string) (ccprovider.ChaincodeDefinition, error) { +func (fake *Lifecycle) GetChaincodeDefinition(chaincodeName string, txSim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) { fake.getChaincodeDefinitionMutex.Lock() ret, specificReturn := fake.getChaincodeDefinitionReturnsOnCall[len(fake.getChaincodeDefinitionArgsForCall)] fake.getChaincodeDefinitionArgsForCall = append(fake.getChaincodeDefinitionArgsForCall, struct { - ctx context.Context - txid string - signedProp *pb.SignedProposal - prop *pb.Proposal - chainID string - chaincodeID string - }{ctx, txid, signedProp, prop, chainID, chaincodeID}) - fake.recordInvocation("GetChaincodeDefinition", []interface{}{ctx, txid, signedProp, prop, chainID, chaincodeID}) + chaincodeName string + txSim ledger.QueryExecutor + }{chaincodeName, txSim}) + fake.recordInvocation("GetChaincodeDefinition", []interface{}{chaincodeName, txSim}) fake.getChaincodeDefinitionMutex.Unlock() if fake.GetChaincodeDefinitionStub != nil { - return fake.GetChaincodeDefinitionStub(ctx, txid, signedProp, prop, chainID, chaincodeID) + return fake.GetChaincodeDefinitionStub(chaincodeName, txSim) } if specificReturn { return ret.result1, ret.result2 @@ -75,10 +66,10 @@ func (fake *Lifecycle) GetChaincodeDefinitionCallCount() int { return len(fake.getChaincodeDefinitionArgsForCall) } -func (fake *Lifecycle) GetChaincodeDefinitionArgsForCall(i int) (context.Context, string, *pb.SignedProposal, *pb.Proposal, string, string) { +func (fake *Lifecycle) GetChaincodeDefinitionArgsForCall(i int) (string, ledger.QueryExecutor) { fake.getChaincodeDefinitionMutex.RLock() defer fake.getChaincodeDefinitionMutex.RUnlock() - return fake.getChaincodeDefinitionArgsForCall[i].ctx, fake.getChaincodeDefinitionArgsForCall[i].txid, fake.getChaincodeDefinitionArgsForCall[i].signedProp, fake.getChaincodeDefinitionArgsForCall[i].prop, fake.getChaincodeDefinitionArgsForCall[i].chainID, fake.getChaincodeDefinitionArgsForCall[i].chaincodeID + return fake.getChaincodeDefinitionArgsForCall[i].chaincodeName, fake.getChaincodeDefinitionArgsForCall[i].txSim } func (fake *Lifecycle) GetChaincodeDefinitionReturns(result1 ccprovider.ChaincodeDefinition, result2 error) { diff --git a/core/endorser/endorser.go b/core/endorser/endorser.go index 78211de9ace..8c4e17089ce 100644 --- a/core/endorser/endorser.go +++ b/core/endorser/endorser.go @@ -65,7 +65,7 @@ type Support interface { ExecuteInit(ctxt context.Context, cid, name, version, txid string, syscc bool, signedProp *pb.SignedProposal, prop *pb.Proposal, spec *pb.ChaincodeDeploymentSpec) (*pb.Response, *pb.ChaincodeEvent, error) // GetChaincodeDefinition returns ccprovider.ChaincodeDefinition for the chaincode with the supplied name - GetChaincodeDefinition(ctx context.Context, chainID string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chaincodeID string, txsim ledger.TxSimulator) (ccprovider.ChaincodeDefinition, error) + GetChaincodeDefinition(chaincodeID string, txsim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) // CheckACL checks the ACL for the resource for the channel using the // SignedProposal from which an id can be extracted for testing against a policy @@ -271,7 +271,7 @@ func (e *Endorser) SimulateProposal(ctx context.Context, chainID string, txid st var version string if !e.s.IsSysCC(cid.Name) { - cdLedger, err = e.s.GetChaincodeDefinition(ctx, chainID, txid, signedProp, prop, cid.Name, txsim) + cdLedger, err = e.s.GetChaincodeDefinition(cid.Name, txsim) if err != nil { return nil, nil, nil, nil, errors.WithMessage(err, fmt.Sprintf("make sure the chaincode %s has been successfully instantiated and try again", cid.Name)) } diff --git a/core/endorser/mocks/support.go b/core/endorser/mocks/support.go index 6abbf03cfbe..6e31440405a 100644 --- a/core/endorser/mocks/support.go +++ b/core/endorser/mocks/support.go @@ -147,16 +147,11 @@ type Support struct { result2 *pb.ChaincodeEvent result3 error } - GetChaincodeDefinitionStub func(ctx context.Context, chainID string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chaincodeID string, txsim ledger.TxSimulator) (ccprovider.ChaincodeDefinition, error) + GetChaincodeDefinitionStub func(chaincodeID string, txsim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) getChaincodeDefinitionMutex sync.RWMutex getChaincodeDefinitionArgsForCall []struct { - ctx context.Context - chainID string - txid string - signedProp *pb.SignedProposal - prop *pb.Proposal chaincodeID string - txsim ledger.TxSimulator + txsim ledger.QueryExecutor } getChaincodeDefinitionReturns struct { result1 ccprovider.ChaincodeDefinition @@ -749,22 +744,17 @@ func (fake *Support) ExecuteInitReturnsOnCall(i int, result1 *pb.Response, resul }{result1, result2, result3} } -func (fake *Support) GetChaincodeDefinition(ctx context.Context, chainID string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chaincodeID string, txsim ledger.TxSimulator) (ccprovider.ChaincodeDefinition, error) { +func (fake *Support) GetChaincodeDefinition(chaincodeID string, txsim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) { fake.getChaincodeDefinitionMutex.Lock() ret, specificReturn := fake.getChaincodeDefinitionReturnsOnCall[len(fake.getChaincodeDefinitionArgsForCall)] fake.getChaincodeDefinitionArgsForCall = append(fake.getChaincodeDefinitionArgsForCall, struct { - ctx context.Context - chainID string - txid string - signedProp *pb.SignedProposal - prop *pb.Proposal chaincodeID string - txsim ledger.TxSimulator - }{ctx, chainID, txid, signedProp, prop, chaincodeID, txsim}) - fake.recordInvocation("GetChaincodeDefinition", []interface{}{ctx, chainID, txid, signedProp, prop, chaincodeID, txsim}) + txsim ledger.QueryExecutor + }{chaincodeID, txsim}) + fake.recordInvocation("GetChaincodeDefinition", []interface{}{chaincodeID, txsim}) fake.getChaincodeDefinitionMutex.Unlock() if fake.GetChaincodeDefinitionStub != nil { - return fake.GetChaincodeDefinitionStub(ctx, chainID, txid, signedProp, prop, chaincodeID, txsim) + return fake.GetChaincodeDefinitionStub(chaincodeID, txsim) } if specificReturn { return ret.result1, ret.result2 @@ -778,10 +768,10 @@ func (fake *Support) GetChaincodeDefinitionCallCount() int { return len(fake.getChaincodeDefinitionArgsForCall) } -func (fake *Support) GetChaincodeDefinitionArgsForCall(i int) (context.Context, string, string, *pb.SignedProposal, *pb.Proposal, string, ledger.TxSimulator) { +func (fake *Support) GetChaincodeDefinitionArgsForCall(i int) (string, ledger.QueryExecutor) { fake.getChaincodeDefinitionMutex.RLock() defer fake.getChaincodeDefinitionMutex.RUnlock() - return fake.getChaincodeDefinitionArgsForCall[i].ctx, fake.getChaincodeDefinitionArgsForCall[i].chainID, fake.getChaincodeDefinitionArgsForCall[i].txid, fake.getChaincodeDefinitionArgsForCall[i].signedProp, fake.getChaincodeDefinitionArgsForCall[i].prop, fake.getChaincodeDefinitionArgsForCall[i].chaincodeID, fake.getChaincodeDefinitionArgsForCall[i].txsim + return fake.getChaincodeDefinitionArgsForCall[i].chaincodeID, fake.getChaincodeDefinitionArgsForCall[i].txsim } func (fake *Support) GetChaincodeDefinitionReturns(result1 ccprovider.ChaincodeDefinition, result2 error) { diff --git a/core/endorser/support.go b/core/endorser/support.go index 1e279903ea2..025a222d599 100644 --- a/core/endorser/support.go +++ b/core/endorser/support.go @@ -14,7 +14,6 @@ import ( "github.com/hyperledger/fabric/core/aclmgmt" "github.com/hyperledger/fabric/core/aclmgmt/resources" "github.com/hyperledger/fabric/core/chaincode" - lc "github.com/hyperledger/fabric/core/chaincode/lifecycle" "github.com/hyperledger/fabric/core/common/ccprovider" "github.com/hyperledger/fabric/core/handlers/decoration" . "github.com/hyperledger/fabric/core/handlers/endorsement/api/identities" @@ -144,15 +143,8 @@ func (s *SupportImpl) Execute(ctxt context.Context, cid, name, version, txid str } // GetChaincodeDefinition returns ccprovider.ChaincodeDefinition for the chaincode with the supplied name -func (s *SupportImpl) GetChaincodeDefinition(ctx context.Context, chainID string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chaincodeID string, txsim ledger.TxSimulator) (ccprovider.ChaincodeDefinition, error) { - ctxt := ctx - if txsim != nil { - ctxt = context.WithValue(ctx, chaincode.TXSimulatorKey, txsim) - } - lifecycle := &lc.Lifecycle{ - Executor: s.ChaincodeSupport, - } - return lifecycle.GetChaincodeDefinition(ctxt, txid, signedProp, prop, chainID, chaincodeID) +func (s *SupportImpl) GetChaincodeDefinition(chaincodeName string, txsim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) { + return s.ChaincodeSupport.Lifecycle.GetChaincodeDefinition(chaincodeName, txsim) } // CheckACL checks the ACL for the resource for the Channel using the diff --git a/core/mocks/endorser/support.go b/core/mocks/endorser/support.go index f94e86cb7a3..06fb81aa05f 100644 --- a/core/mocks/endorser/support.go +++ b/core/mocks/endorser/support.go @@ -107,7 +107,7 @@ func (s *MockSupport) GetChaincodeDeploymentSpecFS(cds *pb.ChaincodeDeploymentSp return cds, nil } -func (s *MockSupport) GetChaincodeDefinition(ctx context.Context, chainID string, txid string, signedProp *pb.SignedProposal, prop *pb.Proposal, chaincodeID string, txsim ledger.TxSimulator) (ccprovider.ChaincodeDefinition, error) { +func (s *MockSupport) GetChaincodeDefinition(chaincodeName string, txsim ledger.QueryExecutor) (ccprovider.ChaincodeDefinition, error) { return s.ChaincodeDefinitionRv, s.ChaincodeDefinitionError } diff --git a/peer/node/start.go b/peer/node/start.go index 458d4ce28e8..f73a41d3c18 100644 --- a/peer/node/start.go +++ b/peer/node/start.go @@ -30,6 +30,7 @@ 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/lifecycle" "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/chaincode/platforms/car" "github.com/hyperledger/fabric/core/chaincode/platforms/golang" @@ -628,6 +629,10 @@ func registerChaincodeSupport(grpcServer *comm.GRPCServer, ccEndpoint string, ca sccp := scc.NewProvider(peer.Default, peer.DefaultSupport, ipRegistry) lsccInst := lscc.New(sccp, aclProvider, pr) + lifecycleImpl := &lifecycle.Lifecycle{ + InstantiatedChaincodeStore: lsccInst, + } + chaincodeSupport := chaincode.NewChaincodeSupport( chaincode.GlobalConfig(), ccEndpoint, @@ -635,7 +640,7 @@ func registerChaincodeSupport(grpcServer *comm.GRPCServer, ccEndpoint string, ca ca.CertBytes(), authenticator, &ccprovider.CCInfoFSImpl{}, - lsccInst, + lifecycleImpl, aclProvider, container.NewVMController(map[string]container.VMProvider{ dockercontroller.ContainerType: dockercontroller.NewProvider(