//Stop stops a chaincode if running func (chaincodeSupport *ChaincodeSupport) Stop(context context.Context, cds *pb.ChaincodeDeploymentSpec) error { chaincode := cds.ChaincodeSpec.ChaincodeID.Name if chaincode == "" { return fmt.Errorf("chaincode name not set") } //stop the chaincode sir := container.StopImageReq{CCID: ccintf.CCID{ChaincodeSpec: cds.ChaincodeSpec, NetworkID: chaincodeSupport.peerNetworkID, PeerID: chaincodeSupport.peerID}, Timeout: 0} vmtype, _ := chaincodeSupport.getVMType(cds) _, err := container.VMCProcess(context, vmtype, sir) if err != nil { err = fmt.Errorf("Error stopping container: %s", err) //but proceed to cleanup } chaincodeSupport.runningChaincodes.Lock() if _, ok := chaincodeSupport.chaincodeHasBeenLaunched(chaincode); !ok { //nothing to do chaincodeSupport.runningChaincodes.Unlock() return nil } delete(chaincodeSupport.runningChaincodes.chaincodeMap, chaincode) chaincodeSupport.runningChaincodes.Unlock() return err }
// Invoke chaincode_example02 func invokeExample02Transaction(ctxt context.Context, cccid *CCContext, cID *pb.ChaincodeID, args []string, destroyImage bool) error { f := "init" argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Args: argsDeploy}} _, err := deploy(ctxt, cccid, spec) chaincodeID := spec.ChaincodeID.Name if err != nil { return fmt.Errorf("Error deploying <%s>: %s", chaincodeID, err) } time.Sleep(time.Second) if destroyImage { theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) dir := container.DestroyImageReq{CCID: ccintf.CCID{ChaincodeSpec: spec, NetworkID: theChaincodeSupport.peerNetworkID, PeerID: theChaincodeSupport.peerID, ChainID: cccid.ChainID}, Force: true, NoPrune: true} _, err = container.VMCProcess(ctxt, container.DOCKER, dir) if err != nil { err = fmt.Errorf("Error destroying image: %s", err) return err } } f = "invoke" invokeArgs := append([]string{f}, args...) spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} _, uuid, _, err := invoke(ctxt, cccid.ChainID, spec) if err != nil { return fmt.Errorf("Error invoking <%s>: %s", cccid.Name, err) } cccid.TxID = uuid err = checkFinalState(cccid) if err != nil { return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", chaincodeID, err) } // Test for delete state f = "delete" delArgs := util.ToChaincodeArgs(f, "a") spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Args: delArgs}} _, uuid, _, err = invoke(ctxt, cccid.ChainID, spec) if err != nil { return fmt.Errorf("Error deleting state in <%s>: %s", cccid.Name, err) } return nil }
// Deploy deploys the chaincode if not in development mode where user is running the chaincode. func (chaincodeSupport *ChaincodeSupport) Deploy(context context.Context, t *pb.Transaction) (*pb.ChaincodeDeploymentSpec, error) { //build the chaincode cds := &pb.ChaincodeDeploymentSpec{} err := proto.Unmarshal(t.Payload, cds) if err != nil { return nil, err } cID := cds.ChaincodeSpec.ChaincodeID cLang := cds.ChaincodeSpec.Type chaincode := cID.Name if err != nil { return cds, err } if chaincodeSupport.userRunsCC { chaincodeLogger.Debug("user runs chaincode, not deploying chaincode") return nil, nil } chaincodeSupport.runningChaincodes.Lock() //if its in the map, there must be a connected stream...and we are trying to build the code ?! if _, ok := chaincodeSupport.chaincodeHasBeenLaunched(chaincode); ok { chaincodeLogger.Debugf("deploy ?!! there's a chaincode with that name running: %s", chaincode) chaincodeSupport.runningChaincodes.Unlock() return cds, fmt.Errorf("deploy attempted but a chaincode with same name running %s", chaincode) } chaincodeSupport.runningChaincodes.Unlock() args, envs, err := chaincodeSupport.getArgsAndEnv(cID, cLang) if err != nil { return cds, fmt.Errorf("error getting args for chaincode %s", err) } var targz io.Reader = bytes.NewBuffer(cds.CodePackage) cir := &container.CreateImageReq{CCID: ccintf.CCID{ChaincodeSpec: cds.ChaincodeSpec, NetworkID: chaincodeSupport.peerNetworkID, PeerID: chaincodeSupport.peerID}, Args: args, Reader: targz, Env: envs} vmtype, _ := chaincodeSupport.getVMType(cds) chaincodeLogger.Debugf("deploying chaincode %s(networkid:%s,peerid:%s)", chaincode, chaincodeSupport.peerNetworkID, chaincodeSupport.peerID) //create image and create container _, err = container.VMCProcess(context, vmtype, cir) if err != nil { err = fmt.Errorf("Error starting container: %s", err) } return cds, err }
// Invoke chaincode_example02 func invokeExample02Transaction(ctxt context.Context, cID *pb.ChaincodeID, args []string, destroyImage bool) error { f := "init" argsDeploy := []string{"a", "100", "b", "200"} spec := &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Function: f, Args: argsDeploy}} _, err := deploy(ctxt, spec) chaincodeID := spec.ChaincodeID.Name if err != nil { return fmt.Errorf("Error deploying <%s>: %s", chaincodeID, err) } time.Sleep(time.Second) if destroyImage { GetChain(DefaultChain).Stop(ctxt, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) dir := container.DestroyImageReq{CCID: ccintf.CCID{ChaincodeSpec: spec, NetworkID: GetChain(DefaultChain).peerNetworkID, PeerID: GetChain(DefaultChain).peerID}, Force: true, NoPrune: true} _, err = container.VMCProcess(ctxt, container.DOCKER, dir) if err != nil { err = fmt.Errorf("Error destroying image: %s", err) return err } } f = "invoke" spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Function: f, Args: args}} _, uuid, _, err := invoke(ctxt, spec, pb.Transaction_CHAINCODE_INVOKE) if err != nil { return fmt.Errorf("Error invoking <%s>: %s", chaincodeID, err) } err = checkFinalState(uuid, chaincodeID) if err != nil { return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", chaincodeID, err) } // Test for delete state f = "delete" delArgs := []string{"a"} spec = &pb.ChaincodeSpec{Type: 1, ChaincodeID: cID, CtorMsg: &pb.ChaincodeInput{Function: f, Args: delArgs}} _, uuid, _, err = invoke(ctxt, spec, pb.Transaction_CHAINCODE_INVOKE) if err != nil { return fmt.Errorf("Error deleting state in <%s>: %s", chaincodeID, err) } return nil }
// Deploy deploys the chaincode if not in development mode where user is running the chaincode. func (chaincodeSupport *ChaincodeSupport) Deploy(context context.Context, cccid *CCContext, cds *pb.ChaincodeDeploymentSpec) (*pb.ChaincodeDeploymentSpec, error) { cLang := cds.ChaincodeSpec.Type canName := cccid.GetCanonicalName() if chaincodeSupport.userRunsCC { chaincodeLogger.Debug("user runs chaincode, not deploying chaincode") return nil, nil } chaincodeSupport.runningChaincodes.Lock() //if its in the map, there must be a connected stream...and we are trying to build the code ?! if _, ok := chaincodeSupport.chaincodeHasBeenLaunched(canName); ok { chaincodeLogger.Debugf("deploy ?!! there's a chaincode with that name running: %s", canName) chaincodeSupport.runningChaincodes.Unlock() return cds, fmt.Errorf("deploy attempted but a chaincode with same name running %s", canName) } chaincodeSupport.runningChaincodes.Unlock() args, envs, err := chaincodeSupport.getArgsAndEnv(cccid, cLang) if err != nil { return cds, fmt.Errorf("error getting args for chaincode %s", err) } var targz io.Reader = bytes.NewBuffer(cds.CodePackage) cir := &container.CreateImageReq{CCID: ccintf.CCID{ChaincodeSpec: cds.ChaincodeSpec, NetworkID: chaincodeSupport.peerNetworkID, PeerID: chaincodeSupport.peerID, ChainID: cccid.ChainID}, Args: args, Reader: targz, Env: envs} vmtype, _ := chaincodeSupport.getVMType(cds) chaincodeLogger.Debugf("deploying chaincode %s(networkid:%s,peerid:%s)", canName, chaincodeSupport.peerNetworkID, chaincodeSupport.peerID) //create image and create container resp, err2 := container.VMCProcess(context, vmtype, cir) if err2 != nil || (resp != nil && resp.(container.VMCResp).Err != nil) { err = fmt.Errorf("Error creating image: %s", err2) } return cds, err }
// launchAndWaitForRegister will launch container if not already running. Use the targz to create the image if not found func (chaincodeSupport *ChaincodeSupport) launchAndWaitForRegister(ctxt context.Context, cds *pb.ChaincodeDeploymentSpec, cID *pb.ChaincodeID, uuid string, cLang pb.ChaincodeSpec_Type, targz io.Reader) (bool, error) { chaincode := cID.Name if chaincode == "" { return false, fmt.Errorf("chaincode name not set") } chaincodeSupport.runningChaincodes.Lock() var ok bool //if its in the map, there must be a connected stream...nothing to do if _, ok = chaincodeSupport.chaincodeHasBeenLaunched(chaincode); ok { chaincodeLogger.Debugf("chaincode is running and ready: %s", chaincode) chaincodeSupport.runningChaincodes.Unlock() return true, nil } alreadyRunning := false notfy := chaincodeSupport.preLaunchSetup(chaincode) chaincodeSupport.runningChaincodes.Unlock() //launch the chaincode args, env, err := chaincodeSupport.getArgsAndEnv(cID, cLang) if err != nil { return alreadyRunning, err } chaincodeLogger.Debugf("start container: %s(networkid:%s,peerid:%s)", chaincode, chaincodeSupport.peerNetworkID, chaincodeSupport.peerID) vmtype, _ := chaincodeSupport.getVMType(cds) sir := container.StartImageReq{CCID: ccintf.CCID{ChaincodeSpec: cds.ChaincodeSpec, NetworkID: chaincodeSupport.peerNetworkID, PeerID: chaincodeSupport.peerID}, Reader: targz, Args: args, Env: env} ipcCtxt := context.WithValue(ctxt, ccintf.GetCCHandlerKey(), chaincodeSupport) resp, err := container.VMCProcess(ipcCtxt, vmtype, sir) if err != nil || (resp != nil && resp.(container.VMCResp).Err != nil) { if err == nil { err = resp.(container.VMCResp).Err } err = fmt.Errorf("Error starting container: %s", err) chaincodeSupport.runningChaincodes.Lock() delete(chaincodeSupport.runningChaincodes.chaincodeMap, chaincode) chaincodeSupport.runningChaincodes.Unlock() return alreadyRunning, err } //wait for REGISTER state select { case ok := <-notfy: if !ok { err = fmt.Errorf("registration failed for %s(networkid:%s,peerid:%s,tx:%s)", chaincode, chaincodeSupport.peerNetworkID, chaincodeSupport.peerID, uuid) } case <-time.After(chaincodeSupport.ccStartupTimeout): err = fmt.Errorf("Timeout expired while starting chaincode %s(networkid:%s,peerid:%s,tx:%s)", chaincode, chaincodeSupport.peerNetworkID, chaincodeSupport.peerID, uuid) } if err != nil { chaincodeLogger.Debugf("stopping due to error while launching %s", err) errIgnore := chaincodeSupport.Stop(ctxt, cds) if errIgnore != nil { chaincodeLogger.Debugf("error on stop %s(%s)", errIgnore, err) } } return alreadyRunning, err }