github.com/ewagmig/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  }