Skip to content

Commit f4ed742

Browse files
author
Jason Yellick
committed
FAB-10987 GetChaincodeDeploymentSpec direct call
Presently, the chaincode/lifecycle/lifecycle.go GetChaincodeDeploymentSpec makes a chaincode invocation of LSCC to retrieve information which is directly and trivially available. This CR passes in a reference to LSCC so that all of the chaincode overhead and complexity can be eliminated. Change-Id: I57523144264e3efffc8cb81ff5d72f0138d1a79c Signed-off-by: Jason Yellick <jyellick@us.ibm.com>
1 parent be01b7e commit f4ed742

13 files changed

+181
-144
lines changed

core/chaincode/chaincode_support.go

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,7 @@ type Lifecycle interface {
4848
) (ccprovider.ChaincodeDefinition, error)
4949

5050
// GetChaincodeDeploymentSpec returns the package necessary to launch a chaincode
51-
GetChaincodeDeploymentSpec(
52-
ctx context.Context,
53-
txid string,
54-
signedProp *pb.SignedProposal,
55-
prop *pb.Proposal,
56-
chainID string,
57-
chaincodeID string,
58-
) (*pb.ChaincodeDeploymentSpec, error)
51+
GetChaincodeDeploymentSpec(chainID string, chaincodeID string) (*pb.ChaincodeDeploymentSpec, error)
5952
}
6053

6154
// ChaincodeSupport responsible for providing interfacing with chaincodes from the Peer.
@@ -78,6 +71,7 @@ func NewChaincodeSupport(
7871
caCert []byte,
7972
certGenerator CertGenerator,
8073
packageProvider PackageProvider,
74+
chaincodeStore lifecycle.InstantiatedChaincodeStore,
8175
aclProvider ACLProvider,
8276
processor Processor,
8377
sccp sysccprovider.SystemChaincodeProvider,
@@ -114,8 +108,11 @@ func NewChaincodeSupport(
114108
Runtime: cs.Runtime,
115109
Registry: cs.HandlerRegistry,
116110
PackageProvider: packageProvider,
117-
Lifecycle: &lifecycle.Lifecycle{Executor: cs},
118-
StartupTimeout: config.StartupTimeout,
111+
Lifecycle: &lifecycle.Lifecycle{
112+
Executor: cs,
113+
InstantiatedChaincodeStore: chaincodeStore,
114+
},
115+
StartupTimeout: config.StartupTimeout,
119116
}
120117

121118
return cs

core/chaincode/chaincode_support_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,15 @@ func initMockPeer(chainIDs ...string) (*ChaincodeSupport, error) {
175175
config.StartupTimeout = 10 * time.Second
176176
config.ExecuteTimeout = 1 * time.Second
177177
pr := platforms.NewRegistry(&golang.Platform{})
178+
lsccImpl := lscc.New(sccp, mockAclProvider, pr)
178179
chaincodeSupport := NewChaincodeSupport(
179180
config,
180181
"0.0.0.0:7052",
181182
true,
182183
ca.CertBytes(),
183184
certGenerator,
184185
&ccprovider.CCInfoFSImpl{},
186+
lsccImpl,
185187
mockAclProvider,
186188
container.NewVMController(
187189
map[string]container.VMProvider{
@@ -198,7 +200,7 @@ func initMockPeer(chainIDs ...string) (*ChaincodeSupport, error) {
198200

199201
ccp := &CCProviderImpl{cs: chaincodeSupport}
200202

201-
sccp.RegisterSysCC(lscc.New(sccp, mockAclProvider, pr))
203+
sccp.RegisterSysCC(lsccImpl)
202204

203205
globalBlockNum = make(map[string]uint64, len(chainIDs))
204206
for _, id := range chainIDs {

core/chaincode/exectransaction_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,15 @@ func initPeer(chainIDs ...string) (net.Listener, *ChaincodeSupport, func(), erro
129129
config := GlobalConfig()
130130
config.StartupTimeout = 3 * time.Minute
131131
pr := platforms.NewRegistry(&golang.Platform{})
132+
lsccImpl := lscc.New(sccp, mockAclProvider, pr)
132133
chaincodeSupport := NewChaincodeSupport(
133134
config,
134135
peerAddress,
135136
false,
136137
ca.CertBytes(),
137138
certGenerator,
138139
&ccprovider.CCInfoFSImpl{},
140+
lsccImpl,
139141
aclmgmt.NewACLProvider(func(string) channelconfig.Resources { return nil }),
140142
container.NewVMController(
141143
map[string]container.VMProvider{
@@ -152,7 +154,7 @@ func initPeer(chainIDs ...string) (net.Listener, *ChaincodeSupport, func(), erro
152154
policy.RegisterPolicyCheckerFactory(&mockPolicyCheckerFactory{})
153155

154156
ccp := &CCProviderImpl{cs: chaincodeSupport}
155-
sccp.RegisterSysCC(lscc.New(sccp, mockAclProvider, pr))
157+
sccp.RegisterSysCC(lsccImpl)
156158

157159
for _, id := range chainIDs {
158160
sccp.DeDeploySysCCs(id, ccp)

core/chaincode/lifecycle/lifecycle.go

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,15 @@ type Executor interface {
2121
Execute(ctxt context.Context, cccid *ccprovider.CCContext, cis *pb.ChaincodeInvocationSpec) (*pb.Response, *pb.ChaincodeEvent, error)
2222
}
2323

24+
// InstantiatedChaincodeStore returns information on chaincodes which are instantiated
25+
type InstantiatedChaincodeStore interface {
26+
ChaincodeDeploymentSpec(channelID, chaincodeName string) (*pb.ChaincodeDeploymentSpec, error)
27+
}
28+
2429
// Lifecycle provides methods to invoke the lifecycle system chaincode.
2530
type Lifecycle struct {
26-
Executor Executor
31+
Executor Executor
32+
InstantiatedChaincodeStore InstantiatedChaincodeStore
2733
}
2834

2935
// ChaincodeContainerInfo is yet another synonym for the data required to start/stop a chaincode.
@@ -38,42 +44,10 @@ type ChaincodeContainerInfo struct {
3844
}
3945

4046
// GetChaincodeDeploymentSpec retrieves a chaincode deployment spec for the specified chaincode.
41-
func (l *Lifecycle) GetChaincodeDeploymentSpec(
42-
ctx context.Context,
43-
txid string,
44-
signedProp *pb.SignedProposal,
45-
prop *pb.Proposal,
46-
chainID string,
47-
chaincodeID string,
48-
) (*pb.ChaincodeDeploymentSpec, error) {
49-
version := util.GetSysCCVersion()
50-
cccid := ccprovider.NewCCContext(chainID, "lscc", version, txid, true, signedProp, prop)
51-
52-
invocationSpec := &pb.ChaincodeInvocationSpec{
53-
ChaincodeSpec: &pb.ChaincodeSpec{
54-
Type: pb.ChaincodeSpec_GOLANG,
55-
ChaincodeId: &pb.ChaincodeID{Name: cccid.Name},
56-
Input: &pb.ChaincodeInput{
57-
Args: util.ToChaincodeArgs("getdepspec", chainID, chaincodeID),
58-
},
59-
},
60-
}
61-
62-
res, _, err := l.Executor.Execute(ctx, cccid, invocationSpec)
63-
if err != nil {
64-
return nil, errors.Wrapf(err, "getdepspec %s/%s failed", chainID, chaincodeID)
65-
}
66-
if res.Status != shim.OK {
67-
return nil, errors.Errorf("getdepspec %s/%s responded with error: %s", chainID, chaincodeID, res.Message)
68-
}
69-
if res.Payload == nil {
70-
return nil, errors.Errorf("getdepspec %s/%s failed: payload is nil", chainID, chaincodeID)
71-
}
72-
73-
cds := &pb.ChaincodeDeploymentSpec{}
74-
err = proto.Unmarshal(res.Payload, cds)
47+
func (l *Lifecycle) GetChaincodeDeploymentSpec(channelID, chaincodeName string) (*pb.ChaincodeDeploymentSpec, error) {
48+
cds, err := l.InstantiatedChaincodeStore.ChaincodeDeploymentSpec(channelID, chaincodeName)
7549
if err != nil {
76-
return nil, errors.Wrapf(err, "failed to unmarshal deployment spec payload for %s/%s", chainID, chaincodeID)
50+
return nil, errors.Wrapf(err, "could not retrieve deployment spec for %s/%s", channelID, chaincodeName)
7751
}
7852

7953
return cds, nil

core/chaincode/lifecycle/lifecycle_suite_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ type executor interface {
2020
lifecycle.Executor
2121
}
2222

23+
//go:generate counterfeiter -o mock/instantiated_cc_store.go --fake-name InstantiatedChaincodeStore . instantiatedChaincodeStore
24+
type instantiatedChaincodeStore interface {
25+
lifecycle.InstantiatedChaincodeStore
26+
}
27+
2328
func TestLifecycle(t *testing.T) {
2429
RegisterFailHandler(Fail)
2530
RunSpecs(t, "Lifecycle Suite")

core/chaincode/lifecycle/lifecycle_test.go

Lines changed: 34 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -22,113 +22,74 @@ import (
2222

2323
var _ = Describe("Lifecycle", func() {
2424
var (
25-
fakeExecutor *mock.Executor
26-
signedProp *pb.SignedProposal
27-
proposal *pb.Proposal
28-
2925
lifecycle *lc.Lifecycle
3026
)
3127

3228
BeforeEach(func() {
33-
fakeExecutor = &mock.Executor{}
34-
signedProp = &pb.SignedProposal{ProposalBytes: []byte("some-proposal-bytes")}
35-
proposal = &pb.Proposal{Payload: []byte("some-payload-bytes")}
36-
lifecycle = &lc.Lifecycle{
37-
Executor: fakeExecutor,
38-
}
3929
})
4030

4131
Describe("GetChaincodeDeploymentSpec", func() {
42-
var deploymentSpec *pb.ChaincodeDeploymentSpec
32+
var (
33+
fakeInstantiatedCCStore *mock.InstantiatedChaincodeStore
34+
deploymentSpec *pb.ChaincodeDeploymentSpec
35+
)
4336

4437
BeforeEach(func() {
4538
chaincodeID := &pb.ChaincodeID{Name: "chaincode-name", Version: "chaincode-version"}
4639
deploymentSpec = &pb.ChaincodeDeploymentSpec{
4740
CodePackage: []byte("code-package"),
4841
ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID},
4942
}
50-
deploymentSpecPayload, err := proto.Marshal(deploymentSpec)
51-
Expect(err).NotTo(HaveOccurred())
5243

53-
response := &pb.Response{Status: shim.OK, Payload: deploymentSpecPayload}
54-
fakeExecutor.ExecuteReturns(response, nil, nil)
44+
fakeInstantiatedCCStore = &mock.InstantiatedChaincodeStore{}
45+
fakeInstantiatedCCStore.ChaincodeDeploymentSpecReturns(deploymentSpec, nil)
46+
47+
lifecycle = &lc.Lifecycle{
48+
InstantiatedChaincodeStore: fakeInstantiatedCCStore,
49+
}
5550
})
5651

5752
It("invokes lscc getdepspec with the correct args", func() {
58-
cds, err := lifecycle.GetChaincodeDeploymentSpec(context.Background(), "tx-id", signedProp, proposal, "chain-id", "chaincode-id")
53+
cds, err := lifecycle.GetChaincodeDeploymentSpec("chain-id", "chaincode-name")
5954
Expect(err).NotTo(HaveOccurred())
6055
Expect(proto.Equal(cds, deploymentSpec)).To(BeTrue())
6156

62-
Expect(fakeExecutor.ExecuteCallCount()).To(Equal(1))
63-
ctx, cccid, cis := fakeExecutor.ExecuteArgsForCall(0)
64-
Expect(ctx).To(Equal(context.Background()))
65-
Expect(cccid).To(Equal(ccprovider.NewCCContext("chain-id", "lscc", "latest", "tx-id", true, signedProp, proposal)))
66-
Expect(cis).To(Equal(&pb.ChaincodeInvocationSpec{
67-
ChaincodeSpec: &pb.ChaincodeSpec{
68-
Type: pb.ChaincodeSpec_GOLANG,
69-
ChaincodeId: &pb.ChaincodeID{Name: "lscc"},
70-
Input: &pb.ChaincodeInput{
71-
Args: util.ToChaincodeArgs("getdepspec", "chain-id", "chaincode-id"),
72-
},
73-
},
74-
}))
75-
})
76-
77-
Context("when the executor fails", func() {
78-
BeforeEach(func() {
79-
fakeExecutor.ExecuteReturns(nil, nil, errors.New("mango-tango"))
80-
})
81-
82-
It("returns a wrapped error", func() {
83-
_, err := lifecycle.GetChaincodeDeploymentSpec(context.Background(), "tx-id", signedProp, proposal, "chain-id", "chaincode-id")
84-
Expect(err).To(MatchError("getdepspec chain-id/chaincode-id failed: mango-tango"))
85-
})
86-
})
87-
88-
Context("when the executor returns an error response", func() {
89-
BeforeEach(func() {
90-
response := &pb.Response{
91-
Status: shim.ERROR,
92-
Message: "danger-danger",
93-
}
94-
fakeExecutor.ExecuteReturns(response, nil, nil)
95-
})
96-
97-
It("returns a wrapped error", func() {
98-
_, err := lifecycle.GetChaincodeDeploymentSpec(context.Background(), "tx-id", signedProp, proposal, "chain-id", "chaincode-id")
99-
Expect(err).To(MatchError("getdepspec chain-id/chaincode-id responded with error: danger-danger"))
100-
})
101-
})
102-
103-
Context("when the response contains a nil payload", func() {
104-
BeforeEach(func() {
105-
response := &pb.Response{Status: shim.OK, Payload: nil}
106-
fakeExecutor.ExecuteReturns(response, nil, nil)
107-
})
108-
109-
It("returns a wrapped error", func() {
110-
_, err := lifecycle.GetChaincodeDeploymentSpec(context.Background(), "tx-id", signedProp, proposal, "chain-id", "chaincode-id")
111-
Expect(err).To(MatchError("getdepspec chain-id/chaincode-id failed: payload is nil"))
112-
})
57+
Expect(fakeInstantiatedCCStore.ChaincodeDeploymentSpecCallCount()).To(Equal(1))
58+
channelID, chaincodeName := fakeInstantiatedCCStore.ChaincodeDeploymentSpecArgsForCall(0)
59+
Expect(channelID).To(Equal("chain-id"))
60+
Expect(chaincodeName).To(Equal("chaincode-name"))
11361
})
11462

115-
Context("when unmarshaling the payload fails", func() {
63+
Context("when the instantiated chaincode store fails", func() {
11664
BeforeEach(func() {
117-
response := &pb.Response{Status: shim.OK, Payload: []byte("bogus-payload")}
118-
fakeExecutor.ExecuteReturns(response, nil, nil)
65+
fakeInstantiatedCCStore.ChaincodeDeploymentSpecReturns(nil, errors.New("mango-tango"))
11966
})
12067

12168
It("returns a wrapped error", func() {
122-
_, err := lifecycle.GetChaincodeDeploymentSpec(context.Background(), "tx-id", signedProp, proposal, "chain-id", "chaincode-id")
123-
Expect(err).To(MatchError(HavePrefix("failed to unmarshal deployment spec payload for chain-id/chaincode-id")))
69+
_, err := lifecycle.GetChaincodeDeploymentSpec("chain-id", "chaincode-id")
70+
Expect(err).To(MatchError("could not retrieve deployment spec for chain-id/chaincode-id: mango-tango"))
12471
})
12572
})
12673
})
12774

12875
Describe("GetChaincodeDefinition", func() {
129-
var chaincodeData *ccprovider.ChaincodeData
76+
var (
77+
chaincodeData *ccprovider.ChaincodeData
78+
79+
fakeExecutor *mock.Executor
80+
signedProp *pb.SignedProposal
81+
proposal *pb.Proposal
82+
)
13083

13184
BeforeEach(func() {
85+
fakeExecutor = &mock.Executor{}
86+
signedProp = &pb.SignedProposal{ProposalBytes: []byte("some-proposal-bytes")}
87+
proposal = &pb.Proposal{Payload: []byte("some-payload-bytes")}
88+
89+
lifecycle = &lc.Lifecycle{
90+
Executor: fakeExecutor,
91+
}
92+
13293
chaincodeData = &ccprovider.ChaincodeData{
13394
Name: "george",
13495
Version: "old",

0 commit comments

Comments
 (0)