github.com/true-sqn/fabric@v2.1.1+incompatible/internal/peer/chaincode/upgrade.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package chaincode
     8  
     9  import (
    10  	"context"
    11  	"errors"
    12  	"fmt"
    13  
    14  	protcommon "github.com/hyperledger/fabric-protos-go/common"
    15  	pb "github.com/hyperledger/fabric-protos-go/peer"
    16  	"github.com/hyperledger/fabric/bccsp"
    17  	"github.com/hyperledger/fabric/protoutil"
    18  	"github.com/spf13/cobra"
    19  )
    20  
    21  var chaincodeUpgradeCmd *cobra.Command
    22  
    23  const upgradeCmdName = "upgrade"
    24  
    25  // upgradeCmd returns the cobra command for Chaincode Upgrade
    26  func upgradeCmd(cf *ChaincodeCmdFactory, cryptoProvider bccsp.BCCSP) *cobra.Command {
    27  	chaincodeUpgradeCmd = &cobra.Command{
    28  		Use:       upgradeCmdName,
    29  		Short:     "Upgrade chaincode.",
    30  		Long:      "Upgrade an existing chaincode with the specified one. The new chaincode will immediately replace the existing chaincode upon the transaction committed.",
    31  		ValidArgs: []string{"1"},
    32  		RunE: func(cmd *cobra.Command, args []string) error {
    33  			return chaincodeUpgrade(cmd, args, cf, cryptoProvider)
    34  		},
    35  	}
    36  	flagList := []string{
    37  		"lang",
    38  		"ctor",
    39  		"path",
    40  		"name",
    41  		"channelID",
    42  		"version",
    43  		"policy",
    44  		"escc",
    45  		"vscc",
    46  		"peerAddresses",
    47  		"tlsRootCertFiles",
    48  		"connectionProfile",
    49  		"collections-config",
    50  	}
    51  	attachFlags(chaincodeUpgradeCmd, flagList)
    52  
    53  	return chaincodeUpgradeCmd
    54  }
    55  
    56  //upgrade the command via Endorser
    57  func upgrade(cmd *cobra.Command, cf *ChaincodeCmdFactory) (*protcommon.Envelope, error) {
    58  	spec, err := getChaincodeSpec(cmd)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  
    63  	cds, err := getChaincodeDeploymentSpec(spec, false)
    64  	if err != nil {
    65  		return nil, fmt.Errorf("error getting chaincode code %s: %s", chaincodeName, err)
    66  	}
    67  
    68  	creator, err := cf.Signer.Serialize()
    69  	if err != nil {
    70  		return nil, fmt.Errorf("error serializing identity: %s", err)
    71  	}
    72  
    73  	prop, _, err := protoutil.CreateUpgradeProposalFromCDS(channelID, cds, creator, policyMarshalled, []byte(escc), []byte(vscc), collectionConfigBytes)
    74  	if err != nil {
    75  		return nil, fmt.Errorf("error creating proposal %s: %s", chainFuncName, err)
    76  	}
    77  	logger.Debugf("Get upgrade proposal for chaincode <%v>", spec.ChaincodeId)
    78  
    79  	var signedProp *pb.SignedProposal
    80  	signedProp, err = protoutil.GetSignedProposal(prop, cf.Signer)
    81  	if err != nil {
    82  		return nil, fmt.Errorf("error creating signed proposal  %s: %s", chainFuncName, err)
    83  	}
    84  
    85  	// upgrade is currently only supported for one peer
    86  	proposalResponse, err := cf.EndorserClients[0].ProcessProposal(context.Background(), signedProp)
    87  	if err != nil {
    88  		return nil, fmt.Errorf("error endorsing %s: %s", chainFuncName, err)
    89  	}
    90  	logger.Debugf("endorse upgrade proposal, get response <%v>", proposalResponse.Response)
    91  
    92  	if proposalResponse != nil {
    93  		// assemble a signed transaction (it's an Envelope message)
    94  		env, err := protoutil.CreateSignedTx(prop, cf.Signer, proposalResponse)
    95  		if err != nil {
    96  			return nil, fmt.Errorf("could not assemble transaction, err %s", err)
    97  		}
    98  		logger.Debug("Get Signed envelope")
    99  		return env, nil
   100  	}
   101  
   102  	return nil, nil
   103  }
   104  
   105  // chaincodeUpgrade upgrades the chaincode. On success, the new chaincode
   106  // version is printed to STDOUT
   107  func chaincodeUpgrade(cmd *cobra.Command, args []string, cf *ChaincodeCmdFactory, cryptoProvider bccsp.BCCSP) error {
   108  	if channelID == "" {
   109  		return errors.New("The required parameter 'channelID' is empty. Rerun the command with -C flag")
   110  	}
   111  	// Parsing of the command line is done so silence cmd usage
   112  	cmd.SilenceUsage = true
   113  
   114  	var err error
   115  	if cf == nil {
   116  		cf, err = InitCmdFactory(cmd.Name(), true, true, cryptoProvider)
   117  		if err != nil {
   118  			return err
   119  		}
   120  	}
   121  	defer cf.BroadcastClient.Close()
   122  
   123  	env, err := upgrade(cmd, cf)
   124  	if err != nil {
   125  		return err
   126  	}
   127  
   128  	if env != nil {
   129  		logger.Debug("Send signed envelope to orderer")
   130  		err = cf.BroadcastClient.Send(env)
   131  		return err
   132  	}
   133  
   134  	return nil
   135  }