Skip to content

Commit 9dab228

Browse files
author
Srinivasan Muralidharan
committed
FAB-1295 - multichannel use chain in chain namespace
https://jira.hyperledger.org/browse/FAB-1295 This changeset uses the passed chainID (previous change set prepared the way by removing DefaultChain and passing chain ID top down) as as part of the namespace when registering and launching chaincodes. With that single stroke, the chaincode framework is ready for multichain. This change applies to both user and system chaincodes. The endorser provides the ledger simulation context for the proposal, outside of chaincodes, so the chaincodes naturally execute on the chain for the proposal. Given the chaincode execution uses the the ledger context supplied to it, all is needed a different container for a chaincode . to avoid name collision between chaincodes . more secure with no fear of leakage This changeset deliberately does not excercise multichain capabilities. The intent is to make sure the changes do not break current code. The next changeset will provide just test cases for executing chaincodes on multiple chains. Change-Id: Icab52e015e8d6373ef4056905695e28d8d58b3e5 Signed-off-by: Srinivasan Muralidharan <[email protected]>
1 parent 71805c9 commit 9dab228

12 files changed

+187
-152
lines changed

core/chaincode/chaincode_support.go

+55-48
Large diffs are not rendered by default.

core/chaincode/exectransaction.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func Execute(ctxt context.Context, chainID string, txid string, prop *pb.Proposa
3939
}
4040

4141
if cds != nil {
42-
_, err := theChaincodeSupport.Deploy(ctxt, cds)
42+
_, err := theChaincodeSupport.Deploy(ctxt, chainID, cds)
4343
if err != nil {
4444
return nil, nil, fmt.Errorf("Failed to deploy chaincode spec(%s)", err)
4545
}

core/chaincode/exectransaction_test.go

+66-65
Large diffs are not rendered by default.

core/chaincode/importsysccs.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ func RegisterSysCCs(chainID string) {
5757
//this is used in unit tests to stop and remove the system chaincodes before
5858
//restarting them in the same process. This allows clean start of the system
5959
//in the same process
60-
func deRegisterSysCCs() {
60+
func deRegisterSysCCs(chainID string) {
6161
for _, sysCC := range systemChaincodes {
62-
deregisterSysCC(sysCC)
62+
deregisterSysCC(chainID, sysCC)
6363
}
6464
}

core/chaincode/lccc.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ func (lccc *LifeCycleSysCC) deploy(stub shim.ChaincodeStubInterface, chainname s
265265

266266
ctxt = context.WithValue(ctxt, TXSimulatorKey, dummytxsim)
267267

268-
_, err = theChaincodeSupport.Deploy(ctxt, cds)
268+
_, err = theChaincodeSupport.Deploy(ctxt, chainname, cds)
269269
if err != nil {
270270
return fmt.Errorf("Failed to deploy chaincode spec(%s)", err)
271271
}
@@ -280,7 +280,7 @@ func (lccc *LifeCycleSysCC) deploy(stub shim.ChaincodeStubInterface, chainname s
280280
}
281281

282282
//stop now that we are done
283-
theChaincodeSupport.Stop(ctxt, cds)
283+
theChaincodeSupport.Stop(ctxt, chainname, cds)
284284

285285
return nil
286286
}
@@ -371,7 +371,7 @@ func (lccc *LifeCycleSysCC) Invoke(stub shim.ChaincodeStubInterface) ([]byte, er
371371
cd, _ := lccc.getChaincode(stub, chain, ccname)
372372
if cd == nil {
373373
logger.Debug("ChaincodeID [%s/%s] does not exist", chain, ccname)
374-
return nil, TXNotFoundErr(chain + "/" + ccname)
374+
return nil, TXNotFoundErr(ccname + "/" + chain)
375375
}
376376

377377
if function == GETCCINFO {

core/chaincode/sysccapi.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func RegisterSysCC(chainID string, syscc *SystemChaincode) error {
9494
}
9595

9696
// deregisterSysCC stops the system chaincode and deregisters it from inproccontroller
97-
func deregisterSysCC(syscc *SystemChaincode) error {
97+
func deregisterSysCC(chainID string, syscc *SystemChaincode) error {
9898
chaincodeID := &pb.ChaincodeID{Path: syscc.Path, Name: syscc.Name}
9999
spec := &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]), ChaincodeID: chaincodeID, CtorMsg: &pb.ChaincodeInput{Args: syscc.InitArgs}}
100100

@@ -109,7 +109,7 @@ func deregisterSysCC(syscc *SystemChaincode) error {
109109

110110
chaincodeSupport := GetChain()
111111
if chaincodeSupport != nil {
112-
err = chaincodeSupport.Stop(ctx, chaincodeDeploymentSpec)
112+
err = chaincodeSupport.Stop(ctx, chainID, chaincodeDeploymentSpec)
113113
}
114114

115115
return err

core/chaincode/systemchaincode_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func TestExecuteDeploySysChaincode(t *testing.T) {
103103

104104
cds := &pb.ChaincodeDeploymentSpec{ExecEnv: 1, ChaincodeSpec: &pb.ChaincodeSpec{Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "sample_syscc", Path: url}, CtorMsg: &pb.ChaincodeInput{Args: args}}}
105105

106-
theChaincodeSupport.Stop(ctxt, cds)
106+
theChaincodeSupport.Stop(ctxt, chainID, cds)
107107

108108
closeListenerAndSleep(lis)
109109
}

core/container/ccintf/ccintf.go

+20
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ package ccintf
2121
//Currently inproccontroller uses it. dockercontroller does not.
2222

2323
import (
24+
"encoding/hex"
25+
26+
"github.com/hyperledger/fabric/core/util"
2427
pb "github.com/hyperledger/fabric/protos/peer"
2528
"golang.org/x/net/context"
2629
)
@@ -47,4 +50,21 @@ type CCID struct {
4750
ChaincodeSpec *pb.ChaincodeSpec
4851
NetworkID string
4952
PeerID string
53+
ChainID string
54+
}
55+
56+
//GetName returns canonical chaincode name based on chain name
57+
func (ccid *CCID) GetName() string {
58+
if ccid.ChaincodeSpec == nil {
59+
panic("nil chaincode spec")
60+
}
61+
if ccid.ChainID == "" {
62+
panic("chain id not specified")
63+
}
64+
65+
hash := util.ComputeCryptoHash([]byte(ccid.ChainID))
66+
67+
hexstr := hex.EncodeToString(hash[:])
68+
69+
return ccid.ChaincodeSpec.ChaincodeID.Name + "-" + hexstr
5070
}

core/container/dockercontroller/dockercontroller.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,13 @@ func (vm *DockerVM) Destroy(ctxt context.Context, ccid ccintf.CCID, force bool,
267267
//GetVMName generates the docker image from peer information given the hashcode. This is needed to
268268
//keep image name's unique in a single host, multi-peer environment (such as a development environment)
269269
func (vm *DockerVM) GetVMName(ccid ccintf.CCID) (string, error) {
270+
name := ccid.GetName()
271+
270272
if ccid.NetworkID != "" {
271-
return fmt.Sprintf("%s-%s-%s", ccid.NetworkID, ccid.PeerID, ccid.ChaincodeSpec.ChaincodeID.Name), nil
273+
return fmt.Sprintf("%s-%s-%s", ccid.NetworkID, ccid.PeerID, name), nil
272274
} else if ccid.PeerID != "" {
273-
return fmt.Sprintf("%s-%s", ccid.PeerID, ccid.ChaincodeSpec.ChaincodeID.Name), nil
275+
return fmt.Sprintf("%s-%s", ccid.PeerID, name), nil
274276
} else {
275-
return ccid.ChaincodeSpec.ChaincodeID.Name, nil
277+
return name, nil
276278
}
277279
}

core/container/inproccontroller/inproccontroller.go

+20-15
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,15 @@ type InprocVM struct {
6767
id string
6868
}
6969

70-
func (vm *InprocVM) getInstance(ctxt context.Context, ipctemplate *inprocContainer, ccid ccintf.CCID, args []string, env []string) (*inprocContainer, error) {
71-
ipc := instRegistry[ccid.ChaincodeSpec.ChaincodeID.Name]
70+
func (vm *InprocVM) getInstance(ctxt context.Context, ipctemplate *inprocContainer, instName string, args []string, env []string) (*inprocContainer, error) {
71+
ipc := instRegistry[instName]
7272
if ipc != nil {
73-
inprocLogger.Warningf("chaincode instance exists for %s", ccid.ChaincodeSpec.ChaincodeID.Name)
73+
inprocLogger.Warningf("chaincode instance exists for %s", instName)
7474
return ipc, nil
7575
}
7676
ipc = &inprocContainer{args: args, env: env, chaincode: ipctemplate.chaincode, stopChan: make(chan struct{})}
77-
instRegistry[ccid.ChaincodeSpec.ChaincodeID.Name] = ipc
78-
inprocLogger.Debugf("chaincode instance created for %s", ccid.ChaincodeSpec.ChaincodeID.Name)
77+
instRegistry[instName] = ipc
78+
inprocLogger.Debugf("chaincode instance created for %s", instName)
7979
return ipc, nil
8080
}
8181

@@ -92,7 +92,8 @@ func (vm *InprocVM) Deploy(ctxt context.Context, ccid ccintf.CCID, args []string
9292
return fmt.Errorf(fmt.Sprintf("%s system chaincode does not contain chaincode instance", path))
9393
}
9494

95-
_, err := vm.getInstance(ctxt, ipctemplate, ccid, args, env)
95+
instName, _ := vm.GetVMName(ccid)
96+
_, err := vm.getInstance(ctxt, ipctemplate, instName, args, env)
9697

9798
//FUTURE ... here is where we might check code for safety
9899
inprocLogger.Debugf("registered : %s", path)
@@ -161,10 +162,12 @@ func (vm *InprocVM) Start(ctxt context.Context, ccid ccintf.CCID, args []string,
161162
return fmt.Errorf(fmt.Sprintf("%s not registered", path))
162163
}
163164

164-
ipc, err := vm.getInstance(ctxt, ipctemplate, ccid, args, env)
165+
instName, _ := vm.GetVMName(ccid)
166+
167+
ipc, err := vm.getInstance(ctxt, ipctemplate, instName, args, env)
165168

166169
if err != nil {
167-
return fmt.Errorf(fmt.Sprintf("could not create instance for %s", ccid.ChaincodeSpec.ChaincodeID.Name))
170+
return fmt.Errorf(fmt.Sprintf("could not create instance for %s", instName))
168171
}
169172

170173
if ipc.running {
@@ -183,10 +186,10 @@ func (vm *InprocVM) Start(ctxt context.Context, ccid ccintf.CCID, args []string,
183186
go func() {
184187
defer func() {
185188
if r := recover(); r != nil {
186-
inprocLogger.Criticalf("caught panic from chaincode %s", ccid.ChaincodeSpec.ChaincodeID.Name)
189+
inprocLogger.Criticalf("caught panic from chaincode %s", instName)
187190
}
188191
}()
189-
ipc.launchInProc(ctxt, ccid.ChaincodeSpec.ChaincodeID.Name, args, env, ccSupport)
192+
ipc.launchInProc(ctxt, instName, args, env, ccSupport)
190193
}()
191194

192195
return nil
@@ -201,19 +204,21 @@ func (vm *InprocVM) Stop(ctxt context.Context, ccid ccintf.CCID, timeout uint, d
201204
return fmt.Errorf("%s not registered", path)
202205
}
203206

204-
ipc := instRegistry[ccid.ChaincodeSpec.ChaincodeID.Name]
207+
instName, _ := vm.GetVMName(ccid)
208+
209+
ipc := instRegistry[instName]
205210

206211
if ipc == nil {
207-
return fmt.Errorf("%s not found", ccid.ChaincodeSpec.ChaincodeID.Name)
212+
return fmt.Errorf("%s not found", instName)
208213
}
209214

210215
if !ipc.running {
211-
return fmt.Errorf("%s not running", ccid.ChaincodeSpec.ChaincodeID.Name)
216+
return fmt.Errorf("%s not running", instName)
212217
}
213218

214219
ipc.stopChan <- struct{}{}
215220

216-
delete(instRegistry, ccid.ChaincodeSpec.ChaincodeID.Name)
221+
delete(instRegistry, instName)
217222
//TODO stop
218223
return nil
219224
}
@@ -226,5 +231,5 @@ func (vm *InprocVM) Destroy(ctxt context.Context, ccid ccintf.CCID, force bool,
226231

227232
//GetVMName ignores the peer and network name as it just needs to be unique in process
228233
func (vm *InprocVM) GetVMName(ccid ccintf.CCID) (string, error) {
229-
return ccid.ChaincodeSpec.ChaincodeID.Name, nil
234+
return ccid.GetName(), nil
230235
}

core/endorser/endorser.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func (*Endorser) getTxSimulator(ledgername string) (ledger.TxSimulator, error) {
6767
func (e *Endorser) deploy(ctxt context.Context, txid string, proposal *pb.Proposal, chainname string, cds *pb.ChaincodeDeploymentSpec, cid *pb.ChaincodeID) error {
6868
chaincodeSupport := chaincode.GetChain()
6969

70-
_, err := chaincodeSupport.Deploy(ctxt, cds)
70+
_, err := chaincodeSupport.Deploy(ctxt, chainname, cds)
7171
if err != nil {
7272
return fmt.Errorf("Failed to deploy chaincode spec(%s)", err)
7373
}
@@ -79,7 +79,7 @@ func (e *Endorser) deploy(ctxt context.Context, txid string, proposal *pb.Propos
7979
}
8080

8181
//stop now that we are done
82-
chaincodeSupport.Stop(ctxt, cds)
82+
chaincodeSupport.Stop(ctxt, chainname, cds)
8383

8484
return nil
8585
}

core/endorser/endorser_test.go

+10-10
Original file line numberDiff line numberDiff line change
@@ -241,10 +241,10 @@ func TestDeploy(t *testing.T) {
241241
if err != nil {
242242
t.Fail()
243243
t.Logf("Deploy-error in deploy %s", err)
244-
chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
244+
chaincode.GetChain().Stop(context.Background(), chainID, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
245245
return
246246
}
247-
chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
247+
chaincode.GetChain().Stop(context.Background(), chainID, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
248248
}
249249

250250
//TestDeployBadArgs sets bad args on deploy. It should fail, and example02 should not be deployed
@@ -257,10 +257,10 @@ func TestDeployBadArgs(t *testing.T) {
257257
if err == nil {
258258
t.Fail()
259259
t.Log("DeployBadArgs-expected error in deploy but succeeded")
260-
chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
260+
chaincode.GetChain().Stop(context.Background(), chainID, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
261261
return
262262
}
263-
chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
263+
chaincode.GetChain().Stop(context.Background(), chainID, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
264264
}
265265

266266
//TestDeployBadPayload set payload to nil and do a deploy. It should fail and example02 should not be deployed
@@ -276,10 +276,10 @@ func TestDeployBadPayload(t *testing.T) {
276276
if err == nil {
277277
t.Fail()
278278
t.Log("DeployBadPayload-expected error in deploy but succeeded")
279-
chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
279+
chaincode.GetChain().Stop(context.Background(), chainID, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
280280
return
281281
}
282-
chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
282+
chaincode.GetChain().Stop(context.Background(), chainID, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
283283
}
284284

285285
//TestRedeploy - deploy two times, second time should fail but example02 should remain deployed
@@ -293,7 +293,7 @@ func TestRedeploy(t *testing.T) {
293293
if err != nil {
294294
t.Fail()
295295
t.Logf("error in endorserServer.ProcessProposal %s", err)
296-
chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
296+
chaincode.GetChain().Stop(context.Background(), chainID, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
297297
return
298298
}
299299

@@ -302,10 +302,10 @@ func TestRedeploy(t *testing.T) {
302302
if err != nil {
303303
t.Fail()
304304
t.Logf("error in endorserServer.ProcessProposal %s", err)
305-
chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
305+
chaincode.GetChain().Stop(context.Background(), chainID, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
306306
return
307307
}
308-
chaincode.GetChain().Stop(context.Background(), &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
308+
chaincode.GetChain().Stop(context.Background(), chainID, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec})
309309
}
310310

311311
// TestDeployAndInvoke deploys and invokes chaincode_example01
@@ -349,7 +349,7 @@ func TestDeployAndInvoke(t *testing.T) {
349349
fmt.Printf("Invoke test passed\n")
350350
t.Logf("Invoke test passed")
351351

352-
chaincode.GetChain().Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: chaincodeID}})
352+
chaincode.GetChain().Stop(ctxt, chainID, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeID: chaincodeID}})
353353
}
354354

355355
func TestMain(m *testing.M) {

0 commit comments

Comments
 (0)