github.com/defanghe/fabric@v2.1.1+incompatible/core/scc/scc.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package scc 8 9 import ( 10 "github.com/hyperledger/fabric-chaincode-go/shim" 11 pb "github.com/hyperledger/fabric-protos-go/peer" 12 "github.com/hyperledger/fabric/common/flogging" 13 "github.com/hyperledger/fabric/core/container/ccintf" 14 ) 15 16 // SysCCVersion is a constant used for the version field of system chaincodes. 17 // Historically, the version of a system chaincode was implicitly tied to the exact 18 // build version of a peer, which does not work for collecting endorsements across 19 // sccs across peers. Until there is a need for separate SCC versions, we use 20 // this constant here. 21 const SysCCVersion = "syscc" 22 23 // ChaincodeID returns the chaincode ID of a system chaincode of a given name. 24 func ChaincodeID(ccName string) string { 25 return ccName + "." + SysCCVersion 26 } 27 28 // XXX should we change this name to actually match the package name? Leaving now for historical consistency 29 var sysccLogger = flogging.MustGetLogger("sccapi") 30 31 // BuiltinSCCs are special system chaincodes, differentiated from other (plugin) 32 // system chaincodes. These chaincodes do not need to be initialized in '_lifecycle' 33 // and may be invoked without a channel context. It is expected that '_lifecycle' 34 // will eventually be the only builtin SCCs. 35 // Note, this field should only be used on _endorsement_ side, never in validation 36 // as it might change. 37 type BuiltinSCCs map[string]struct{} 38 39 func (bccs BuiltinSCCs) IsSysCC(name string) bool { 40 _, ok := bccs[name] 41 return ok 42 } 43 44 // A ChaincodeStreamHandler is responsible for handling the ChaincodeStream 45 // communication between a per and chaincode. 46 type ChaincodeStreamHandler interface { 47 HandleChaincodeStream(ccintf.ChaincodeStream) error 48 LaunchInProc(packageID string) <-chan struct{} 49 } 50 51 type SelfDescribingSysCC interface { 52 //Unique name of the system chaincode 53 Name() string 54 55 // Chaincode returns the underlying chaincode 56 Chaincode() shim.Chaincode 57 } 58 59 // DeploySysCC is the hook for system chaincodes where system chaincodes are registered with the fabric. 60 // This call directly registers the chaincode with the chaincode handler and bypasses the other usercc constructs. 61 func DeploySysCC(sysCC SelfDescribingSysCC, chaincodeStreamHandler ChaincodeStreamHandler) { 62 sysccLogger.Infof("deploying system chaincode '%s'", sysCC.Name()) 63 64 ccid := ChaincodeID(sysCC.Name()) 65 done := chaincodeStreamHandler.LaunchInProc(ccid) 66 67 peerRcvCCSend := make(chan *pb.ChaincodeMessage) 68 ccRcvPeerSend := make(chan *pb.ChaincodeMessage) 69 70 go func() { 71 stream := newInProcStream(peerRcvCCSend, ccRcvPeerSend) 72 defer stream.CloseSend() 73 74 sysccLogger.Debugf("starting chaincode-support stream for %s", ccid) 75 err := chaincodeStreamHandler.HandleChaincodeStream(stream) 76 sysccLogger.Criticalf("shim stream ended with err: %v", err) 77 }() 78 79 go func(sysCC SelfDescribingSysCC) { 80 stream := newInProcStream(ccRcvPeerSend, peerRcvCCSend) 81 defer stream.CloseSend() 82 83 sysccLogger.Debugf("chaincode started for %s", ccid) 84 err := shim.StartInProc(ccid, stream, sysCC.Chaincode()) 85 sysccLogger.Criticalf("system chaincode ended with err: %v", err) 86 }(sysCC) 87 <-done 88 }