github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/peer/channel/join.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package channel
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"io/ioutil"
    23  
    24  	"github.com/hyperledger/fabric/core/scc/cscc"
    25  	"github.com/hyperledger/fabric/peer/common"
    26  	pcommon "github.com/hyperledger/fabric/protos/common"
    27  	pb "github.com/hyperledger/fabric/protos/peer"
    28  	putils "github.com/hyperledger/fabric/protos/utils"
    29  	"github.com/spf13/cobra"
    30  	"golang.org/x/net/context"
    31  )
    32  
    33  const commandDescription = "Joins the peer to a chain."
    34  
    35  func joinCmd(cf *ChannelCmdFactory) *cobra.Command {
    36  	// Set the flags on the channel start command.
    37  	joinCmd := &cobra.Command{
    38  		Use:   "join",
    39  		Short: commandDescription,
    40  		Long:  commandDescription,
    41  		RunE: func(cmd *cobra.Command, args []string) error {
    42  			return join(cmd, args, cf)
    43  		},
    44  	}
    45  	flagList := []string{
    46  		"blockpath",
    47  	}
    48  	attachFlags(joinCmd, flagList)
    49  
    50  	return joinCmd
    51  }
    52  
    53  //GBFileNotFoundErr genesis block file not found
    54  type GBFileNotFoundErr string
    55  
    56  func (e GBFileNotFoundErr) Error() string {
    57  	return fmt.Sprintf("genesis block file not found %s", string(e))
    58  }
    59  
    60  //ProposalFailedErr proposal failed
    61  type ProposalFailedErr string
    62  
    63  func (e ProposalFailedErr) Error() string {
    64  	return fmt.Sprintf("proposal failed (err: %s)", string(e))
    65  }
    66  
    67  func getJoinCCSpec() (*pb.ChaincodeSpec, error) {
    68  	if genesisBlockPath == common.UndefinedParamValue {
    69  		return nil, errors.New("Must supply genesis block file")
    70  	}
    71  
    72  	gb, err := ioutil.ReadFile(genesisBlockPath)
    73  	if err != nil {
    74  		return nil, GBFileNotFoundErr(err.Error())
    75  	}
    76  	// Build the spec
    77  	input := &pb.ChaincodeInput{Args: [][]byte{[]byte(cscc.JoinChain), gb}}
    78  
    79  	spec := &pb.ChaincodeSpec{
    80  		Type:        pb.ChaincodeSpec_Type(pb.ChaincodeSpec_Type_value["GOLANG"]),
    81  		ChaincodeId: &pb.ChaincodeID{Name: "cscc"},
    82  		Input:       input,
    83  	}
    84  
    85  	return spec, nil
    86  }
    87  
    88  func executeJoin(cf *ChannelCmdFactory) (err error) {
    89  	spec, err := getJoinCCSpec()
    90  	if err != nil {
    91  		return err
    92  	}
    93  
    94  	// Build the ChaincodeInvocationSpec message
    95  	invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec}
    96  
    97  	creator, err := cf.Signer.Serialize()
    98  	if err != nil {
    99  		return fmt.Errorf("Error serializing identity for %s: %s", cf.Signer.GetIdentifier(), err)
   100  	}
   101  
   102  	var prop *pb.Proposal
   103  	prop, _, err = putils.CreateProposalFromCIS(pcommon.HeaderType_CONFIG, "", invocation, creator)
   104  	if err != nil {
   105  		return fmt.Errorf("Error creating proposal for join %s", err)
   106  	}
   107  
   108  	var signedProp *pb.SignedProposal
   109  	signedProp, err = putils.GetSignedProposal(prop, cf.Signer)
   110  	if err != nil {
   111  		return fmt.Errorf("Error creating signed proposal %s", err)
   112  	}
   113  
   114  	var proposalResp *pb.ProposalResponse
   115  	proposalResp, err = cf.EndorserClient.ProcessProposal(context.Background(), signedProp)
   116  	if err != nil {
   117  		return ProposalFailedErr(err.Error())
   118  	}
   119  
   120  	if proposalResp == nil {
   121  		return ProposalFailedErr("nil proposal response")
   122  	}
   123  
   124  	if proposalResp.Response.Status != 0 && proposalResp.Response.Status != 200 {
   125  		return ProposalFailedErr(fmt.Sprintf("bad proposal response %d", proposalResp.Response.Status))
   126  	}
   127  	logger.Infof("Peer joined the channel!")
   128  	return nil
   129  }
   130  
   131  func join(cmd *cobra.Command, args []string, cf *ChannelCmdFactory) error {
   132  	if genesisBlockPath == common.UndefinedParamValue {
   133  		return errors.New("Must supply genesis block path")
   134  	}
   135  
   136  	var err error
   137  	if cf == nil {
   138  		cf, err = InitCmdFactory(EndorserRequired, OrdererNotRequired)
   139  		if err != nil {
   140  			return err
   141  		}
   142  	}
   143  	return executeJoin(cf)
   144  }