2019-09-09 07:52:09.409 UTC [gossip.gossip] start -> INFO 013 Gossip instance peer1.org1.example.com:8051 started 2019-09-09 07:52:09.418 UTC [sccapi] deploySysCC -> INFO 014 system chaincode lscc/(github.com/hyperledger/fabric/core/scc/lscc) deployed 2019-09-09 07:52:09.420 UTC [cscc] Init -> INFO 015 Init CSCC 2019-09-09 07:52:09.422 UTC [sccapi] deploySysCC -> INFO 016 system chaincode cscc/(github.com/hyperledger/fabric/core/scc/cscc) deployed 2019-09-09 07:52:09.424 UTC [qscc] Init -> INFO 017 Init QSCC 2019-09-09 07:52:09.424 UTC [sccapi] deploySysCC -> INFO 018 system chaincode qscc/(github.com/hyperledger/fabric/core/scc/qscc) deployed 2019-09-09 07:52:09.425 UTC [sccapi] deploySysCC -> INFO 019 system chaincode (+lifecycle,github.com/hyperledger/fabric/core/chaincode/lifecycle) disabled ... 2019-09-09 07:52:14.386 UTC [sccapi] deploySysCC -> INFO 031 system chaincode lscc/mychannel(github.com/hyperledger/fabric/core/scc/lscc) deployed 2019-09-09 07:52:14.386 UTC [cscc] Init -> INFO 032 Init CSCC 2019-09-09 07:52:14.386 UTC [sccapi] deploySysCC -> INFO 033 system chaincode cscc/mychannel(github.com/hyperledger/fabric/core/scc/cscc) deployed 2019-09-09 07:52:14.387 UTC [qscc] Init -> INFO 034 Init QSCC 2019-09-09 07:52:14.387 UTC [sccapi] deploySysCC -> INFO 035 system chaincode qscc/mychannel(github.com/hyperledger/fabric/core/scc/qscc) deployed 2019-09-09 07:52:14.387 UTC [sccapi] deploySysCC -> INFO 036 system chaincode (+lifecycle,github.com/hyperledger/fabric/core/chaincode/lifecycle) disabled
// Registrar provides a way for system chaincodes to be registered type Registrar interface { // Register registers a system chaincode Register(ccid *ccintf.CCID, cc shim.Chaincode) error }
//Register registers system chaincode with given path. The deploy should be called to initialize func(r *Registry)Register(ccid *ccintf.CCID, cc shim.Chaincode)error { r.mutex.Lock() defer r.mutex.Unlock()
//DeploySysCCs is the hook for system chaincodes where system chaincodes are registered with the fabric //note the chaincode must still be deployed and launched like a user chaincode will be func(p *Provider)DeploySysCCs(chainID string, ccp ccprovider.ChaincodeProvider) { // 部署每一个scc for _, sysCC := range p.SysCCs { deploySysCC(chainID, ccp, sysCC) } }
// deploySysCC deploys the given system chaincode on a chain funcdeploySysCC(chainID string, ccprov ccprovider.ChaincodeProvider, syscc SelfDescribingSysCC)error { // disable或不在白名单的scc不执行部署 if !syscc.Enabled() || !isWhitelisted(syscc) { sysccLogger.Info(fmt.Sprintf("system chaincode (%s,%s) disabled", syscc.Name(), syscc.Path())) returnnil }
// Note, this structure is barely initialized, // we omit the history query executor, the proposal // and the signed proposal txParams := &ccprovider.TransactionParams{ TxID: txid, ChannelID: chainID, }
// 设置交易执行模拟器,系统通道chainID为"",所以系统通道的scc没有模拟器 if chainID != "" { // 获取链/通道的账本 lgr := peer.GetLedger(chainID) if lgr == nil { panic(fmt.Sprintf("syschain %s start up failure - unexpected nil ledger for channel %s", syscc.Name(), chainID)) }
// ChaincodeProvider provides an abstraction layer that is // used for different packages to interact with code in the // chaincode package without importing it; more methods // should be added below if necessary type ChaincodeProvider interface { // Execute executes a standard chaincode invocation for a chaincode and an input Execute(txParams *TransactionParams, cccid *CCContext, input *pb.ChaincodeInput) (*pb.Response, *pb.ChaincodeEvent, error) // ExecuteLegacyInit is a special case for executing chaincode deployment specs, // which are not already in the LSCC, needed for old lifecycle ExecuteLegacyInit(txParams *TransactionParams, cccid *CCContext, spec *pb.ChaincodeDeploymentSpec) (*pb.Response, *pb.ChaincodeEvent, error) // Stop stops the chaincode give Stop(ccci *ChaincodeContainerInfo) error }
// ExecuteLegacyInit executes a chaincode which is not in the LSCC table func(c *CCProviderImpl)ExecuteLegacyInit(txParams *ccprovider.TransactionParams, cccid *ccprovider.CCContext, spec *pb.ChaincodeDeploymentSpec)(*pb.Response, *pb.ChaincodeEvent, error) { return c.cs.ExecuteLegacyInit(txParams, cccid, spec) }
// ExecuteLegacyInit is a temporary method which should be removed once the old style lifecycle // is entirely deprecated. Ideally one release after the introduction of the new lifecycle. // It does not attempt to start the chaincode based on the information from lifecycle, but instead // accepts the container information directly in the form of a ChaincodeDeploymentSpec. func(cs *ChaincodeSupport)ExecuteLegacyInit(txParams *ccprovider.TransactionParams, cccid *ccprovider.CCContext, spec *pb.ChaincodeDeploymentSpec)(*pb.Response, *pb.ChaincodeEvent, error) { // 部署链码需要的信息 ccci := ccprovider.DeploymentSpecToChaincodeContainerInfo(spec) ccci.Version = cccid.Version
cname := ccci.Name + ":" + ccci.Version h := cs.HandlerRegistry.Handler(cname) if h == nil { returnnil, nil, errors.Wrapf(err, "[channel %s] claimed to start chaincode container for %s but could not find handler", txParams.ChannelID, cname) }
// LaunchInit bypasses getting the chaincode spec from the LSCC table // as in the case of v1.0-v1.2 lifecycle, the chaincode will not yet be // defined in the LSCC table func(cs *ChaincodeSupport)LaunchInit(ccci *ccprovider.ChaincodeContainerInfo)error { cname := ccci.Name + ":" + ccci.Version // 已经有handler,即容器已经启动。调用链码的时候,也会获取handler if cs.HandlerRegistry.Handler(cname) != nil { returnnil }
//VMCReq - all requests should implement this interface. //The context should be passed and tested at each layer till we stop //note that we'd stop on the first method on the stack that does not //take context type VMCReq interface { Do(v VM) error GetCCID() ccintf.CCID }
// 从进程启动链码 func(ipc *inprocContainer)launchInProc(id string, args []string, env []string)error { if ipc.ChaincodeSupport == nil { inprocLogger.Panicf("Chaincode support is nil, most likely you forgot to set it immediately after calling inproccontroller.NewRegsitry()") }
// 和调用链码的上层通信的2个通道 peerRcvCCSend := make(chan *pb.ChaincodeMessage) ccRcvPeerSend := make(chan *pb.ChaincodeMessage) var err error ccchan := make(chanstruct{}, 1) ccsupportchan := make(chanstruct{}, 1) shimStartInProc := _shimStartInProc // shadow to avoid race in test gofunc() { deferclose(ccchan) // 启动链码 inprocLogger.Debugf("chaincode started for %s", id) if args == nil { args = ipc.args } if env == nil { env = ipc.env } // 利用shim启动 err := shimStartInProc(env, args, ipc.chaincode, ccRcvPeerSend, peerRcvCCSend) if err != nil { err = fmt.Errorf("chaincode-support ended with err: %s", err) _inprocLoggerErrorf("%s", err) } inprocLogger.Debugf("chaincode ended for %s with err: %s", id, err) }()
// shadow function to avoid data race inprocLoggerErrorf := _inprocLoggerErrorf gofunc() { deferclose(ccsupportchan) // 处理scc和外部通信的消息流 inprocStream := newInProcStream(peerRcvCCSend, ccRcvPeerSend) inprocLogger.Debugf("chaincode-support started for %s", id) err := ipc.ChaincodeSupport.HandleChaincodeStream(inprocStream) if err != nil { err = fmt.Errorf("chaincode ended with err: %s", err) inprocLoggerErrorf("%s", err) } inprocLogger.Debugf("chaincode-support ended for %s with err: %s", id, err) }() }
// 启动SCC的入口 // StartInProc is an entry point for system chaincodes bootstrap. It is not an // API for chaincodes. funcStartInProc(env []string, args []string, cc Chaincode, recv <-chan *pb.ChaincodeMessage, send chan<- *pb.ChaincodeMessage)error { // 有点奇怪,这些日志都没有看到,因为已经在shim,不属于peer日志了 chaincodeLogger.Debugf("in proc %v", args)
// 从环境变量获取cc name var chaincodename string for _, v := range env { if strings.Index(v, "CORE_CHAINCODE_ID_NAME=") == 0 { p := strings.SplitAfter(v, "CORE_CHAINCODE_ID_NAME=") chaincodename = p[1] break } } if chaincodename == "" { return errors.New("error chaincode id not provided") }
//send may happen on a closed channel when the system is //shutting down. Just catch the exception and return error deferfunc() { if r := recover(); r != nil { err = SendPanicFailure(fmt.Sprintf("%s", r)) return } }() s.send <- msg return }
// 接收是从recv读数据 func(s *inProcStream)Recv()(*pb.ChaincodeMessage, error) { msg, ok := <-s.recv if !ok { returnnil, errors.New("channel is closed") } return msg, nil }
2019-09-09 07:52:09.915 UTC [chaincode] LaunchConfig -> DEBU 098 launchConfig: executable:"chaincode",Args:[chaincode,-peer.address=peer0.org1.example.com:7052],Envs:[CORE_CHAINCODE_LOGGING_LEVEL=info,CORE_CHAINCODE_LOGGING_SHIM=warning,CORE_CHAINCODE_LOGGING_FORMAT=%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message},CORE_CHAINCODE_ID_NAME=lscc:1.4.3,CORE_PEER_TLS_ENABLED=true,CORE_TLS_CLIENT_KEY_PATH=/etc/hyperledger/fabric/client.key,CORE_TLS_CLIENT_CERT_PATH=/etc/hyperledger/fabric/client.crt,CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/peer.crt],Files:[/etc/hyperledger/fabric/client.crt /etc/hyperledger/fabric/client.key /etc/hyperledger/fabric/peer.crt] 2019-09-09 07:52:09.915 UTC [chaincode] Start -> DEBU 099 start container: lscc:1.4.3 2019-09-09 07:52:09.915 UTC [chaincode] Start -> DEBU 09a start container with args: chaincode -peer.address=peer0.org1.example.com:7052 2019-09-09 07:52:09.915 UTC [chaincode] Start -> DEBU 09b start container with env: CORE_CHAINCODE_LOGGING_LEVEL=info CORE_CHAINCODE_LOGGING_SHIM=warning CORE_CHAINCODE_LOGGING_FORMAT=%{color}%{time:2006-01-02 15:04:05.000 MST} [%{module}] %{shortfunc} -> %{level:.4s} %{id:03x}%{color:reset} %{message} CORE_CHAINCODE_ID_NAME=lscc:1.4.3 CORE_PEER_TLS_ENABLED=true CORE_TLS_CLIENT_KEY_PATH=/etc/hyperledger/fabric/client.key CORE_TLS_CLIENT_CERT_PATH=/etc/hyperledger/fabric/client.crt CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/peer.crt 2019-09-09 07:52:09.915 UTC [container] lockContainer -> DEBU 09c waiting for container(lscc-1.4.3) lock 2019-09-09 07:52:09.915 UTC [container] lockContainer -> DEBU 09d got container (lscc-1.4.3) lock 2019-09-09 07:52:09.915 UTC [inproccontroller] getInstance -> DEBU 09e chaincode instance created for lscc-1.4.3 2019-09-09 07:52:09.915 UTC [container] unlockContainer -> DEBU 09f container lock deleted(lscc-1.4.3) 2019-09-09 07:52:09.915 UTC [container] lockContainer -> DEBU 0a0 waiting for container(lscc-1.4.3) lock 2019-09-09 07:52:09.915 UTC [container] lockContainer -> DEBU 0a1 got container (lscc-1.4.3) lock 2019-09-09 07:52:09.915 UTC [container] unlockContainer -> DEBU 0a2 container lock deleted(lscc-1.4.3) 2019-09-09 07:52:09.915 UTC [inproccontroller] func2 -> DEBU 0a3 chaincode-support started for lscc-1.4.3 2019-09-09 07:52:09.915 UTC [inproccontroller] func1 -> DEBU 0a4 chaincode started for lscc-1.4.3 // 以上日志对应的代码流程在上文都讲到了
// 以下是交互过程peer日志 // peer收到容器的注册消息 2019-09-09 07:52:09.916 UTC [chaincode] handleMessage -> DEBU 0a5 [] Fabric side handling ChaincodeMessage of type: REGISTER in state created 2019-09-09 07:52:09.916 UTC [chaincode] HandleRegister -> DEBU 0a6 Received REGISTER in state created 2019-09-09 07:52:09.916 UTC [chaincode] Register -> DEBU 0a7 registered handler complete for chaincode lscc:1.4.3 2019-09-09 07:52:09.916 UTC [chaincode] HandleRegister -> DEBU 0a8 Got REGISTER for chaincodeID = name:"lscc:1.4.3" , sending back REGISTERED 2019-09-09 07:52:09.920 UTC [grpc] HandleSubConnStateChange -> DEBU 0a9 pickfirstBalancer: HandleSubConnStateChange: 0xc0026318c0, READY 2019-09-09 07:52:09.923 UTC [chaincode] HandleRegister -> DEBU 0aa Changed state to established for name:"lscc:1.4.3"
// peer发送ready消息 2019-09-09 07:52:09.923 UTC [chaincode] sendReady -> DEBU 0ab sending READY for chaincode name:"lscc:1.4.3" 2019-09-09 07:52:09.923 UTC [chaincode] sendReady -> DEBU 0ac Changed to state ready for chaincode name:"lscc:1.4.3"
// 已经完成启动容器 2019-09-09 07:52:09.923 UTC [chaincode] Launch -> DEBU 0ad launch complete 2019-09-09 07:52:09.924 UTC [chaincode] Execute -> DEBU 0ae Entry // 收到容器COMPLETED消息 2019-09-09 07:52:09.925 UTC [chaincode] handleMessage -> DEBU 0af [01b03aae] Fabric side handling ChaincodeMessage of type: COMPLETED in state ready
// 通知scc,部署已经完成 2019-09-09 07:52:09.925 UTC [chaincode] Notify -> DEBU 0b0 [01b03aae] notifying Txid:01b03aae-17a6-4b63-874e-dc20d6f5df0c, channelID: 2019-09-09 07:52:09.925 UTC [chaincode] Execute -> DEBU 0b1 Exit 2019-09-09 07:52:09.925 UTC [sccapi] deploySysCC -> INFO 0b2 system chaincode lscc/(github.com/hyperledger/fabric/core/scc/lscc) deployed